Picassostyle Image Maker
Version 1.0.1 (3.7 KB) by
Chun
将一张RGB彩图处理成毕加索风格的抽象画(参数可量化), 与该过程的可视化。Process an RGB color drawing into a Picasso-style abstract painting and a gif. visualizing the process
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
Cite As
Chun (2025). Picassostyle Image Maker (https://ch.mathworks.com/matlabcentral/fileexchange/182062-picassostyle-image-maker), MATLAB Central File Exchange. Retrieved .
MATLAB Release Compatibility
Created with
R2023a
Compatible with any release
Platform Compatibility
Windows macOS LinuxTags
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Discover Live Editor
Create scripts with code, output, and formatted text in a single executable document.
