灰度直方图均衡化----python实现

直方图均衡化是使用图像直方图进行对比度调整的图像处理的方法。

该方法通常会增加许多图像的整体对比度,尤其是当图像的可用数据由接近的对比度值表示时。 通过这种调整,强度可以更好地分布在直方图上。 这允许局部对比度较低的区域获得较高的对比度。 直方图均衡化通过有效地分散最频繁的强度值来实现这一点。

实现原理参考自直方图均衡(维基百科)

第一种是自己写的,消耗时间长。第二种参考自opencv-python的直方图均衡

import cv2
import numpy as np


def equalizationByLoop(img):
    a, b = img.shape
    flatten = np.reshape(img, [-1, ])
    img_list = flatten.tolist()

    # 获取出现的灰度值
    img_set = np.unique(img)
    img_set = np.sort(img_set)
    
    # 获取灰度值出现次数
    cdf = []
    for i in img_set:
        cdf.append(img_list.count(i))
    cdf = np.array(cdf)
    
    # 累积分布函数和计算均衡化
    cdf = np.cumsum(cdf)
    cdf_min = np.min(cdf)
    cdf = (cdf-cdf_min)/(len(img_list)-cdf_min)*255
    
    # 获取新图像 
    for x in range(a):
        for y in range(b):
            index = np.argwhere(img_set == img[x][y])
            img[x][y] = cdf[index]
    return img


def equalizationByNumpy(img):
    hist, bins = np.histogram(img.flatten(), 256, [0, 256])
    # hist是亮度值出现次数的统计
    cdf = hist.cumsum()
    # cdf是出现次数的累积分布函数
    # 如果高灰度值没有次数,但累计分布函数会把它加入。但最后在索引生成新图像时舍去

    # 均衡化处理
    cdf_m = np.ma.masked_equal(cdf, 0)
    cdf_m = (cdf_m - cdf_m.min())*255/(cdf_m.max()-cdf_m.min())
    cdf = np.ma.filled(cdf_m, 0).astype('uint8')

    # 生成新图像
    img2 = cdf[img]
    
    return img2


def main():
    img = cv2.imread('leno.jpg', cv2.IMREAD_GRAYSCALE)
    new_img = np.copy(img)
    # 处理时间长
    # new_img = equalizationByLoop(new_img)
    new_img = equalizationByNumpy(new_img)
    cv2.imshow('img', img)
    cv2.imshow('new img', new_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


if __name__ == '__main__':
    main()  

猜你喜欢

转载自www.cnblogs.com/tianyahai/p/10541810.html
今日推荐