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)
自动色阶调整的实现方法是,系统基于灰度直方图统计结果,自动设置色阶调整所需的参数。
首先设置修剪比例,白场截断比 ClowC_{low}Clow 和黑场截断比 ChighC_{high}Chigh 。默认值 0.1%,通常取 0.1~1.0%。修剪比例的作用是剔除一定比例的最小、最大灰度的像素,以排除个别异常噪声点的干扰。排除异常干扰后的最小、最大灰度值被设为图像中的黑场、白场基准。
具体地,将图像中灰度值最小的、比例为 ClowC_{low}Clow 的像素剔除后的最小灰度值作为黑场阈值,将图像中灰度值最大的、比例为 ChighC_{high}Chigh 的像素剔除后的最大灰度值作为白场阈值。
例如,一个尺寸 100*100 的图像的像素灰度值从小到大排序的结果是:{75, 77,…,240,241},按 0.1%的修剪比例分别剔除最小、最大灰度值后的结果是:{77, …, 240},则设黑场阈值为 77,白场阈值为 240。
为了提高算法效率,可以先将图像转为灰度图像后计算得到灰度直方图,然后按修剪比例查找得到黑场阈值、白场阈值。
灰场调节值 midtone 实际上是实现 Gamma 变换,可以由灰度均值或中间值得到。
具体地,输入色阶调整有 3 个调节参数:黑场阈值 SinS_{in}Sin、白场阈值 HinH_{in}Hin和灰场值MMM。
输入色阶调整算法,先根据黑场阈值和白场阈值对 RGB 颜色通道的动态范围进行线性拉伸,再根据灰场调节值进行幂律变换(伽马变换),对发白(曝光过度)或过暗(曝光不足)的图片进行矫正。
V1={0,Vin<Sin255,Vin>Hin255∗(Vin−Sin)/(Hin−Sin),elseV2=255∗(V1/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∗(Vin−Sin)/(Hin−Sin),Vin<Sin,Vin>Hin,elseV2=255∗(V1/255)1/M
输出色阶调整有 2个调节参数:黑场阈值 SoutS_{out}Sout、白场阈值 HoutH_{out}Hout ,分别对应着输出图像的最小像素值、最大像素值。
输出色阶调整方法是基于动态范围进行线性拉伸:
Vout={0,V2<0255,V2>255Sout+(Hout−Sout)∗V2∗/255,elseV_{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+(Hout−Sout)∗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,chtable = 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<HinHin = min(high, 255) # Hin, 白场阈值, Sin<Hin<=255difIn = Hin - SinV1 = 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 - Souttable[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学习课』 系列,持续更新中