本文共享自华为云社区《[Python从零到壹] 五十四.图画增强及运算篇之部分直方图均衡化和主动颜色均衡化处理》,作者: eastmount。

一.部分直方图均衡化

前文经过调用OpenCV中equalizeHist()函数完成直方图均衡化处理,该办法简单高效,但其实它是一种大局意义上的均衡化处理,许多时候这种操作不是很好,会把某些不应调整的部分给均衡处理了。一起,图画中不同的区域灰度散布相差甚远,对它们运用同一种改换常常发生不理想的效果,实际使用中,常常需要增强图画的某些部分区域的细节。

为了解决这类问题,Pizer等提出了部分直方图均衡化的办法(AHE),但AHE办法仅仅考虑了部分区域的像素,忽略了图画其他区域的像素,且关于图画中相似区域具有过度扩大噪声的缺陷。为此K. Zuiderveld等人提出了对比度受限CLAHE的图画增强办法,经过约束部分直方图的高度来约束部分对比度的增强幅度,从而约束噪声的扩大及部分对比度的过增强,该办法常用于图画增强,也能够被用来进行图画去雾操作[1-2]。

在OpenCV中,调用函数createCLAHE()完成对比度受限的部分直方图均衡化。它将整个图画分成许多小块(比方按1010作为一个小块),那么对每个小块进行均衡化。这种办法首要关于图画直方图不是那么单一的(比方存在多峰状况)图画比较有用。其函数原型如下所示:

retval = createCLAHE([, clipLimit[, tileGridSize]])

  • clipLimit参数表明对比度的巨细
  • tileGridSize参数表明每次处理块的巨细

调用createCLAHE()完成对比度受限的部分直方图均衡化的代码如下:

# -*- coding: utf-8 -*-
# By:Eastmount
import cv2  
import numpy as np  
import matplotlib.pyplot as plt
#读取图片
img = cv2.imread('lena.bmp')
#灰度转换
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#部分直方图均衡化处理
clahe = cv2.createCLAHE(clipLimit=2, tileGridSize=(10,10))
#将灰度图画和部分直方图相关联, 把直方图均衡化使用到灰度图 
result = clahe.apply(gray)
#显现图画
plt.subplot(221)
plt.imshow(gray, cmap=plt.cm.gray), plt.axis("off"), plt.title('(a)') 
plt.subplot(222)
plt.imshow(result, cmap=plt.cm.gray), plt.axis("off"), plt.title('(b)') 
plt.subplot(223)
plt.hist(img.ravel(), 256), plt.title('(c)') 
plt.subplot(224)
plt.hist(result.ravel(), 256), plt.title('(d)') 
plt.show()

输出成果如图1所示,图1(a)为原始图画,对应的直方图为图1,图1(b)和图1(d)为对比度受限的部分直方图均衡化处理后的图画及对应直方图,它让图画的灰度值散布更加均衡。能够看到,相关于大局的直方图均衡化,这个部分的均衡化似乎得到的效果更天然一点。

图像增强及运算:局部直方图均衡化和自动色彩均衡化处理

二.主动颜色均衡化

Retinex算法是代表性的图画增强算法,它根据人的视网膜和大脑皮层模拟对物体颜色的波长光线反射才能而构成,对复杂环境下的一维条码具有必定范围内的动态紧缩,对图画边缘有着必定自适应的增强。主动颜色均衡(Automatic Color Enhancement,ACE)算法是在Retinex算法的理论上提出的,它经过计算图画目标像素点和周围像素点的明暗程度及其关系来对终究的像素值进行校对,完成图画的对比度调整,发生相似人体视网膜的颜色恒常性和亮度恒常性的均衡,具有很好的图画增强效果[3-4]。

ACE算法包括两个过程,一是对图画进行颜色和空域调整,完成图画的色差校对,得到空域重构图画;二是对校对后的图画进行动态扩展。ACE算法计算公式如下:

图像增强及运算:局部直方图均衡化和自动色彩均衡化处理

其间,W是权重参数,离中心点像素越远的W值越小;g是相对对比度调节参数,其计算办法如公式(22-2)所示,a表明控制参数,值越大细节增强越明显。

图2是条形码图画进行ACE图画增强后的效果图,经过图画增强后的图(b)对比度更强,改善了原图画的明暗程度,增强的一起坚持了图画的真实性。

图像增强及运算:局部直方图均衡化和自动色彩均衡化处理

由于OpenCV中暂时没有ACE算法包,下面的代码是借鉴“zmshy2128”教师的文章,修正完成的彩色直方图均衡化处理[5]。

# -*- coding: utf-8 -*-
# By:Eastmount
# 参考zmshy2128教师文章
import cv2
import numpy as np
import math
import matplotlib.pyplot as plt
#线性拉伸处理
#去掉最大最小0.5%的像素值 线性拉伸至[0,1]
def stretchImage(data, s=0.005, bins = 2000):   
    ht = np.histogram(data, bins);
    d = np.cumsum(ht[0])/float(data.size)
    lmin = 0; lmax=bins-1
    while lmin<bins:
        if d[lmin]>=s:
            break
        lmin+=1
    while lmax>=0:
        if d[lmax]<=1-s:
            break
        lmax-=1
    return np.clip((data-ht[1][lmin])/(ht[1][lmax]-ht[1][lmin]), 0,1)
#根据半径计算权重参数矩阵
g_para = {}
def getPara(radius = 5):                        
    global g_para
    m = g_para.get(radius, None)
    if m is not None:
        return m
    size = radius*2+1
    m = np.zeros((size, size))
    for h in range(-radius, radius+1):
        for w in range(-radius, radius+1):
            if h==0 and w==0:
                continue
            m[radius+h, radius+w] = 1.0/math.sqrt(h**2+w**2)
    m /= m.sum()
    g_para[radius] = m
    return m
#常规的ACE完成
def zmIce(I, ratio=4, radius=300):                     
    para = getPara(radius)
    height,width = I.shape
    #Python3报错如下 运用列表append修正
    zh = []
    zw = []
    n = 0
    while n < radius:
        zh.append(0)
        zw.append(0)
        n += 1
    for n in range(height):
        zh.append(n)
    for n in range(width):
        zw.append(n)
    n = 0
    while n < radius:
        zh.append(height-1)
        zw.append(width-1)
        n += 1
    #print(zh)
    #print(zw)
    Z = I[np.ix_(zh, zw)]
    res = np.zeros(I.shape)
    for h in range(radius*2+1):
        for w in range(radius*2+1):
            if para[h][w] == 0:
                continue
            res += (para[h][w] * np.clip((I-Z[h:h+height, w:w+width])*ratio, -1, 1))
    return res
#单通道ACE快速增强完成
def zmIceFast(I, ratio, radius):
    print(I)
    height, width = I.shape[:2]
    if min(height, width) <=2:
        return np.zeros(I.shape)+0.5
    Rs = cv2.resize(I, (int((width+1)/2), int((height+1)/2)))
    Rf = zmIceFast(Rs, ratio, radius)             #递归调用
    Rf = cv2.resize(Rf, (width, height))
    Rs = cv2.resize(Rs, (width, height))
    return Rf+zmIce(I,ratio, radius)-zmIce(Rs,ratio,radius)   
#rgb三通道别离增强 ratio是对比度增强因子 radius是卷积模板半径          
def zmIceColor(I, ratio=4, radius=3):               
    res = np.zeros(I.shape)
    for k in range(3):
        res[:,:,k] = stretchImage(zmIceFast(I[:,:,k], ratio, radius))
    return res
#主函数
if __name__ == '__main__':
    img = cv2.imread('test01.png')
    res = zmIceColor(img/255.0)*255
    cv2.imwrite('Ice.jpg', res)

运行成果如图3和图4所示,ACE算法能有效进行图画去雾处理,完成图画的细节增强。

图像增强及运算:局部直方图均衡化和自动色彩均衡化处理

三.总结

本文首要讲解图画部分直方图均衡化和主动颜色均衡化处理。这些算法能够广泛使用于图画增强、图画去噪、图画去雾等领域。

参考文献:

  • [1]王浩,张叶,沈宏海,张景忠.图画增强算法综述[J].我国光学,2017,10(04):438-448.
  • [2]李艳梅. 图画增强的相关技能及使用研究[D].电子科技大学,2013.
  • [3]S. Bidon, Olivier Besson, J. Y. Tourneret. The Adaptive Coherence Estimator is the Generalized Likelihood Ratio Test for a Class of Heterogeneous Environments[J]. IEEE Signal Processing Letters, 2008, 15: 281-284.
  • [4]eastmount. [Python图画处理] 三十八.OpenCV图画增强和图画去雾万字详解(直方图均衡化、部分直方图均衡化、主动颜色均衡化)[EB/OL]. (2021-03-12). blog.csdn.net/ Eastmount/article/details/114706950.
  • [5]zmshy2128. 主动颜色均衡(ACE)快速算法[EB/OL]. (2016-12-05). www.cnblogs.com/zmshy2128/p….

点击关注,第一时间了解华为云新鲜技能~