PS图层混合模式MATLAB实现

PS图层混合模式的MATLAB实现

  • 一、基本介绍
  • 二、算法
    • 1. 组合模式(正常、溶解)
    • 2. 加深混合模式(变暗、正片叠底、颜色加深、线性加深,深色)
    • 3. 减淡混合模式(变亮、滤色、颜色减淡、线性减淡,浅色)
    • 4. 对比混合模式(叠加、柔光、强光、亮光、线性光、点光、实色混合)
    • 5. 比较混合模式(差值、排除、减去、划分)
    • 6. 色彩混合模式(色相、饱和度、颜色、亮度)
  • 三、调用实例
  • 其他

因为需要批量处理图像,而PS好像只能一张张人工操作,想把PS中一系列操作改写成代码。
所以开始探索PS中各个功能背后的原理。记录并分享在这里。

by HPC_ZY

一、基本介绍

Photoshop的图层选项里有一个图层混合方法,如下图所示。6个模块,27种方式
PS图层混合模式MATLAB实现_第1张图片

二、算法

这里我们将放在下层的图片称为背景(bg),放在上层的图片称为混合图(mix)
PS图层混合模式MATLAB实现_第2张图片

注:
1)以下代码均为彩色模式下,对于灰度图可自行推导。
2)以下bg,mix均以double类型输入,计算完毕再将out转为uint8。
3)以下所有方法的描述,均为自己的理解(并非官方定义)。

1. 组合模式(正常、溶解)

  • 正常:mix完全覆盖bg
    o u t = b g out = bg out=bg
% 正常
function out = do1_1(bg,mix)
out = mix;
end

  • 溶解:还没搞明白怎么回事……

2. 加深混合模式(变暗、正片叠底、颜色加深、线性加深,深色)

  • 变暗:取各分量最小值
    o u t = m i n ( b g , m i x ) out = min(bg,mix) out=min(bg,mix)
% 变暗
function out = do2_1(bg,mix)
R = min(cat(3,bg(:,:,1),mix(:,:,1)),[],3);
G = min(cat(3,bg(:,:,2),mix(:,:,2)),[],3);
B = min(cat(3,bg(:,:,3),mix(:,:,3)),[],3);
out = cat(3,R,G,B);
end

  • 正片叠底:灰度乘积后,调整至0~255范围
    o u t = b g ∗ m i x 255 out = \frac{bg*mix}{255} out=255bgmix
% 正片叠底
function out = do2_2(bg,mix)
out = bg.*mix/255;
end

  • 颜色加深
    o u t = b g − ( 255 − b g ) ( 255 − m i x ) m i x ; out = bg-\frac{(255-bg)(255-mix)}{mix}; out=bgmix(255bg)(255mix);
function out = do2_3(bg,mix)
out = bg-(255-bg).*(255-mix)./(mix+0.0001);
end

注:经过测试发现PS在进行颜色加深时是以uint8进行计算的,所以结果有杂点(可自行测试)


  • 线性加深:减去mix的反色
    o u t = b g − ( 255 − m i x ) out = bg-(255-mix) out=bg(255mix)
% 线性加深
function out = do2_4(bg,mix)
out = bg+mix-255;
end

  • 深色:保留总体亮度更低的点
    o u t = { b g , I b g < I m i x m i x , I b g > I m i x out=\left\{ \begin{aligned} bg & ,& I_{bg}I_{mix} \end{aligned} \right. out={bgmix,,Ibg<ImixIbg>Imix
% 深色
function out = do2_5(bg,mix)
bgsum = 0.299*bg(:,:,1)+0.587*bg(:,:,2)+0.114*bg(:,:,3);
mixsum = 0.299*mix(:,:,1)+0.587*mix(:,:,2)+0.114*mix(:,:,3);
flag = double(bgsum<mixsum);
out = bg.*flag+mix.*(~flag);
end

3. 减淡混合模式(变亮、滤色、颜色减淡、线性减淡,浅色)

  • 变亮:取各分量最大值
    o u t = m a x ( b g , m i x ) out = max(bg,mix) out=max(bg,mix)
% 变亮
function out = do3_1(bg,mix)
R = max(cat(3,bg(:,:,1),mix(:,:,1)),[],3);
G = max(cat(3,bg(:,:,2),mix(:,:,2)),[],3);
B = max(cat(3,bg(:,:,3),mix(:,:,3)),[],3);
out = cat(3,R,G,B);
end

  • 滤色
    o u t = 255 − ( 255 − b g ) ∗ ( 255 − m i x ) 255 ; out = 255-\frac{(255-bg)*(255-mix)}{255}; out=255255(255bg)(255mix);
% 滤色
function out = do3_2(bg,mix)
out = 255-(255-bg).*(255-mix)/255;
end

  • 颜色减淡:根据mix灰度,增加bg的亮度
    o u t = b g + b g ∗ m i x 255 − m i x ; out = bg+\frac{bg*mix}{255-mix}; out=bg+255mixbgmix;
% 颜色减淡
function out = do3_3(bg,mix)
out = bg+bg.*mix./(255.0001-mix);
end

  • 线性减淡:直接累加
    o u t = b g + m i x out = bg+mix out=bg+mix
% 线性减淡
function out = do3_4(bg,mix)
out = bg+mix;
end

  • 浅色:保留总体亮度更高的点
    o u t = { b g , I b g > I m i x m i x , I b g < I m i x out=\left\{ \begin{aligned} bg & ,& I_{bg}>I_{mix} \\ mix &, &I_{bg}out={bgmix,,Ibg>ImixIbg<Imix
    注:这里的 I I I指亮度
% 浅色
function out = do3_5(bg,mix)
bgsum = 0.299*bg(:,:,1)+0.587*bg(:,:,2)+0.114*bg(:,:,3);
mixsum = 0.299*mix(:,:,1)+0.587*mix(:,:,2)+0.114*mix(:,:,3);
flag = double(bgsum>mixsum);
out = bg.*flag+mix.*(~flag);
end

4. 对比混合模式(叠加、柔光、强光、亮光、线性光、点光、实色混合)

  • 叠加
    o u t = { b g ∗ m i x 128 , b g < 128 255 − ( 255 − b g ) ( 255 − m i x ) 128 , b g ≥ 128 out=\left\{ \begin{aligned} \frac{bg*mix}{128} & ,& bg<128 \\ 255-\frac{(255-bg)(255-mix)}{128} &, & bg\geq128 \end{aligned} \right. out=128bgmix255128(255bg)(255mix),,bg<128bg128
% 叠加
function out = do4_1(bg,mix)
out = zeros(size(bg));
idx = bg<128;
out(idx) = bg(idx).*mix(idx)/128;
out(~idx) = 255-(255-bg(~idx)).*(255-mix(~idx))/128;
end

  • 柔光
    o u t = { b g + ( 2 ∗ m i x − 255 ) ∗ ( b g 255 − ( b g 255 ) 2 ) , b g < 128 b g + ( 2 ∗ m i x − 255 ) ∗ ( b g 255 − b g 255 ) , b g ≥ 128 out=\left\{ \begin{aligned} bg+(2*mix-255)*(\frac{bg}{255}-(\frac{bg}{255})^2) & ,& bg<128 \\ bg+(2*mix-255)*(\sqrt{\frac{bg}{255}}-\frac{bg}{255}) &, & bg\geq128 \end{aligned} \right. out=bg+(2mix255)(255bg(255bg)2)bg+(2mix255)(255bg 255bg),,bg<128bg128
% 柔光
function out = do4_2(bg,mix)
out = zeros(size(bg));
idx = bg<128;
out(idx) = bg(idx)+(2*mix(idx)-255).*(bg(idx)/255-(bg(idx)/255).^2);
out(~idx) = bg(~idx)+(2*mix(~idx)-255).*(sqrt(bg(~idx)/255)-bg(~idx)/255);
end

  • 强光
    o u t = { 255 − ( 255 − b g ) ( 255 − m i x ) , b g < 128 b g ∗ m i x 128 , b g ≥ 128 out=\left\{ \begin{aligned} 255-(255-bg)(255-mix) & ,& bg<128 \\ \frac{bg*mix}{128}&, & bg\geq128 \end{aligned} \right. out=255(255bg)(255mix)128bgmix,,bg<128bg128
% 强光
function out = do4_3(bg,mix)
out = zeros(size(bg));
idx = bg<128;
out(idx) = 255-(255-bg(idx)).*(255-mix(idx))/128;
out(~idx) = bg(~idx).*mix(~idx)/128;
end

  • 亮光
    o u t = { 255 ∗ ( 1 − 255 − m i x 2 ∗ b g ) , b g < 128 255 ∗ m i x 2 ∗ ( 255 − b g ) , b g ≥ 128 out=\left\{ \begin{aligned} 255*(1-\frac{255-mix}{2*bg}) & ,& bg<128 \\ 255*\frac{mix}{2*(255-bg)}&, & bg\geq128 \end{aligned} \right. out=255(12bg255mix)2552(255bg)mix,,bg<128bg128
% 亮光
function out = do4_4(bg,mix)
out = zeros(size(bg));
idx = bg<128;
out(idx) = 255-(255-mix(idx))./(2*bg(idx)+0.0001)*255;
out(~idx) = mix(~idx)./(2*(255-bg(~idx))+0.0001)*255;
end

注:跟PS有一点点出入,待查明原因


  • 线性光:线性加深+线性减淡
    o u t = b g + m i x − ( 255 − m i x ) out= bg+mix-(255-mix) out=bg+mix(255mix)
function out = do4_5(bg,mix)
out = bg+mix*2-255;
end

  • 点光:以mix为标准,将bg太亮的调暗,太暗的调亮
    o u t = { 2 ∗ m i x − 255 , b g < 2 ∗ m i n − 255 2 ∗ m i x , b g > 2 ∗ m i x b g , o t h e r out=\left\{ \begin{aligned} 2*mix-255 & ,& bg<2*min-255 \\ 2*mix &, & bg>2*mix \\ bg &,& other \end{aligned} \right. out=2mix2552mixbg,,,bg<2min255bg>2mixother
% 点光
function out = do4_6(bg,mix)
out = bg;
idx1 = bg<2*mix-255;
idx2 = bg>2*mix;
out(idx1) = 2*mix(idx1)-255;
out(idx2) = 2*mix(idx2);
end

  • 实色混合:各通道根据累加和进行二值化
    o u t = { 255 , b g + m i x > = 255 0 , b g + m i x < 255 out=\left\{ \begin{aligned} 255 & ,& bg+mix>=255 \\ 0 &, & bg+mix<255 \end{aligned} \right. out={2550,,bg+mix>=255bg+mix<255
% 实色混合
function out = do4_7(bg,mix)
out = double((bg+mix)>=255)*255;
end

5. 比较混合模式(差值、排除、减去、划分)

  • 差值:两图的绝对差值
    o u t = ∣ b g − m i x ∣ out = |bg-mix| out=bgmix
% 差值
function out = do5_1(bg,mix)
out = abs(bg-mix);
end

  • 排除
    o u t = b g + m i x − b g ∗ m i x 128 out = bg+mix-bg*\frac{mix}{128} out=bg+mixbg128mix
% 排除
function out = do5_2(bg,mix)
out = bg+mix-bg.*mix/128;
end

  • 减去:直接减去mix,负数取0。
    o u t = m a x ( b g − m i x , 0 ) out = max(bg-mix,0) out=max(bgmix,0)
% 减去
function out = do5_3(bg,mix)
out = bg-mix;
end

  • 划分:根据mix的值,调亮bg
  • o u t = { 255 , m i x = 0 m i n ( b g ∗ 255 m i x , 255 ) , m i x > 0 out=\left\{ \begin{aligned} 255 & ,& mix=0 \\ min(bg*\frac{255}{mix}, 255) &, & mix>0 \end{aligned} \right. out=255min(bgmix255,255),,mix=0mix>0
% 划分
function out = do5_4(bg,mix)
out = bg./(mix+0.0001)*255;
end

6. 色彩混合模式(色相、饱和度、颜色、亮度)

  • 色相
在这里插入代码片

  • 饱和度
在这里插入代码片

  • 颜色
在这里插入代码片

  • 亮度
在这里插入代码片

三、调用实例

为了方便使用,写了一个间接调用函数

function out = LayerBlending(bg,mix,mode)

% 判断尺寸
if ~isequal(size(bg),size(mix))
    message("图像尺寸不相等")
end
if size(bg,3)~=3
    message("图像不是彩色图")
end

% 初始化
bg = double(bg);
mix = double(mix);
switch mode
    case 11
        out = do1_1(bg,mix);
    case 12
        out = do1_2(bg,mix);
    case 21
        out = do2_1(bg,mix);
    case 22
        out = do2_2(bg,mix);
    case 23
        out = do2_3(bg,mix);
    case 24
        out = do2_4(bg,mix);
    case 25
        out = do2_5(bg,mix);
    case 31
        out = do3_1(bg,mix);
    case 32
        out = do3_2(bg,mix);
    case 33
        out = do3_3(bg,mix);
    case 34
        out = do3_4(bg,mix);
    case 35
        out = do3_5(bg,mix);
    case 41
        out = do4_1(bg,mix);
    case 42
        out = do4_2(bg,mix);
    case 43
        out = do4_3(bg,mix);
    case 44
        out = do4_4(bg,mix);
    case 45
        out = do4_5(bg,mix);
    case 46
        out = do4_6(bg,mix);
    case 47
        out = do4_7(bg,mix);
    case 51
        out = do5_1(bg,mix);
    case 52
        out = do5_2(bg,mix);
    case 53
        out = do5_3(bg,mix);
    case 54
        out = do5_4(bg,mix);
    case 61
        out = do6_1(bg,mix);
    case 62
        out = do6_2(bg,mix);
    case 63
        out = do6_3(bg,mix);
    case 64
        out = do6_4(bg,mix);
end

out = uint8(out);
end

使用方法

bg = imread('1.png');
mix = imread('0.png');

out1 = LayerBlending(bg,mix,24); % 线性加深
out2 = LayerBlending(bg,mix,33); % 颜色减淡
out3 = LayerBlending(bg,mix,47); % 实色混合
out4 = LayerBlending(bg,mix,51); % 差值

subplot(231),imshow(bg)
subplot(234),imshow(mix)
subplot(232),imshow(out1)
subplot(233),imshow(out2)
subplot(235),imshow(out3)
subplot(236),imshow(out4)

PS图层混合模式MATLAB实现_第3张图片

其他

  1. 有些还没完全搞清楚,待续
  2. 以上所有内容(公式、代码),都是针对uint8格式的图像写的。
  3. 代码里有些地方分母+0.0001是为了避免为0带来计算问题
  4. 可以用PS试试,看结果是否一致。

你可能感兴趣的:(代码分享,图层叠加,MATLAB,Photoshop)