在学习图像增强的理论知识后使用python自己编程实现直方图均衡及灰度窗口变换
直方图均衡化的数学原理
运行结果如下:
代码如下:
#!/usr/bin/env python # -*- coding:utf-8 -*- from pylab import * import cv2 import numpy as np import matplotlib.pyplot as plt import copy mpl.rcParams['font.sans-serif'] = ['SimHei']#解决所画图中中文乱码问题 #计算灰度直方图概率 def calGrayNumP(img,grayNum,row,col): for i in img: for j in i: grayNum[j] += 1# 统计原图灰度级 grayNumP = (grayNum / (row * col)).tolist() # 归一化 计算P return grayNum,grayNumP #图像增强:灰度窗口变换 def slicing(img,maxGray,minGray): # img[any(img) >= minGray and any(img) <= maxGray] = 255 # 进行灰度变换 for i in range(len(img)): for j in range(len(img[0])): if img[i,j] <= maxGray and img[i,j] >= minGray: img[i,j] = 255 else: img[i, j] = 0 #直方图均衡 img = cv2.imread("11.png",0) gray = [i for i in range(256)] row = len(img) col = len(img[0]) changedGrayRank = np.zeros(256) img2 = copy.deepcopy(img) grayNum,grayNumP = calGrayNumP(img,np.zeros(256),row,col)#计算灰度直方图概率 for i in range(256): changedGrayRank[i] = sum(grayNumP[:i+1]) changedGrayRank = changedGrayRank*255#计算变换后的灰度等级 for i in range(256): img2[img2 == i] = int(changedGrayRank[i])#进行灰度变换 grayNum2,grayNumP2 = calGrayNumP(img2,np.zeros(256),row,col)#计算变换后的灰度直方图概率 #图像灰度变换 img3 = cv2.imread("gray1.jpg",0) grayNum3,grayNumP3 = calGrayNumP(img3,np.zeros(256),len(img3),len(img3[0])) img4 = copy.deepcopy(img3) slicing(img4,120,110) grayNum4,grayNumP4 = calGrayNumP(img4,np.zeros(256),len(img4),len(img4[0])) #画图 plt.subplot(241), plt.title('图像1') plt.imshow(img,cmap='gray') plt.axis('off') plt.subplot(242), plt.title('图像1灰度直方图') plt.bar(gray,grayNumP) plt.subplot(243), plt.title('图像1-均衡化后') plt.imshow(img2,cmap='gray') plt.axis('off') plt.subplot(244), plt.title('图像1均衡化后灰度直方图') plt.bar(gray,grayNumP2) plt.subplot(245), plt.title('图像2') plt.imshow(img3,cmap='gray') plt.axis('off') plt.subplot(246), plt.title('图像2灰度直方图') plt.bar(gray,grayNumP3) plt.subplot(247), plt.title('图像2-增强后') plt.imshow(img4,cmap='gray') plt.axis('off') plt.subplot(248), plt.title('图像2增强后灰度直方图') plt.bar(gray,grayNumP4) plt.show()在理解直方图均衡和灰度变换的原理后再进行编程实现并不是一件很难的事,当然现已有很多封装好的模块供人直接使用,自己编程实现只是为了更好地理解记忆相关的理论知识。 实现过程中还是用了较多for循环,尤其是实现灰度窗口变换时,当图像像素量多会造成时间复杂度猛增,还有待改进。 图像的灰度变换有很多种处理,这里只实现了灰度窗口变换这一种,其他还有待实现。