采用Python实现图像的直方图均衡化。
直方图均衡化是图像处理领域中利用图像直方图对对比度进行调整的方法,其主要思想是将一副图像的直方图分布变成近似均匀分布,从而增强图像的对比度。这种方法通常用来增加许多图像的全局对比度,尤其是当图像的有用数据的对比度相当接近的时候。通过这种方法,亮度可以更好地在直方图上分布,这样就可以用于增强局部的对比度而不影响整体的对比度。
这种方法对于背景和前景都太亮或者太暗的图像非常有用,这种方法尤其是可以带来X光图像中更好的骨骼结构显示以及曝光过度或者曝光不足照片中更好的细节。
这种方法的一个主要优势是它是一个相当直观的技术并且是可逆操作,如果已知均衡化函数,那么就可以恢复原始的直方图,并且计算量也不大。这种方法的一个缺点是它对处理的数据不加选择,它可能会增加背景噪声的对比度并且降低有用信号的对比度。
直方图均衡化和规定化都是通过全局直方图调节来改变图像的对比度,其实就是根据一个表来做映射。均衡化一句话,就是拿图像本身的累积分布表(cdf)来做映射。规定化就是图像B拿图像A的累积分布表(cdf)来做映射。
直方图均衡化效果:
直方图可视化:
Python代码:
#coding:utf-8
#*********************************************************************************************************
'''
说明:利用python/numpy/opencv实现直方图均衡化,其主要思想是将一副图像的直方图分布变成近似均匀分布,从而增强图像的对比度
算法思路:
1)以灰度图的方式加载图片;
2)求出原图的灰度直方图,计算每个灰度的像素个数在整个图像中所占的百分比;
3)计算图像各灰度级的累积概率密度分布;
4)求出新图像的灰度值。
'''
import cv2
import numpy as np
import matplotlib.pyplot as plt
def Origin_histogram( img ):
#建立原始图像各灰度级的灰度值与像素个数对应表
histogram = {}
for i in range( img.shape[0] ):
for j in range( img.shape[1] ):
k = img[i][j]
if k in histogram:
histogram[k] += 1
else:
histogram[k] = 1
sorted_histogram = {}#建立排好序的映射表
sorted_list = sorted( histogram )#根据灰度值进行从低至高的排序
for j in range( len( sorted_list ) ):
sorted_histogram[ sorted_list[j] ] = histogram[ sorted_list[j] ]
return sorted_histogram
def equalization_histogram( histogram, img ):
pr = {}#建立概率分布映射表
for i in histogram.keys():
pr[i] = histogram[i] / ( img.shape[0] * img.shape[1] )
tmp = 0
for m in pr.keys():
tmp += pr[m]
pr[m] = max( histogram ) * tmp
new_img = np.zeros( shape = ( img.shape[0], img.shape[1] ), dtype = np.uint8 )
for k in range( img.shape[0] ):
for l in range( img.shape[1] ):
new_img[k][l] = pr[img[k][l]]
return new_img
def GrayHist( img ):
# 计算灰度直方图
height, width = img.shape[:2]
grayHist = np.zeros([256], np.uint64)
for i in range(height):
for j in range(width):
grayHist[img[i][j]] += 1
return grayHist
if __name__ == '__main__':
#读取原始图像
img = cv2.imread( 'lowlight.png', cv2.IMREAD_GRAYSCALE )
#计算原图灰度直方图
origin_histogram = Origin_histogram( img )
#直方图均衡化
new_img = equalization_histogram( origin_histogram, img )
origin_grayHist = GrayHist(img)
equaliza_grayHist = GrayHist( new_img )
x = np.arange(256)
# 绘制灰度直方图
plt.figure( num = 1 )
plt.subplot( 2, 2, 1 )
plt.plot(x, origin_grayHist, 'r', linewidth=2, c='black')
plt.title("Origin")
plt.ylabel("number of pixels")
plt.subplot( 2, 2, 2 )
plt.plot(x, equaliza_grayHist, 'r', linewidth=2, c='black')
plt.title("Equalization")
plt.ylabel("number of pixels")
plt.subplot( 2, 2, 3 )
plt.imshow( img, cmap = plt.cm.gray )
plt.title( 'Origin' )
plt.subplot( 2, 2, 4 )
plt.imshow( new_img, cmap = plt.cm.gray )
plt.title( 'Equalization' )
plt.show()