python图像处理:直方图的规定化(直方图匹配)

写在前面
因为笔者数字图像处理的作业是要求用VB来做规定化的处理,笔者写出来后想看看python有什么库可以实现,毕竟像均衡化之类的操作都可以通过py的cv2库里的函数解决,但是在CSDN上查询的时候发现大家都是用openCV或者matlab来做,python并没有相关的函数来进行规定化,唯一一个有规定化代码的但是是需要付钱的,于是笔者就用python写了一个可以做灰度图像直方匹配的代码。
(一)直方图匹配原理介绍
直方图规定化,也叫做直方图匹配,用于将图像变换为某一特定的灰度分布,也就是其目的的灰度直方图是已知的。这其实和均衡化很类似,均衡化后的灰度直方图也是已知的,是一个均匀分布的直方图;而规定化后的直方图可以随意的指定,也就是在执行规定化操作时,首先要知道变换后的灰度直方图,这样才能确定变换函数。规定化操作能够有目的的增强某个灰度区间,相比于,均衡化操作,规定化多了一个输入,但是其变换后的结果也更灵活。
(二)直方图匹配的实现
直方图规定化的实现可以分为一下四步:

  1. 计算原图像的累积直方图
  2. 计算规定直方图的累积直方图
  3. 计算两累积直方图的差值的绝对值
  4. 根据累积直方图差值建立灰度级的映射

(三)编码实现

import cv2

import numpy as np

import matplotlib.pyplot as plt

img0=cv2.imread(r'C:\Users\58381\Desktop\lena.bmp')#读取原图片

scr=cv2.imread(r'C:\Users\58381\Desktop\circle.bmp')#读取目标图片

完成读取之后转图片为灰度图片,笔者目前只会做灰度图片的规定化

#把两张图片转成真正的灰度图片,因为自己只会做灰度图片的规定化

img0=cv2.cvtColor(img0,cv2.COLOR_BGR2GRAY)

img=img0.copy()#用于之后做对比图

scr=cv2.cvtColor(scr,cv2.COLOR_BGR2GRAY)

构造做映射的列表

mHist1=[]

mNum1=[]

inhist1=[]

mHist2=[]

mNum2=[]

inhist2=[]

下面分别对两张图像进行均衡化

#对原图像进行均衡化
for i in range(256):

    mHist1.append(0)

row,col=img.shape#获取原图像像素点的宽度和高度



for i in range(row):

    for j in range(col):

        mHist1[img[i,j]]= mHist1[img[i,j]]+1#统计灰度值的个数

mNum1.append(mHist1[0]/img.size)

for i in range(0,255):

    mNum1.append(mNum1[i]+mHist1[i+1]/img.size)

for i in range(256):

    inhist1.append(round(255*mNum1[i]))
    
 #对目标图像进行均衡化

for i in range(256):

    mHist2.append(0)

rows,cols=scr.shape#获取目标图像像素点的宽度和高度

for i in range(rows):

    for j in range(cols):

        mHist2[scr[i,j]]= mHist2[scr[i,j]]+1#统计灰度值的个数

mNum2.append(mHist2[0]/scr.size)

for i in range(0,255):

    mNum2.append(mNum2[i]+mHist2[i+1]/scr.size)

for i in range(256):

    inhist2.append(round(255*mNum2[i]))

两张图片都均衡化好之后,就通过数组间的映射进行规定化处理

#进行规定化

g=[]#用于放入规定化后的图片像素

for i in range(256):

    a=inhist1[i]

    flag=True

    for j in range(256):

        if inhist2[j]==a:

            g.append(j)

            flag=False

            break

    if flag==True:

        minp=255

        for j in range(256):

            b=abs(inhist2[j]-a)
            if b<minp:                
                                    
                minp=b

                jmin=j

        g.append(jmin)

for i in range(row):

    for j in range(col):

        img[i,j]=g[img[i,j]]

在这里规定化就完成了,我们来看看效果。
先看看原图像以及其灰度直方图

cv2.imshow("原图",img0)
cv2.waitKey(0)
plt.hist(img0.ravel(),256)
plt.show()

原图以及直方图
然后是目标图片的原图以及直方图

cv2.imshow("目标图",scr)
cv2.waitKey(0)
plt.hist(scr.ravel(),256)
plt.show()

在这里插入图片描述
然后看看规定化之后的图片以及其直方图

cv2.imshow("规定化",img)
cv2.waitKey(0)
plt.hist(img.ravel(),256)
plt.show()

在这里插入图片描述
最后把两张图片一起展示。
在这里插入图片描述
写在最后
我会尽快在做完测量的作业之后把彩色图片的规定化编好,由于时间有限,笔者的代码不是特别精简,有很多地方可以优化,大家凑合着看看。

猜你喜欢

转载自blog.csdn.net/qq_44171096/article/details/89232757