2021-10-11

直方图规定化

数学原理

在直方图的规定化中有一个十分重要的条件,也是理解构建映射与反映射的关键:原图像经过均衡化之后与规定图像经过均衡化之后所展现的像素的灰度概率密度函数都是均匀分布。
于是可以进行如下操作:
1:将原图像的r进行均衡化,得到s1=T®。
2:将规定图像的z进行规定化,得到s2=G(z)。
3:对步骤2进行反变换:-G(s2)=z,
4:将s1与s2进行拟合,在连续的灰度变化中,s1严格等于s2,但是离散情况下,不能追求严格的相等,将其进行拟合,做到大概的相等即可。
5:总结:r --> s1 --> s2 --> z ,进行灰度数值的替换,得到我们的规定化图像。

工程实现

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

# 展示图像的直方图
def Showimg(imgname):
    plt.hist(imgname.ravel(), bins=255, rwidth=0.8, range=(0, 255),density=True)         # 设定坐标值域
    plt.xlabel('Gray value')                                                             # 设定x轴名字
    plt.ylabel('number')                                                                 # 设定y轴名字
    plt.title(r'Grayscale')                                                              # 设定直方图名字
    plt.show()  

# 图像均衡化之后的灰度级,是个列表的形式,下标代表输入的灰度级,值是输出的灰度级,形成映射,函数返回均衡化之后的图像与灰度值
def Equalize_img(imgname):
    __img = imgname                                       # 原始图像读取
    __img1 = __img.copy()       
    # 生成列表
    __hist1 = np.zeros(256, dtype=np.float32)             # 直方图统计结果-频次
    __Ph = np.zeros(256, dtype=np.float32)                # 灰度频率
    __s = np.zeros(256, dtype=np.float32)                 # 均衡化之后的频率 
    __S = np.zeros(256, dtype=np.float32)                 # 均衡化之后的灰度级是
    __ABS = np.zeros(256, dtype=np.int)                   # 四舍五入之后的灰度级 
    __value = 255                                         # value的值取决于图像的位数,8位就是(256-1)
    # 直方图统计
    __row, __col = np.shape(__img)                        # 图像的高度,与图像的宽度
    # 统计灰度频次
    for i in range(__row):
        for j in range(__col):
            __hist1[__img[i][j]] += 1
    # 计算灰度频率
    for i in range(0,256):  
        __Ph[i] = __hist1[i]/(__row*__col) 
    # 计算均衡化之后的频率 
    for i in range(1,256):
        __s[0] = __Ph[0]
        __s[i] = (__s[i-1]+__Ph[i])
    # 得出均衡化之后的灰度级
    for i in range(0,256):
        __S[i] = __value*__s[i]                           # 原始图像均衡化之后的映射,下标是原图像的灰度级
                                                          # 值是均衡化之后的灰度级,形成映射
    for i in range(0,256):
        __ABS[i] = math.ceil(__S[i]-0.5)
    # 进行对文件的灰度值重写
    for i in range(__row):
        for j in range(__col):
            __img1[i,j] = __ABS[__img[i,j]]
    return (__img1,__S)

r = cv2.imread(r"C:\Users\li_lei\Desktop\picture\111.png", cv2.IMREAD_GRAYSCALE)         # 原图像的读取
h, w = np.shape(r)                                                                       # 用在图像的替换时使用
img_Equal,S1 = Equalize_img(r)                                                           # img_Equal是均衡化之后的图像,S1是原始图像均衡化之后的映射
                                                                                         # 下标是原图像的灰度级,值是均衡化之后的灰度级,形成映射

z = cv2.imread(r"C:\Users\li_lei\Desktop\picture\ec_lena.jpg", cv2.IMREAD_GRAYSCALE)     # 标定图像的读取
A,S2 = Equalize_img(z)                                                                   # A是均衡化之后的图像(这里没有用),原始图像均衡化之后的映射
                                                                                         # 下标是原图像的灰度级,值是均衡化之后的灰度级,形成映射

# 构建原图形均衡化之后的映射表,将S1相应的值给S与GZ拟合
S = list()                                                                               # S是数学原理中的s1,这里是将列表进行精简,生成列表
for i in range(256):
    if S1[i] in S:
        pass
    else:
        S.append(S1[i])

# 构建映射表,将S2的的下标给Z,将S2相应的值给GZ,形成映射表
GZ = list()                                                                              # GZ是数学原理中的s2
Z = list()                                                                               # Z是我们想要的灰度数值
for i in range(256):                                                                       
    if S2[i] in GZ:
        pass
    else:
        GZ.append(S2[i])
        Z.append(i)

# 拟合并重写图像灰度值 S中与GZ相同的直接重写,其他的不变//可以自行进行代码的优化
for i in range(h):
    for j in range(w):
        if img_Equal[i,j] in GZ:
            index1 = GZ.index(img_Equal[i,j])
            img_Equal[i,j] = Z[index1]
        else:
            pass
# 查看均衡化之后的直方图
Showimg(img_Equal)

效果展示

原图形为lena图:在这里插入图片描述
直方图为:
在这里插入图片描述
目标图像为均衡化之后的lena图(参考笔者上篇文章):
在这里插入图片描述
直方图为:
在这里插入图片描述
规定化之后的图形为:
在这里插入图片描述
直方图为:
在这里插入图片描述

总结:

本次算法还有很大的优化空间,最后呈现的直方图并不是完全拟合目标图形,但是对于实际效果来看,目视相差不大。不能完全拟合的原因:在算法的工程实现当中s1–>s2出现了一些灰度值没有合适的拟合数值,笔者没有对这些灰度值进行处理,其保持原值,大家可以自己探索更好的处理方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值