Picassostyle Image Maker

バージョン 1.0.1 (3.7 KB) 作成者: Chun
将一张RGB彩图处理成毕加索风格的抽象画(参数可量化), 与该过程的可视化。Process an RGB color drawing into a Picasso-style abstract painting and a gif. visualizing the process
ダウンロード: 5
更新 2025/9/19

ライセンスの表示

function imgOut = picassoStyle(filename, varargin)
%picassoStyle 将一张RGB图像转换成毕加索立体主义风格的抽象画。
%picassoStyle Convert an RGB image into a Picasso-style Cubist abstract painting.
%
% 该函数通过分层处理实现艺术效果:
% This function achieves artistic effects through layered processing:
% 1. 结构抽象化:使用超像素将图像分割成几何区域。
% Structural abstraction: segment the image into geometric regions using superpixels.
% 2. 轮廓提取:从区域边界和图像主边缘提取并强化线条。
% Contour extraction: extract and enhance lines from region boundaries and main edges.
% 3. 区域着色:使用简化的调色板为区域填充平涂色块。
% Region coloring: fill regions with flat color blocks using a simplified palette.
% 4. (可选) 形式解构:对部分区域进行几何变换,模拟立体主义。
% (Optional) Form deconstruction: apply geometric transformations to regions to simulate Cubism.
%
% USAGE
% Imshow(picassoStyle(my_photo.jpg))
% imgOut = picassoStyle('my_photo.jpg');
% imgOut = picassoStyle('my_photo.jpg', 'num_superpixels', 250, 'palette_size', 12, 'line_thickness', 2);
% imgOut = picassoStyle('my_photo.jpg', 'enable_distortion', true, 'distortion_prob', 0.2);
%
% PARAMETERS
% 'num_superpixels' - 控制图像分割的块数。值越小,色块越大,画面越抽象。(默认: 300)
% Controls the number of segmented regions. Smaller values → larger blocks, more abstract. (Default: 300)
% 'palette_size' - 简化调色板中的颜色数量。值越小,颜色越抽象。(默认: 15)
% Number of colors in the simplified palette. Smaller values → more abstract colors. (Default: 15)
% 'line_thickness' - 黑色轮廓线的粗细(像素)。(默认: 1)
% Thickness of black contour lines (pixels). (Default: 1)
% 'canny_threshold' - Canny边缘检测的阈值,用于捕捉主体轮廓。(默认: 0.1)
% Threshold for Canny edge detection to capture main outlines. (Default: 0.1)
% 'enable_distortion' - 是否启用第四层“解构”效果。(默认: false)
% Enable the fourth-layer "deconstruction" effect. (Default: false)
% 'distortion_prob' - 每个区域被扭曲的概率。(默认: 0.15)
% Probability that each region will be distorted. (Default: 0.15)
% 'distortion_strength' - 扭曲的强度(旋转角度范围)。(默认: 10度)
% Distortion strength (rotation angle range). (Default: 10 degrees)
% --- 1. 参数解析与默认值设定 ---
% --- 1. Parameter parsing and default value setting ---
p = inputParser;
addRequired(p, 'filename', @(x) ischar(x) || isstring(x));
addParameter(p, 'num_superpixels', 20, @isnumeric);
addParameter(p, 'palette_size', 5, @isnumeric);
addParameter(p, 'line_thickness', 2, @isnumeric);
addParameter(p, 'canny_threshold', 0.1, @isnumeric);
addParameter(p, 'enable_distortion', true, @islogical);
addParameter(p, 'distortion_prob', 0.50, @isnumeric);
addParameter(p, 'distortion_strength', 190, @isnumeric);
parse(p, filename, varargin{:});
% 将解析的参数赋值给变量
% Assign parsed parameters to variables
num_superpixels = p.Results.num_superpixels;
palette_size = p.Results.palette_size;
line_thickness = p.Results.line_thickness;
canny_threshold = p.Results.canny_threshold;
enable_distortion = p.Results.enable_distortion;
distortion_prob = p.Results.distortion_prob;
distortion_strength = p.Results.distortion_strength;
% 读取图像
% Read image
img_orig = imread(filename);
img = im2double(img_orig); % 转换为double类型方便计算
% Convert to double type for easier computation
fprintf('开始处理图像...\n');
% Start processing image...
% --- 第一层:结构抽象化 - 图像分割与几何化 ---
% --- Layer 1: Structural abstraction - image segmentation and geometrization ---
fprintf('第一层:正在进行超像素分割...\n');
% Layer 1: Performing superpixel segmentation...
% 使用SLIC算法将图像分割成N个区域
% Use SLIC algorithm to segment image into N regions
% L是标签矩阵,每个像素的值对应其所属的区域编号
% L is a label matrix where each pixel's value corresponds to its region index
% N是实际生成的超像素数量
% N is the actual number of generated superpixels
[L, N] = superpixels(img, num_superpixels, 'Compactness', 20);
% --- 第二层:轮廓提取与强化 - 勾勒关键线条 ---
% --- Layer 2: Contour extraction and enhancement - outline key lines ---
fprintf('第二层:正在提取和强化轮廓线...\n');
% Layer 2: Extracting and enhancing contour lines...
% 1. 提取超像素区域之间的边界
% 1. Extract boundaries between superpixel regions
superpixel_boundaries = boundarymask(L);
% 2. 提取原图的主体轮廓
% 2. Extract main outlines from the original image
gray_img = rgb2gray(img);
canny_edges = edge(gray_img, 'canny', canny_threshold);
% 3. 合并两种边界并加粗,形成最终的线条层
% 3. Combine both boundaries and thicken them to form the final line layer
combined_lines = superpixel_boundaries | canny_edges;
se = strel('disk', line_thickness);
line_layer = imdilate(combined_lines, se);
% 将线条层反转,用于后续叠加(黑色线条区域为0)
% Invert line layer for later overlay (black line regions as 0)
line_mask = ~line_layer;
% --- 第三层:区域着色与色彩简化 - 大胆的色块填充 ---
% --- Layer 3: Region coloring and palette simplification - bold color filling ---
fprintf('第三层:正在简化调色板并填充色块...\n');
% Layer 3: Simplifying palette and filling regions with colors...
% 1. 创建简化调色板
% 1. Create simplified palette
% 使用rgb2ind从原图中提取有限数量的主导色
% Use rgb2ind to extract a limited set of dominant colors from the original image
[~, simple_map] = rgb2ind(img_orig, palette_size, 'nodither');
% 2. 为每个超像素区域确定一个简化颜色并填充
% 2. Assign each superpixel region a simplified color and fill it
% 初始化一个空白的颜色填充层
% Initialize an empty color fill layer
color_fill_layer = zeros(size(img));
% label2idx可以高效地获取每个区域的像素索引
% label2idx efficiently retrieves pixel indices for each region
idx = label2idx(L);
for i = 1:N
region_idx = idx{i};
% 计算该区域在原图中的平均颜色
% Compute mean color of this region in the original image
mean_color = mean(reshape(img(repmat(L==i, [1,1,3])), [], 3), 1);
% 从简化调色板中找到与该平均色最接近的颜色
% Find the closest color in the simplified palette
[~, closest_color_idx] = min(sum((simple_map - mean_color).^2, 2));
fill_color = simple_map(closest_color_idx, :);
% 在颜色填充层中,将该区域所有像素设置为找到的颜色
% Assign this color to all pixels of the region in the color fill layer
% 需要分别对R, G, B三个通道进行操作
% Must operate separately on R, G, B channels
for channel = 1:3
channel_plane = color_fill_layer(:,:,channel);
channel_plane(region_idx) = fill_color(channel);
color_fill_layer(:,:,channel) = channel_plane;
end
end
% --- 第四层(可选):形式解构与重组 ---
% --- Layer 4 (optional): Form deconstruction and reconstruction ---
output_image = color_fill_layer; % 默认输出为第三层的结果
% Default output is result from Layer 3
if enable_distortion
fprintf('第四层:正在进行形式解构(扭曲)...\n');
% Layer 4: Performing form deconstruction (distortion)...
distorted_layer = output_image;
for i = 1:N
% 以一定概率决定是否扭曲当前区域
% With certain probability, decide whether to distort current region
if rand() < distortion_prob
% 创建一个随机的微小仿射变换(这里是旋转)
% Create a random small affine transformation (here, rotation)
angle = (rand - 0.5) * 2 * distortion_strength;
tform = affine2d([cosd(angle) -sind(angle) 0; sind(angle) cosd(angle) 0; 0 0 1]);
% 获取当前区域的掩码和颜色
% Get mask and color of the current region
region_mask = (L == i);
% 从已经上色的图中获取颜色
% Get colors from already filled image
color_plane = output_image .* double(region_mask);
% 对该区域进行扭曲
% Distort this region
% 'OutputView'确保输出与原图大小一致
% 'OutputView' ensures output matches original size
R = imref2d(size(img));
warped_plane = imwarp(color_plane, tform, 'OutputView', R);
warped_mask = imwarp(region_mask, tform, 'OutputView', R);
% 将扭曲后的区域“贴”回画布
% Paste the distorted region back onto the canvas
distorted_layer(warped_mask) = warped_plane(warped_mask);
end
end
output_image = distorted_layer;
end
% --- 最终合成 ---
% --- Final composition ---
fprintf('正在合成最终图像...\n');
% Composing final image...
% 将黑色线条叠加在彩色图层上
% Overlay black lines on the colored layer
% line_mask是一个逻辑矩阵,需要扩展到3个通道
% line_mask is a logical matrix, needs expansion to 3 channels
final_image = output_image .* double(repmat(line_mask, [1,1,3]));
% 转换回uint8格式
% Convert back to uint8 format
imgOut = im2uint8(final_image);
fprintf('处理完成!\n');
% Processing complete!
end
%%_______GIF. Making Code(should be saved as another document to run)_________
%% makeGif.m
% 基于 picassoStyle.m 生成动图
% MATLAB R2023a
clc; clear; close all;
% 输入图像
filename = "My_photo.jpg"; % 可以换成自己的图像
% GIF 文件名
gif_filename = 'picasso_animation.gif';
% 区块数量范围:200 → 10,步长 -10
block_nums = 200:-10:10;
% Canny 阈值范围:0.1 → 0.9
canny_vals = linspace(0.1, 0.9, numel(block_nums));
% 动画时长和帧率
nFrames = numel(block_nums);
totalDuration = 5; % 秒
frameDelay = totalDuration / nFrames; % 每帧延时
for i = 1:nFrames
numBlocks = block_nums(i);
cannyTh = canny_vals(i);
% 调用 picassoStyle
imgOut = picassoStyle(filename, ...
'num_superpixels', numBlocks, ...
'palette_size', 20, ...
'line_thickness', 2, ...
'canny_threshold', cannyTh, ...
'enable_distortion', false);
% 显示当前帧
imshow(imgOut);
title(sprintf('区块数: %d, Canny阈值: %.2f', numBlocks, cannyTh), 'FontSize', 14);
drawnow;
% 捕获并写入 GIF
frame = getframe(gca);
[imind, cm] = rgb2ind(frame.cdata, 256);
if i == 1
imwrite(imind, cm, gif_filename, 'gif', 'Loopcount', inf, 'DelayTime', frameDelay);
else
imwrite(imind, cm, gif_filename, 'gif', 'WriteMode', 'append', 'DelayTime', frameDelay);
end
end

引用

Chun (2025). Picassostyle Image Maker (https://jp.mathworks.com/matlabcentral/fileexchange/182062-picassostyle-image-maker), MATLAB Central File Exchange. に取得済み.

MATLAB リリースの互換性
作成: R2023a
すべてのリリースと互換性あり
プラットフォームの互換性
Windows macOS Linux

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!
バージョン 公開済み リリース ノート
1.0.1

A small tip: the gif. making section should be saved as another document to run

1.0.0