数字图像处理——直方图匹配【像素级别处理】(python)
文章目录
数字图像处理——直方图匹配【像素级别处理】(python) 直方图匹配实现步骤 代码实现
直方图匹配实现步骤
由输入图像得到p r ( r) ,并由 ( L − 1 ) ∫ 0 r (L-1)\int_{0}^{r} (L−1)∫0rP r ( w ) d w ( w)dw (w)dw求得s的值 使用 G ( z ) = ( L − 1 ) ∫ 0 r G(z)=(L-1)\int_{0}^{r} G(z)=(L−1)∫0rP z ( t ) d t ( t)dt (t)dt中指定的PDF来求得变换函数 G ( z ) G(z) G(z) 求得反变换函数 z = G z=G z=G -1 ( x ) (x) (x) ;因为z是由s得到的,所以处理是s到z 的映射,而后者正是我们所期望的值 首先用 ( L − 1 ) ∫ 0 r (L-1)\int_{0}^{r} (L−1)∫0rP r ( w ) d w ( w)dw (w)dw对输入的图像进行均衡得到输出图像;该图像的像素值是s值,对均衡后的图像中具有s值的每一个像素执行 z = G z=G z=G -1 ( x ) (x) (x),得到输出图像中的相应像素。当所有像素处理完后,输出图像的PDF将等于指定的PDF。对于反函数的变换就是x与y互换,若存在函数 u = f ( x ) u=f(x) u=f(x)、 v = g ( x ) v=g(x) v=g(x),其 g ( x ) g(x) g(x)为 f ( x ) f(x) f(x)的反函数,即 f f f -1 ( x ) = g ( x ) (x)=g(x) (x)=g(x)可表示为 v = g ( f ( x ) ) v=g(f(x)) v=g(f(x))
代码实现
输入:
import cv2import numpy as npimport matplotlib.pyplot as plt img = cv2.imread('Fig0323.tif') # 月球表面图片H = img.shape[0]W = img.shape[1]x = np.arange(256) # 作为index使用hr = np.zeros(256) # 原始图片的灰度统计pr = np.zeros(256) # 原始图片的概率密度rtos = np.zeros(256) # r-s对应关系hs = np.zeros(256) # 直方图均衡之后的灰度值thz = np.zeros(256) # 目标直方图灰度值tpz = np.zeros(256) # 目标直方图的概率密度rtoz = np.zeros(256) # r-z的对应关系Gz = np.zeros(256) # G(z)的值Zg = np.zeros(256) # G(z)的反函数hz = np.zeros(256) # 实际得到的匹配图像的直方图# 统计原始图片的直方图for row in range(H):for col in range(W):hr[img[row, col]] += 1# 直方图均衡# 先计算概率密度for i in range(256):pr[i] = hr[i] / (H * W)for i in range(256): # i=[0,255]temp = 0for j in range(i + 1): # j=[0,i]temp += pr[j]rtos[i] = round(temp * 255) # 四舍五入取整hisImg = np.zeros((H, W, 3), np.uint8) # 建立直方图均衡变换之后的图片for row in range(H):for col in range(W):hisImg[row, col] = rtos[img[row, col]]# 统计均衡后的图片的直方图for row in range(H):for col in range(W):hs[hisImg[row, col]] += 1# 使用类似于图3.25a的概率分布图(估计值)# 对应的几个拐点# i thz# 0 0# 4 400000# 16 45600# 185 0# 205 34200# 255 0for i in range(256):if i < 5:thz[i] = i * 100000elif i < 17:thz[i] = 518133 - 29533 * ielif i < 186:thz[i] = 49950 - i * 270elif i < 206:thz[i] = 1710 * (i - 185)else:thz[i] = 684 * (255 - i)# 统计目标直方图的概率分布ztotal = np.sum(thz)for i in range(256):tpz[i] = thz[i] / ztotal# 计算G(z)的值,同样采用直方图均衡化方法for i in range(256): # i=[0,255]temp = 0for j in range(i + 1): # j=[0,i]temp += tpz[j]Gz[i] = round(temp * 255) # 四舍五入取整# for i in range(256):# print(i, Gz[i])# 因为给出的概率分布没有水平线,所以Gz是单调递增的(除了一个点x=185)# 这里考虑没有单调增的情况,实现r->s->Gz->z的映射# 求G(z)的反函数,这样求出来的反函数可能会有某个Zg[i]==0for i in range(256):Zg[int(Gz[i])] = ifor i in range(1, 256):if Zg[i] == 0:for j in range(1, 256): # 如果Zg[i]为0,则从左右开始搜索最接近i的非零值,设置为Zg[i]的值if i - j >= 0 and Zg[i - j] != 0:Zg[i] = Zg[i - j]elif i + j < 256 and Zg[i + j] != 0:Zg[i] = Zg[i + j]breakSpecifiedImg = np.zeros((H, W, 3), dtype=np.uint8) # 建立规定直方图变换之后的图片# 求出r->s->Gz->z的映射for i in range(256):rtoz[i] = Zg[int(rtos[i])]# 利用新的映射绘制新图for row in range(H):for col in range(W):SpecifiedImg[row, col] = rtoz[img[row, col]]# 统计真正匹配图像的直方图for row in range(H):for col in range(W):hz[SpecifiedImg[row, col]] += 1# print(hz)# 原图plt.subplot(2, 4, 1)plt.axis('off')plt.title('Original image')plt.imshow(img)# 原图的直方图plt.subplot(2, 4, 2)plt.bar(x, hr)plt.title('Histogram of original image')# 均衡后的图片plt.subplot(2, 4, 3)plt.axis('off')plt.title('After equalization')plt.imshow(hisImg)# r->s的变化函数# plt.subplot(3, 2, 4)# plt.title('s=T(r)')# plt.scatter(x, rtos)# 均衡化后的直方图plt.subplot(2, 4, 4)plt.title('Histogram after equalization')plt.bar(x, hs)# 目标直方图plt.subplot(2, 4, 5)plt.title('Specified histogram')plt.plot(x, thz)# Gz和Zgplt.subplot(2, 4, 6)plt.title('G(z) and its reverse')plt.plot(x, Gz, Zg)# 新的图片plt.subplot(2, 4, 7)plt.axis('off')plt.title('Specified Image')plt.imshow(SpecifiedImg)# 新的直方图plt.subplot(2, 4, 8)plt.title('Real specified histogram')plt.bar(x, hz)plt.show()
输出
查看更多关于数字图像处理——直方图匹配【像素级别处理】(python)的详细内容...