【OpenCV 例程200篇】207. Photoshop 色阶自动调整算法

OpenCV 例程200篇 总目录
201. 图像的颜色空间转换
202. 查表快速替换(cv.LUT)
203. 伪彩色图像处理
204. 图像的色彩风格滤镜
205. 调节色彩平衡/饱和度/明度
206. Photoshop 色阶调整算法
207. Photoshop 色阶自动调整算法


【youcans 的 OpenCV 例程200篇】207. Photoshop 色阶自动调整算法

Photoshop 还提供了自动色阶(Auto Levels)功能。

系统可以根据图像的曝光程度、明暗程度自动调节色彩平衡以达到最佳状态。自动色阶和自动对比度功能算法简单,对于一些图像的处理效果非常显著,具有很强的实用性。

Enhance Per Channel Contrast
Maximizes the tonal range in each channel to produce a more dramatic correction. Because each channel is adjusted individually, Enhance Per Channel Contrast may remove or introduce color casts. The Auto Tone command uses this algorithm.

参考文献: Set Auto adjustment options (adobe.com)

在这里插入图片描述

自动色阶调整的实现方法是,系统基于灰度直方图统计结果,自动设置色阶调整所需的参数。

首先设置修剪比例,白场截断比 C l o w C_{low} Clow 和黑场截断比 C h i g h C_{high} Chigh 。默认值 0.1%,通常取 0.1~1.0%。修剪比例的作用是剔除一定比例的最小、最大灰度的像素,以排除个别异常噪声点的干扰。排除异常干扰后的最小、最大灰度值被设为图像中的黑场、白场基准。

具体地,将图像中灰度值最小的、比例为 C l o w C_{low} Clow 的像素剔除后的最小灰度值作为黑场阈值,将图像中灰度值最大的、比例为 C h i g h C_{high} Chigh 的像素剔除后的最大灰度值作为白场阈值。

例如,一个尺寸 100*100 的图像的像素灰度值从小到大排序的结果是:{75, 77,…,240,241},按 0.1%的修剪比例分别剔除最小、最大灰度值后的结果是:{77, …, 240},则设黑场阈值为 77,白场阈值为 240。

为了提高算法效率,可以先将图像转为灰度图像后计算得到灰度直方图,然后按修剪比例查找得到黑场阈值、白场阈值。

灰场调节值 midtone 实际上是实现 Gamma 变换,可以由灰度均值或中间值得到。

具体地,输入色阶调整有 3 个调节参数:黑场阈值 S i n S_{in} Sin、白场阈值 H i n H_{in} Hin和灰场值 M M M

输入色阶调整算法,先根据黑场阈值和白场阈值对 RGB 颜色通道的动态范围进行线性拉伸,再根据灰场调节值进行幂律变换(伽马变换),对发白(曝光过度)或过暗(曝光不足)的图片进行矫正。

V 1 = { 0 , V i n < S i n 255 , V i n > H i n 255 ∗ ( V i n − S i n ) / ( H i n − S i n ) , e l s e V 2 = 255 ∗ ( V 1 / 255 ) 1 / M \begin{aligned} & V_1 = \begin{cases} 0 &, V_{in}<S_{in} \\ 255 &, V_{in}>H_{in} \\ 255 * {(V_{in}-S_{in})}/{(H_{in}-S_{in})} &, else \end{cases} \\ \\ & V_2 = 255 * (V_1 / 255)^{1/M} \end{aligned} V1=0255255(VinSin)/(HinSin),Vin<Sin,Vin>Hin,elseV2=255(V1/255)1/M

输出色阶调整有 2个调节参数:黑场阈值 S o u t S_{out} Sout、白场阈值 H o u t H_{out} Hout ,分别对应着输出图像的最小像素值、最大像素值。

输出色阶调整方法是基于动态范围进行线性拉伸:

V o u t = { 0 , V 2 < 0 255 , V 2 > 255 S o u t + ( H o u t − S o u t ) ∗ V 2 ∗ / 255 , e l s e V_{out} = \begin{cases} 0 &, V_{2}<0 \\ 255 &, V_{2}>255 \\ S_{out} + {(H_{out}-S_{out})} * V_2 */255 &, else \end{cases} Vout=0255Sout+(HoutSout)V2/255,V2<0,V2>255,else


例程 14.14:Photoshop 色阶自动调整算法

本例程实现 Photoshop 的色阶调整算法,自动设置色阶调整参数,对 R/G/B 各通道的动态范围分别进行拉伸。

    # 14.14 Photoshop 自动色阶调整算法
    def autoLevels(img, cutoff=0.1):
        channels = img.shape[2]  # h,w,ch
        table = np.zeros((1,256,3), np.uint8)
        for ch in range(channels):
            # cutoff=0.1, 计算 0.1%, 99.9% 分位的灰度值
            low = np.percentile(img[:,:,ch], q=cutoff)  # ch 通道, cutoff=0.1, 0.1 分位的灰度值
            high = np.percentile(img[:,:,ch], q=100 - cutoff)  # 99.9 分位的灰度值, [0, high] 占比99.9%
            # 输入动态线性拉伸
            Sin = min(max(low, 0), high - 2)  # Sin, 黑场阈值, 0<=Sin<Hin
            Hin = min(high, 255)  # Hin, 白场阈值, Sin<Hin<=255
            difIn = Hin - Sin
            V1 = np.array([(min(max(255*(i-Sin)/difIn, 0), 255)) for i in range(256)])
            # 灰场伽马调节
            gradMed = np.median(img[:,:,ch])  # 拉伸前的中值
            Mt = V1[int(gradMed)] / 128.  # 拉伸后的映射值
            V2 = 255 * np.power(V1/255, 1/Mt)  # 伽马调节
            # 输出线性拉伸
            Sout, Hout = 5, 250  # Sout 输出黑场阈值, Hout 输出白场阈值
            difOut = Hout - Sout
            table[0, :, ch] = np.array([(min(max(Sout + difOut*V2[i]/255, 0), 255)) for i in range(256)])
        return cv.LUT(img, table)

    # Photoshop 自动色阶调整算法
    img = cv.imread("../images/Fig0310b.tif", flags=1)  # 读取彩色图像
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)  # 转换为灰度图像
    print("cutoff={}, minG={}, maxG={}".format(0.0, gray.min(), gray.min()))

    # 色阶手动调整
    equManual = levelsAdjust(img, 63, 205, 0.8, 10, 245)  # 手动调节
    # 色阶自动调整
    cutoff = 0.1  # 截断比例, 建议范围 [0.0,1.0]
    equAuto = autoLevels(img, cutoff)

    plt.figure(figsize=(9, 6))
    plt.subplot(131), plt.title("Origin"), plt.axis('off')
    plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))
    plt.subplot(132), plt.title("ManualTuned"), plt.axis('off')
    plt.imshow(cv.cvtColor(equManual, cv.COLOR_BGR2RGB))
    plt.subplot(133), plt.title("AutoLevels"), plt.axis('off')
    plt.imshow(cv.cvtColor(equAuto, cv.COLOR_BGR2RGB))
    plt.tight_layout()
    plt.show()

在这里插入图片描述

在这里插入图片描述
从本图可以看出,由于 R,G,B 三个通道单独进行调整,出现了明显的色偏问题。



【本节完】

版权声明:
参考文献: Use the Photoshop Levels adjustment (adobe.com)
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/125373625)
Copyright 2022 youcans, XUPT
Crated:2022-6-20
欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中
欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中

猜你喜欢

转载自blog.csdn.net/youcans/article/details/125384500