Python直方图处理(直方图均衡化、规定化)

一、直方图均衡化

在统计学中,直方图是一种对数据分布情况的图形表示,是一种二维统计图表,它的两个坐标分别是统计样本和该样本对应的某个属性的度量。
在这里插入图片描述
灰度直方图是关于灰度级分布的函数,是对图像中灰度级分布的统计。灰度直方图是将数字图像中的所有像素,按照灰度值的大小,统计其出现的频率。

对比度是画面黑与白的比值,也就是从黑到白的渐变层次。比值越大,从黑到白的渐变层次就越多,从而色彩表现越丰富。对比度对视觉效果的影响非常关键,一般来说对比度越大,图像越清晰醒目,色彩也越鲜明艳丽;而对比度小,则会让整个画面都灰蒙蒙的。
直方图均衡化又称直方图修平,就是把一已知灰度概率分布的图像,经过一种变换,使之演变成一幅具有均匀灰度概率分布的新图像。它是一种很重要的非线性点运算,使用该方法可以加强图像的局部对比度,尤其是当图像的有用数据的对比度相当接近的时候。通过这种方法,亮度可以更好的在直方图上分布。

二、直方图均衡化原理

在这里插入图片描述

三、直方图均衡化结果

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

直方图均衡化处理python代码实现过程:

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

# 导入原始图像,色彩空间为灰度图
src_img = cv2.imread('YaoGan/img/avg.jpg', 0)
# 调用cv2.calcHist 函数绘制直方图
img_hist = cv2.calcHist([src_img], [0], None, [256], [0, 256])

# 直方图均衡化,调用cv2.equalizeHist 函数实心
result_img = cv2.equalizeHist(src_img)
# 显示原始图像
cv2.imshow('src_img', src_img)
# 显示均衡化后的图像
cv2.imshow('result_img', result_img)
cv2.waitKey(0)
# 用蓝色绘制原始图像直方图
plt.plot(img_hist, color="b")
plt.show()
plt.hist(img_hist.ravel(), 256, [0, 256])
plt.show()
# 绘制均衡化后的直方图
plt.hist(result_img.ravel(), 256, [0, 256])
plt.show()

四、直方图规定化

直方图规定化是指一幅输入图像经过点运算变化,将原图像的灰度直方图改造成特定的非均匀分布的形状,使其能够更好地突出图像中人们感兴趣的部分,以此得到更好的增强效果。
但由于数字图像的灰度级是离散并且是有限的,所以直方图规定化的结果一般只是与目标直方图的形状大体接近,并非理想的完全一致。
直方图规定化本质上即寻找一个从灰度级𝑘到f(t)的映射,使新的灰度级f(t)分布接近规定化的函数。

直方图规定化的应用
① 能有效地改善图像的整体或局部特征,广泛运用在图像增强处理中。
② 保证不同图像的影调风格的一致性,在处理艺术图像时十分有用。

五、直方图规定化原理

直方图规定化有两种方式:SML单映射和GML组映射。
① SML单映射的实现原理是:首先计算原始图像和规定目标的累计直方图(将统计直方图归一化到(0, 1)之间,再计算累计概率分布函数),然后对原图像的累计直方图寻求一一映射关系(每个灰度值映射到与目标的累计直方图最近的点)。有了映射关系后,遍历原图像的每个像素点,做相应的点运算变换即可。
在这里插入图片描述
② GML单映射的实现原理是:首先计算原始图像和规定目标的累计直方图(将统计直方图归一化到(0, 1)之间,再计算累计概率分布函数),然后对原图像的累计直方图进行分组:先在原图像的累计直方图中找到与目标直方图的每个灰度值距离最近的点(如下图的所示的 0→3;3→5;7→7,即0,3,7为在原图像中要找的点),让点与点之间构成一组,映射到目标直方图中对应的灰度值。有了映射关系后,遍历原图像的每个像素点,做相应的点运算变换即可。
在这里插入图片描述

六、直方图规定化结果

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

直方图规定化代码:

# 直方图规定化,
import cv2
import numpy as np
import matplotlib.pyplot  as plt

def calcHist(mat):
    # 统计元素个数
    mat = np.array(mat)
    hist = []
    for i in range(256):
        hist.append(len(mat[mat == i]))
    return hist

def get_map(Hist):
    # 计算概率分布Pr
    Hist = np.array(Hist)
    sum_Hist = sum(Hist)
    Pr = Hist / sum_Hist
    # 计算累计概率Sk
    Sk = []
    temp_sum = 0
    for n in Pr:
        temp_sum = temp_sum + n
        Sk.append(temp_sum)
    Sk = np.array(Sk)
    return Sk

# 得到图片像素的概率分布
def get_infer_map(infer_img):
    infer_Hist = calcHist(infer_img)
    infer_map = get_map(infer_Hist)
    return infer_map

# 根据两张图的概率分布计算像素值映射关系
def get_finalmap(infer_map, img_map):
    final_map = []  # 原图像素点映射到目标图的map
    index = 0
    for i in range(len(img_map)):
        # 防止像素值超过255
        if index == 255:
            final_map.append(255)
            continue
        # 将像素值依据自身概率分布映射到目标图片的概率分布上
        if infer_map[index] > img_map[i]:
            final_map.append(index)
        else:
            while (infer_map[index] <= img_map[i]):
                index += 1
                # 防止像素值超过255
                if index == 255:
                    break
            final_map.append(index)
    return final_map

def get_new_img(img, infer_map):
    new_img = img.copy()
    img_map = get_infer_map(img)
    final_map = get_finalmap(infer_map, img_map)
    # 遍历,将每个像素点的值进行映射
    for i in range(256):
        new_img[img == i] = final_map[i]
    return new_img

def showGray(src_img,title):
    # 调用cv2.calcHist 函数绘制直方图
    img_hist = cv2.calcHist([src_img], [0], None, [256], [0, 256])
    plt.plot(img_hist, color="b")
    plt.title(title)
    plt.show()

if __name__ == "__main__":
    #选取基准图像
    # infer_img = cv2.imread('YaoGan/img/10.jpg',0)
    infer_img = cv2.imread('YaoGan/img/aveImg.png',0)   
    cv2.imshow('Infer Image',infer_img)
    showGray(infer_img,'Infer Image')
    cv2.waitKey(0)
    # 计算参考映射关系
    infer_map = get_infer_map(infer_img)
    
    #读取待规范化的图像
    img_org = cv2.imread('YaoGan/img/avg.jpg', 0)
    cv2.imshow('Source Image of Gray',img_org)
    showGray(img_org,'Source Image of Gray')
    # 根据映射关系获得新的图像
    new_img = get_new_img(img_org, infer_map)

    cv2.imshow('Result Image', new_img)
    showGray(new_img,'Result Image')
    cv2.waitKey(0)
    cv2.destroyAllWindows()
  • 46
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值