「眼前的黑不是黑,你说的白是什麽白」-- 你是我的眼(萧煌奇)
没错,并非所有图片都是在理想的环境下拍摄的,
光线不足(太黑)或是过曝(太白)问题都会让图片中的讯息丢失,
造成人们看不清楚照片中的物品。
好在我们可以统计各个像素值的数量,得知这张图片灰度的分布。
然後使用数学来解决它!
什麽是灰度直方图(Histogram):
X轴为像素值(0 ~ 255),Y轴为该值的数量。
灰度直方图的特性:
若图片全黑(像素为0),则直方会集中在图的左侧,代表图片太暗了。
观察照片(angry):
因为下图(MDFK)较上图暗,所以直方图的bin偏向左边。
观察照片(neutral):
因为上图(女人)各个灰度值发生较平均,所以直方图的bin呈现平均分散的状态,
而下图(婴儿)黑白分明,少有中间灰色,所以直方图的bin集中在两侧,中间只有零星几个bin。
我们挑选一张可爱的婴儿表情图片进行解说,
由於原图片太小,我将它放大至(600,600)。
idx = 12
gray_img = X_train[idx][:, :, 0].astype("uint8")
gray_img = cv2.resize(gray_img, (600, 600))
plt.figure(figsize=(5, 5))
plt.imshow(gray_img, cmap='gray')
之所以挑选这张照片,
是因为它黑白分明,有利於说明。
在opencv中,有提供equalizeHist函数,将图片进行均衡化(Equalization)。
均衡化:透过拉伸的像素值(对比度拉伸),使得像素分布较均匀,提高对比度。
原理:透过调整累积分布函数(CDF),把像素值高的区域分散给周围区域,使CDF呈现斜直线。
equalized_img = cv2.equalizeHist(gray_img)
cv2.imshow("equal_image", equalized_img)
来看看调整後的图片:
好像有点恐怖...
这时,我们就可以透过灰度直方图的比较来看看发生什麽事:
看起来是因为原本超级白的脸蛋在边缘位置上被黑色污染了,
如果这张图是彩色的,那我可以合理推测婴儿是掉进泥巴坑了。
不~~~~~~~把我可爱的宝宝还来!
有没有更好的均衡化方法呢?有的!
那就是自适应直方图均衡化,
它的改良处在於将图片分成多个区域(如8x8),
每个区域各自做直方图均衡化,所以AHE比HE更适合增强局部对比度。
但直方图均衡化的缺点「放大暗处的杂讯」在AHE中并没有获得改善。
好在有人提出限制对比度自适应直方图均衡化(Contrast Limited Adaptive Histogram Equalization),
限制对比度的核心概念是控制CDF斜率,将突然长太高(超过某阈值)的bin砍掉头,拿去补低的像素值。
clahe = cv2.createCLAHE(clipLimit=2)
clahe_img = clahe.apply(gray_img)
cv2.imshow("clahe_img", clahe_img)
经由CLAHE处理过後图片的对比增加了,
连婴儿的眼睛鼻子嘴巴都看得非常清楚呢!
再来比较CLAHE处理前後的直方图,
灰度分布比只用HE还要更均匀了。
这篇讲到影像处理中常用的图像增强技巧,
目的是让大家认识这个技巧,
我没有深入到讲解演算法的部分,
如果有兴趣知道背後数学的话,
网路上有许多资源可以学习。
>>: Spring boot 配置 Fluent bit 传递 Log
时差学习 Temporal difference learning link 时差学习是通过boot...
今天要来提到的是判断式的部分,在JS中判断式有两种语法:if...else和 switch。 这篇我...
Hashicorp Vault: PKI issue limit Vault Forum 有篇文章询...
前言 前面学习了 Structure, 今天就来介绍 Class, Structure 与 Clas...
Spring 初探 (二) Spring初探(二) ...