灰度直方图
定义:
性质:
-
直方图不包含空间信息
一幅图像有唯一的直方图,
不同的图像可能有相同的直方图。
-
∑ i = 0 2 k − 1 H ( r i ) = M × N \sum_{i=0}^{2^k-1}H(r_i) = M\times N i=0∑2k−1H(ri)=M×N
k:图像位数,2k : 灰度级数,M,N:图像行数,列数
直方图均衡化
如果图像的灰度值集中在一个小区间内,对比度低。直方图均衡化是指通过每个像素的灰度变换,使全部灰度级别基本均匀分布,图像具有较大动态范围,增强图像整体对比度。
直方图均衡化算法要求:
-
灰度变换曲线单调增长;
-
对于8位图像,函数的值域应在0和255之间,避免截止和饱和。
-
输出图像灰度尽可能分布均匀
常用的经典直方图均衡化算法:
s
=
r
m
a
x
A
∑
i
=
0
r
H
i
s = \frac{r_{max}}{A}\sum_{i=0}^{r}H_i
s=Armaxi=0∑rHi
s = { r m a x A − H 0 ∑ i = 1 r H i , r > 0 0 , r = 0 s = \begin{cases} \frac{r_{max}}{A-H_0}\sum_{i=1}^{r}H_i,& r>0 \\ 0,& r=0 \end{cases} s={A−H0rmax∑i=1rHi,0,r>0r=0
rmax最大允许灰度,例如255,A为总像素数,
Hi为第 i 级灰度的像素数
直方图均衡化算法具有自适应性:不同对比度、不同亮度的图像,应用该算法后得到了大致相同的图像。
直方图均衡化是消除光照等因素造成的图像差异的有效方法。这种将图像转换为统一形式的做法,对于后续进行图像分析比较是非常有益的。
不足:
1、输出图像的实际灰度变化范围难达到允许的最大灰度变化范围(0-255)
2、输出图像的直方图虽然接近均匀分布, 但是和理想情况仍有可能存在一定差异。
3、输出图像的灰度级有可能被过多地合并,造成图像信息的丢失。
Code for Python with lib of open-cv
"""
直方图均衡化处理
"""
# write code here ...
import matplotlib.pyplot as plt
import numpy as np
import cv2 as cv
# input a image
img = cv.imread('1.png')
# change img to gray
img = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# show original image
cv.imshow('original',img)
# Get the image's histogram
hist_img = cv.calcHist([img],[0],None,[256],[0,256])
# equalize image
pic = cv.equalizeHist(img)
hist_pic = cv.calcHist([pic],[0],None,[256],[0,256])
# show equalize image
cv.imshow('equalize',pic)
# plot images hist...
plt.plot(hist_img, label='original image')
plt.plot(hist_pic, label='equalize image')
plt.title("histogram equalize")
plt.legend()
plt.show()
Output for Code
Code for Python with lib of numpy
import numpy as np
import cv2 as cv
"""
求直方图分布
"""
def histogram(img):
row,col = img.shape
A = row*col # 总像素数
r = np.arange(256).reshape(256,1)
hist = np.zeros(shape = r.shape,dtype=np.int32)
for i in range(row):
for j in range(col):
if img[i][j] in r:
hist[img[i][j]][0] += 1
return hist/A,A
"""
进行直方图均衡化处理,返回均衡化后的图像
"""
def equalizeHist(img):
hist,A = histogram(img)
Rmax = 255 # 最大允许的灰度
# 累加得到新的灰度级
pro = np.int32(Rmax*np.cumsum(hist))
row, col = img.shape
re_img = img.copy()
for i in range(row):
for j in range(col):
re_img[i][j] = pro[img[i][j]]
cv.imshow('img',img)
cv.imshow('re_img', re_img)
cv.resizeWindow('img', 400, 400)
cv.resizeWindow('re_img', 400, 400)
return re_img
if '__name__'=='__main__':
# input a image
img = cv.imread('1.png')
# change img to gray
img = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# 直方图均衡化处理
equalizeHist(img)