直方图均衡化

兴趣所在,代码小白;自己学习,自我监督
学习《计算机视觉——算法与应用》(Richard Szeliski),希望自己坚持下来。
通过图像的直方图可以获得一些有意义的统计量,比如图1,它的亮度直方图为图2.我们看到其中的黑色最多,白色值稍多,中间值较少。利用直方图均衡化的方法,来使一些暗的值变亮,一些亮的值变暗。
图1
图1
图2
图2
直方图均衡化的方法,是寻找一个映射函数f(I)使映射后的直方图平坦。得到映射函数f(I)首先计算累计分布函数。一般通过下式计算:
c(I)=1NIi=0h(i)=c(I1)+1Nh(I)
一种方法是让累计分布函数为映射函数,即f(I) = c(I)。效果如图4。
图3 均衡化前
图3 均衡化前
图4 均衡化后
图4 均衡化后
从图3,图4的对比中可以看出,均衡化后亮的部分变暗。
另一种映射函数为 f(I)=αc(I)+(1α)I ,是对采取局部补偿的方法改善结果。效果如图6,其中 α=0.3 (数自己瞎写的)。感觉过度效果稍好些。
图5 均衡化前
图5 均衡化前
图6 均衡化后
图6 均衡化后
代码用Python自己写,学习编程,理解思路。

import matplotlib.pyplot as plt
import cv2
import numpy as np

# 统计每个灰度值的像素点个数
# numPixels 为最大灰度值
def Hist(img, rows, cols, numPixels=256, dens=None):
    hist = np.zeros(numPixels)
    for i in range(rows):
        for j in range(cols):
            hist[img[i, j]] += 1
    if (dens == True):
# 每个灰度值的像素点个数占总像素点的比例,即灰度密度
        totalPixels = rows * cols
        for i in range(numPixels):
            hist[i] = hist[i] / totalPixels
        return hist
    else:
        return hist

# 累计分布函数
# cum为累计函数
# cumProj为累计函数在灰度值上的对应值
def Cumulation(hist, numPixels=256):
    cum = np.zeros(numPixels)
    cumProj = np.zeros(numPixels, dtype="int32")
    for i in range(numPixels):
        if i == 0:
            cum[i] = hist[i]
            cumProj[i] = cum[i] * i
        else:
            cum[i] = cum[i-1] + hist[i]
            cumProj[i] = cum[i] * i

    return cum, cumProj

# 直方图均匀化
# "itype=True"可选择采用局部补偿的方法,同时选择alpha值改变均匀化效果
def cvtImage(img, rows, cols, cum, alpha=1):
    if alpha != 1:
        for i in range(rows):
            for j in range(cols):
                img[i, j] = cum[img[i, j]] * alpha + (1 - alpha) * img[i, j]
    else:
        for i in range(rows):
            for j in range(cols):
                img[i, j] = cum[img[i, j]]
    return img

img = cv2.imread("./1.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

rows, cols = gray.shape
gray_ = gray.copy()
hist_ = Hist(gray_, rows, cols, dens=True)

hist = Hist(gray, rows, cols, dens=True)
cum, cumProj = Cumulation(hist)

gray = cvtImage(gray, rows, cols, cumProj, alpha=0.3)
hist = Hist(gray, rows, cols, dens=True)

fig = plt.figure(figsize=(12.5, 24))
ax1 = fig.add_subplot(411)
ax2 = fig.add_subplot(412)
ax3 = fig.add_subplot(413)
ax4 = fig.add_subplot(414)

cv2.imshow("original", gray_)
cv2.imshow("histogram", gray)
cv2.waitKey(0)
cv2.destroyAllWindows()
ax1.plot([x for x in range(256)], cum)
ax2.plot([x for x in range(256)], cumProj)
ax3.plot([x for x in range(256)], hist_)
ax4.plot([x for x in range(256)], hist)
plt.show()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值