(1)图像增强
(2)直方图均衡化原理(应用于图像增强)
直方图均衡化三个核心步骤
1.统计直方图中每个灰度级出现的次数
2.计算累计归一化直方图
3.重新计算像素点的像素值
dst = cv2.equalizeHist(src)
import cv2
import numpy as np
import matplotlib.pyplot as plt
img=cv2.imread('lena.png')
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#直方图均衡化处理
result=cv2.equalizeHist(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()
如果需要对彩色图片进行全局直方图均衡化处理,则需要分解 RGB 三色通道,分别进行处理后再进行通道合并。完整代码如下所示:
import cv2
import numpy as np
import matplotlib.pyplot as plt
#读取图片
img=cv2.imread('yxz.jpg')
#彩色图像均衡化 需要分解通道 对每一个通道均衡化
(b,g,r)=cv2.split(img)
bH=cv2.equalizeHist(b)
gH=cv2.equalizeHist(g)
rH=cv2.equalizeHist(r)
#合并每一个通道
result=cv2.merge((bH,gH,rH))
cv2.imshow('input',img)
cv2.imshow('result',result)
#等待显示
cv2.waitKey(0)
cv2.destoryAllWindows()
#绘制直方图
plt.figure('Hist')
#蓝色分量
plt.hist(bH.ravel(),bins=256,normed=1,facecolor='b',edgecolor='b',hold=1)
#绿色分量
plt.hist(gH.ravel(),bins=256,normed=1,facecolor='g',edgecolor='g',hold=1)
#红色分量
plt.hist(rH.ravel(),bins=256,normed=1,facecolor='r',edgecolor='r',hold=1)
plt.xlable('x')
plt.ylable('y')
plt.show()
(1)局部直方图均衡化
调用函数 createCLAHE()实现对比度受限的局部直方图均衡化。它将整个图像分成许多小块(比如按 10×10 作为一个小块),那么对每个小块进行均衡化。这种方法主要对于图像直方图不是那么单一的(比如存在多峰情况)图像比较实用。
retval = createCLAHE([, clipLimit[, tileGridSize]])
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()
(2)自动色彩均衡化(ACE算法)
ACE 算法包括两个步骤,一是对图像进行色彩和空域调整,完成图像的色差校正,得到空域重构图像;二是对校正后的图像进行动态扩展。ACE 算法计算公式如下:
其中,W 是权重参数,离中心点像素越远的 W 值越小;g 是相对对比度调节参数,其计算方法如公式(22-2)所示,a 表示控制参数,值越大细节增强越明显。
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=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 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)