对比度是指图像中明暗区域最亮的白和最暗的黑之间不同亮度层级的测量,差异范围越大代表对比越大。 当对比率达到 120:1 就可以容易地显示生动、丰富的色彩,对比率高达 300:1 时就可支持各阶的颜色。
对比度对视觉效果的影响非常关键。高对比度对于图像的清晰度、细节表现、灰度层次表现都有很大帮助。
对比度调整的目的通常是增强对比度,形成清晰的图像效果和醒目的视觉冲击力。
Photoshop 提供了自动对比度调整功能(AutoContrast),通过自动将图像最深的颜色加强为黑色,最亮的部分加强为白色,以增强图像的亮度和暗度的对比度。
Photoshop 中的自动对比度调整算法,与自动色阶调整算法基本相同,区别在于对比度自动调整不是对三个通道分别调整,而是对各通道按统一的比例进行调整。首先获取图像的亮度信息,然后根据修剪比例对亮度进行动态范围的拉伸,同比例调整 R,G,B 三个通道,因此不会出现色偏问题。
Enhance Monochromatic Contrast
Clips all channels identically. This preserves the overall color relationship while making highlights appear lighter and shadows appear darker. The Auto Contrast command uses this algorithm.
输入色阶调整,先根据黑场阈值和白场阈值对图像的动态范围进行线性拉伸,再根据灰场调节值进行伽马变换,对发白(曝光过度)或过暗(曝光不足)进行矫正。
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
输出色阶调整是基于动态范围进行线性拉伸:
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} =
本例程实现 Photoshop 的对比度自动调整算法,对三个通道同时调整。
# 14.15 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)
def autoContrast(img, cutoff): # 自动对比度调整
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) # 转换为灰度图像
# 计算 0.1%, 99.9% 分位的灰度值
Sin = np.percentile(gray, q=cutoff) # cutoff=0.1, 0.1 分位的灰度值
Hin = np.percentile(gray, q=100 - cutoff) # 99.9 分位的灰度值, [0, per999] 占比99.9%
# 输入动态线性拉伸
difIn = Hin - Sin
V1 = np.array([(min(max(255 * (i-Sin)/difIn,0), 255)) for i in range(256)])
# 灰场伽马调节, Mt: 0.01~9.99
gradMed = np.median(gray) # 拉伸前的中值
Mt = V1[int(gradMed)] / 160. # 拉伸后的映射值
V2 = 255 * np.power(V1/255, 1/Mt) # 伽马调节
# 输出线性拉伸
Sout, Hout = 5, 250 # Sout 输出黑场阈值, Hout 输出白场阈值
difOut = Hout - Sout
table = np.array([(min(max(Sout + difOut*V2[i]/255, 0), 255)) for i in range(256)]).astype("uint8")
imgTone = cv.LUT(img, table)
return imgTone
# Photoshop 自动对比度调整算法
img = cv.imread("../images/Fig0310b.tif", flags=1) # 读取彩色图像
# img = cv.imread("../images/demist02.png", flags=1) # 读取彩色图像
# 色阶自动调整
cutoff = 0.1 # 截断比例, 建议范围 [0.0,1.0]
levelsAuto = autoLevels(img, cutoff)
# 对比度自动调整
cutoff = 0.1 # 截断比例, 建议范围 [0.0,1.0]
contrastAuto = autoContrast(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("AutoLevels"), plt.axis('off')
plt.imshow(cv.cvtColor(levelsAuto, cv.COLOR_BGR2RGB))
plt.subplot(133), plt.title("AutoContrast"), plt.axis('off')
plt.imshow(cv.cvtColor(contrastAuto, 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/125389684)
Copyright 2022 youcans, XUPT
Crated:2022-6-20
欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中
欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中
201. 图像的颜色空间转换
202. 查表快速替换(cv.LUT)
203. 伪彩色图像处理
204. 图像的色彩风格滤镜
205. 调节色彩平衡/饱和度/明度
206. Photoshop 色阶调整算法
207. Photoshop 色阶自动调整算法
208. Photoshop 对比度自动调整算法