挑战图像处理100问(23)——直方图均衡化

在这里插入图片描述

直方图均衡化( Histogram Equalization )

直方图均衡化是使直方图变得平坦的操作,是不需要计算上面的问题中的平均值、标准差等数据使直方图的值变得均衡的操作。

直方图均衡化保证在图像像素映射过程中原来的大小关系保持不变,即较亮的区域依旧较亮,较暗的依旧较暗,只是对比度增加,不能明暗颠倒;保证像素映射函数的值域在0和255之间。

按照以下步骤对像素值进行处理:

  1. 对图像中的像素点进行统计,统计每个像素值对应的个数和占比
  2. 进行函数映射,zmax是映射范围,一般为255。h(i)h(i)的累加是灰度值的累计像素个数。S是像素点个数。
    Z=ZmaxS i=0z h(i) Z' = \frac{Z_{max}}{S} \ \sum\limits_{i=0}^z\ h(i)

计算方法就是用当前灰度值的累计像素个数乘上要分布映射的范围(255)

  1. 比如100个像素点,其中像素值最小为3,个数为5个,(sum(3) = 5)
  2. 那么就把像素值为3的像素点值改为 255×(5100)=12.75255 \times\left(\frac{5}{100}\right)=12.75 -> 取整 -> 13
  3. 下一个像素值为4,个数有8个,那么sum(4)=5+8=12sum(4) = 5+8 = 12
  4. 把像素值为4的像素点值改为255×(12100)=30.6255 \times\left(\frac{12}{100}\right)=30.6 ----> 取整 ----> 31

依次累加计算像素值。

代码实现

def equalHist(img):
    result = np.zeros_like(img)
    #像素总数
    imgsize = img.size
    #统计0~255的值的个数
    count = np.bincount(img.reshape(-1))
    
    for i in range(count.size):
        #如果这个像素值的个数不为0(就是存在该像素值的点)
        if count[i]:
            #计算累计个数
            sum = count[:i+1].sum()
            x = 255*(sum/imgsize)
            #四舍五入后转为uint8类型
            x = np.around(x).astype(np.uint8)
            #修改原本的像素值,改动放到新的图片上,以免打乱后面的像素值运算
            result[img == i] = x
    
    return result
# 读取图片
path = 'C:/Users/86187/Desktop/image/'
file_in = path + 'cake.jpg' 
img = imread(file_in)

img3 = img.copy()
img3 = equalHist(img3)
imgshow = plt.imshow(img3)
plt.show()
hist1 = plt.hist(img3.reshape(-1),bins=255,rwidth=0.85,range=(0,255))
在这里插入图片描述 在这里插入图片描述 在这里插入图片描述
posted @ 2020-04-16 22:36  田纳尔多  阅读(33)  评论(0编辑  收藏  举报