Python: PS 图层混合算法汇总

本文使用Python实现Photoshop中的图层混合算法,包括正片叠底、颜色加深、线性加深等多种效果,并通过矩阵运算提高运行效率。提供详细代码及效果对比。

本文用 Python 实现了PS 中的图层混合算法,把很多常见的图层混合算法都汇总到了一起,比起以前写的算法,就是用矩阵运算代替了很耗时的for 循环,运行效率有所提升。具体的代码如下:

import matplotlib.pyplot as plt
from skimage import io
import math
import numpy as np

# image fusion

file_name='D:/Visual Effects/PS Algorithm/2.jpg';
img_1=io.imread(file_name)
img_1 = img_1/255.0

file_name2='D:/Visual Effects/PS Algorithm/3.jpg'
img_2=io.imread(file_name2)
img_2 = img_2/255.0


# 不透明度
def Transparent(img_1, img_2, alpha):
    img = img_1 * alpha + img_2 * (1-alpha)
    return img

# 正片叠底
def Multiply (img_1, img_2):
    img = img_1 * img_2
    return img

# 颜色加深 
def Color_burn (img_1, img_2):
    img = 1 - (1 - img_2) / (img_1 + 0.001)

    mask_1 = img  < 0 
    mask_2 = img  > 1

    img = img * (1-mask_1)
    img = img * (1-mask_2) + mask_2

    '''
    row, col, channel = img.shape
    for i in range(row):
        for j in range(col):
            img[i, j, 0] = min(max(img[i, j, 0], 0), 1)
            img[i, j, 1] = min(max(img[i, j, 1], 0), 1)
            img[i, j, 2] = min(max(img[i, j, 2], 0), 1)
    '''

    return img

# 颜色减淡
def Color_dodge(img_1, img_2):
    img = img_2 / (1.0 - img_1 + 0.001)
    mask_2 = img  > 1
    img = img * (1-mask_2) + mask_2          
    return img 

# 线性加深 
def Linear_burn(img_1, img_2):
    img = img_1 + img_2 - 1
    mask_1 = img  < 0 
    img = img * (1-mask_1)
    return img

# 线性减淡
def Linear_dodge(img_1, img_2):
    img = img_1 + img_2
    mask_2 = img  > 1
    img = img * (1-mask_2) + mask_2
    return img

# 变亮
def Lighten(img_1, img_2):
    img = img_1 - img_2
    mask = img > 0
    img = img_1 * mask + img_2 * (1-mask) 

    return img 

# 变暗
def Dark(img_1, img_2):
    img = img_1 - img_2
    mask = img < 0
    img = img_1 * mask + img_2 * (1-mask) 

    return img 

# 滤色
def Screen(img_1, img_2):
    img = 1- (1-img_1)*(1-img_2)

    return img

# 叠加
def Overlay(img_1, img_2):
    mask = img_2 < 0.5
    img = 2 * img_1 * img_2 * mask + (1-mask) * (1- 2 * (1-img_1)*(1-img_2))

    return img

# 柔光
def Soft_light(img_1, img_2):
    mask = img_1 < 0.5
    T1 = (2 * img_1 -1)*(img_2 - img_2 * img_2) + img_2
    T2 = (2 * img_1 -1)*(np.sqrt(img_2) - img_2) + img_2
    img = T1 * mask + T2 * (1-mask)

    return img

# 强光
def Hard_light(img_1, img_2):
    mask = img_1 < 0.5
    T1 = 2 * img_1 * img_2
    T2 = 1 - 2 * (1 - img_1) * (1 - img_2)
    img = T1 * mask + T2 * (1-mask)

    return img

# 亮光
def Vivid_light(img_1, img_2):
    mask = img_1 < 0.5
    T1 = 1 - (1 - img_2)/(2 * img_1 + 0.001)
    T2 = img_2 / (2*(1-img_1) + 0.001)
    mask_1 = T1 < 0
    mask_2 = T2 > 1
    T1 = T1 * (1-mask_1)
    T2 = T2 * (1-mask_2) + mask_2
    img = T1 * mask  + T2 * (1 - mask) 

    return img 

# 点光
def Pin_light(img_1, img_2):
    mask_1 = img_2 < (img_1 * 2 -1)
    mask_2 = img_2 > 2 * img_1
    T1 = 2 * img_1 -1 
    T2 = img_2
    T3 = 2 * img_1 
    img = T1 * mask_1 + T2 * (1 - mask_1) * (1 - mask_2) + T3 * mask_2

    return img

# 线性光
def Linear_light(img_1, img_2):
    img = img_2 + img_1 * 2 - 1
    mask_1 = img < 0
    mask_2 = img > 1
    img = img * (1-mask_1)
    img = img * (1-mask_2) + mask_2

    return img

# 实色混合
def Hard_mix(img_1, img_2):
    img = img_1 + img_2 
    mask = img_1 + img_2 > 1 
    img = img * (1-mask) + mask 
    img = img * mask
    return img


alpha = 0.5

# img = Transparent(img_1, img_2, alpha)
# img = Multiply (img_1, img_2)
# img = Color_burn(img_1, img_2)
# img = Color_dodge(img_1, img_2)
# img = Linear_burn(img_1, img_2)
# img = Linear_dodge(img_1, img_2)
# img = Lighten(img_1, img_2)
# img = Dark (img_1, img_2)
# img = Screen(img_1, img_2)
# img = Overlay(img_1, img_2)
# img = Soft_light(img_1, img_2)
# img = Hard_light(img_1, img_2)
# img = Vivid_light(img_1, img_2)
# img = Pin_light(img_1, img_2)
# img = Linear_light(img_1, img_2)
img = Hard_mix(img_1, img_2)

# show the image

plt.figure(1)
plt.imshow(img_1)
plt.axis('off');

plt.figure(2)
plt.imshow(img_2)
plt.axis('off');

plt.figure(3)
plt.imshow(img)
plt.axis('off');

plt.show()

所有的算法原理以及效果图可以参考我以前的博客:

http://blog.youkuaiyun.com/matrix_space/article/details/22416241

http://blog.youkuaiyun.com/matrix_space/article/details/22425209

http://blog.youkuaiyun.com/matrix_space/article/details/22426633

http://blog.youkuaiyun.com/matrix_space/article/details/22427285

http://blog.youkuaiyun.com/matrix_space/article/details/22488159

http://blog.youkuaiyun.com/matrix_space/article/details/22488467

图层混合模式是 Photoshop 中用于控制两个图层之间颜色如何进行交互的一种机制,其核心原理是基于数学公式来计算上下图层像素值的叠加结果。不同的混合模式会根据特定的算法改变最终输出的颜色,从而实现丰富的视觉效果。 ### 1. 常见混合模式及其算法原理 #### 正常(Normal) 在“正常”模式下,顶层的颜色完全覆盖底层的颜色,没有额外的混合操作。 - 输出颜色:$ C_{out} = C_{top} $ 其中 $ C_{top} $ 是上层图层的颜色值 [^1]。 #### 叠加(Overlay) “叠加”模式结合了正片叠底和滤色两种模式的效果,具体取决于底层颜色的亮度。对于暗色调区域,它类似于“正片叠底”,而对于亮色调区域,则类似于“滤色”。 - 算法公式: 如果 $ C_{base} < 0.5 $: $$ C_{out} = 2 \times C_{top} \times C_{base} $$ 否则: $$ C_{out} = 1 - 2 \times (1 - C_{top}) \times (1 - C_{base}) $$ 其中 $ C_{base} $ 是底层图层的颜色值 [^1]。 #### 滤色(Screen) “滤色”模式通常用于提亮图像,其公式是将两个图层的颜色值取反后相乘,再取反得到结果。 - 输出颜色: $$ C_{out} = 1 - (1 - C_{top}) \times (1 - C_{base}) $$ 这种模式特别适合创建发光效果 [^1]。 #### 正片叠底(Multiply) “正片叠底”模式通过将两个图层的颜色值相乘来生成较暗的效果。 - 输出颜色: $$ C_{out} = C_{top} \times C_{base} $$ 这种模式常用于阴影或纹理叠加 [^1]。 #### 柔光(Soft Light) “柔光”模式类似于在图像上投射柔和的光线,根据上层图层的颜色值调整图像的明暗。 - 算法公式: 如果 $ C_{top} < 0.5 $: $$ C_{out} = C_{base} - (1 - 2 \times C_{top}) \times C_{base} \times (1 - C_{base}) $$ 否则: $$ C_{out} = C_{base} + (2 \times C_{top} - 1) \times ( \sqrt{C_{base}} - C_{base} ) $$ 其中 $ C_{top} $ 是上层图层的颜色值 [^1]。 #### 差值(Difference) “差值”模式通过计算两个图层颜色值的绝对差异来生成效果,通常用于对齐图像或创建负片效果。 - 输出颜色: $$ C_{out} = |C_{top} - C_{base}| $$ ### 2. 图像处理中的高反差保留与混合模式 在实际应用中,例如使用“高反差保留”滤镜时,可以通过混合模式进一步增强图像的细节。高反差保留的步骤包括: 1. 复制图层。 2. 对复制的图层应用高反差保留滤镜。 3. 调整半径参数以控制高频成分的提取。 4. 通过调整图层的不透明度或使用图层混合模式(如“叠加”或“柔光”)来控制最终效果 [^2]。 以下是一个简单的 Python 示例代码,模拟“叠加”模式的计算过程: ```python def overlay_mode(top, base): result = [] for t, b in zip(top, base): if b < 0.5: result.append(2 * t * b) else: result.append(1 - 2 * (1 - t) * (1 - b)) return result # 示例输入颜色值(RGB格式,范围0到1) top_color = [0.6, 0.3, 0.8] base_color = [0.4, 0.7, 0.2] output_color = overlay_mode(top_color, base_color) print("叠加模式输出颜色:", output_color) ``` ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值