对于直方图均衡化我们首先要知道一个概念:累计概率
对于每个灰度等级,我们存在概率和累计概率两个概率统计
eg:1 概率0.2 则灰度等级1的累计概率为 0.2
2 概率0.3 则灰度等级2的累计概率为 0.5
3 概率0.1 则灰度等级3的累计概率为 0.6
那么对于256个灰度等级来说,每个灰度等级都有一个概率,和一个累计概率
比如 100 这个灰度等级,他的累计概率是0.5 ,那么255*0.5= New值
就是100 这个灰度等级的映射,那么每个为100的灰度等级以后就用New值替代
这个过程就叫直方图均衡化
import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread('OpenCV\\image0.JPG', 1)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows() # 显示原图
ImgInfo = img.shape
height = ImgInfo[0]
width = ImgInfo[1]
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 将原图灰度化
cv2.imshow('MapBeforeGray',gray)
cv2.waitKey(0)
cv2.destroyAllWindows() # 显示灰度图
count = np.zeros(256, np.float) # 建立一个大小为256的数组
for i in range(height):
for j in range(width):
pixel = gray[i,j] # 图像中像素值的类型是np.uint8
index = int(pixel)
# 0-255的下标,意味着0-255的灰度等级,每当符合其灰度等级,就在count数组中的对应位置加一
count[index] = count[index] + 1
# 计算每种灰度出现的概率
for i in range(255):
count[i] = count[i]/(height*width)
# 用matplot绘图,绘制灰度直方图
x = np.linspace(0,255,256)
y = count
plt.bar(x, y, width=0.8, alpha=1, color='b')
plt.show()
# 计算累计概率
sum1 = float(0)
for i in range(256):
sum1 = sum1 + count[i]
count[i] = sum1
# 计算映射表
map1 = np.zeros(256,np.uint16)
for i in range(256):
map1[i] = np.uint16(count[i]*255)
# 将new值映射成为原灰度值
for i in range(height):
for j in range(width):
pixel = gray[i,j]
gray[i,j] = map1[pixel]
# 根据映射后的图像画直方图
for i in range(height):
for j in range(width):
pixel = gray[i,j] # 图像中像素值的类型是np.uint8
index = int(pixel)
# 0-255的下标,意味着0-255的灰度等级,每当符合其灰度等级,就在count数组中的对应位置加一
count[index] = count[index] + 1
# 用matplot绘图,绘制均衡化后的灰度直方图
x = np.linspace(0,255,256)
y = count
plt.bar(x, y, width=0.8, alpha=1, color='b')
plt.show()
cv2.imshow('MapAfterGray',gray)
cv2.waitKey(0)
cv2.destroyAllWindows() # 显示均衡化后的灰度图
结果如下:
直方图如下:右图为均衡化后的