局部颜色校正
原理
我们将介绍一种局部颜色校正的技术,用以提高数字图像的对比度。当图像整体太暗或太亮的时候,我们可以使用Gamma校正的技术提高图像的对比度。
图一 从左至右:分别是较暗原始图像,Gamma系数为0.5的Gamma校正,直方图均衡化

图二 从左至右:分别是较亮原始图像,Gamma系数为2.5的Gamma校正,直方图均衡化

图三 从左至右:分别是原始图像,Gamma系数为0.5、2.5,0.75,1.5的Gamma校正图像
图一和图二是分别使用Gamma校正提高对比度之后的效果。在第一幅较暗的图像中我们使用,第二幅较亮的图像二中我们使用
。图像方法的直方图信息表面经过Gamma校正之后,提高了图像的动态范围。当图像中既含有较暗区域又含有较亮区域的时候,这种情况下,如果仅仅使用一个Gamma对整幅图像进行Gamma校正时,输出的图像效果将很差。因为Gamma校正是一种全局的方法,某一部分相近的像素将被映射到相同的图像灰度值,并没有考虑到图像像素邻域的信息。
图像三显示的是在既包含较暗区域又包含较亮区域的图像中,不可能用一种Gamma校正值就取得较好的效果。一种折中的办法是,根据图像的平均灰度值水平对Gamma值进行选择。当图像平均灰度信息大于127.5的时候使用,对图像亮度进行抑制;当图像灰度信息小于127.5的时候使用
,对图像亮度进行增强。我们假设图像用无符号8bit表示的图像,那么我们可以根据上述的讨论得到如下式子:
在既有较暗区域又有较亮区域的图像中,全局Gamma校正效果不能取得较好的效果,那么,考虑到图像邻域的信息,我们可以使用局部的信息,对图像进行Gamma校正。较暗的区域对图像进行增亮处理,较亮的区域适当的对其进行抑制。局部颜色校正方法可以根据邻域内像素的灰度值情况,把同一输入像素值,映射成不同水平的像素灰度值。
算法步骤
假设输入图形为8bit的RGB图像,整个算法可以分两步进行:
1. 根据输入图像计算出掩膜图像
2. 结合输入图像和掩膜图像计算出最终结果
掩膜图像一般根据彩色图像各个通道的图像灰度值获得。假设RGB图像各个通道的像素灰度值为R,G,B,则掩膜图像可以表示为;
之后对掩膜图像进行反转并进行高斯滤波:

高斯滤波的时候,我们选取较大核进行滤波,以保证对比度不会沿着边缘方向过度减小。上述的输出结果图像表明:图像哪部分需要提亮,哪部分需要减暗。比如,图像中较亮区域将获得较小的Mask值,该区域应该减暗。
最后输入图像表示为:
如果掩膜图像M(x,y)大于128,将得到一个大于1的指数,将对图像亮度进行抑制;当掩膜图像M(x,y)小于128,,将得到一个小于1的指数,将对图像增亮;当掩膜图像M(x,y)等于128的时候,并不该边图像的亮度值。
实现代码:
#Local_Color_correction
img = cv2.imread('Hydrangeas.jpg')
h,w = img.shape[:2]
I = zeros((h,w),dtype=float64)
Out_img = img.copy()
B = array(img[:,:,0],dtype=float64)
G = array(img[:,:,1],dtype=float64)
R = array(img[:,:,2],dtype=float64)
print(B.dtype)
for i in range(0,h):
for j in range(0,w):
I[i,j] = ((B[i,j]+G[i,j]+R[i,j]))/3.0
Revert_I = full((h,w),255.0,dtype=float64)
Mast = Revert_I-I
Mast_Blur = cv2.GaussianBlur(Mast,(41,41),0)
for k in range(0,3):
for i in range(0,h):
for j in range(0,w):
Exp = 2**((128-Mast_Blur[i,j])/128.0)
Value = uint8(255*((img.item(i,j,k)/255.0)**Exp))
Out_img.itemset((i,j,k),Value)
cv2.namedWindow("original image")
cv2.namedWindow("output image")
cv2.imshow("original image",img)
cv2.imshow("output image",Out_img)
cv2.imwrite("Hydrangeas_LCC.jpg",Out_img)
cv2.waitKey(0) # 等待键盘触发事件,释放窗口
图像效果:





参考资料: