Python图像处理--直方图,高斯滤波,直方图均衡化
一,PIL(Python Imaging Library Python,图像处理类库)提供了通用的图像处理功能,以及大量有用的基本图像操作,比如图像缩放、裁剪、旋转、颜色转换等。利用 PIL 中的函数,我们可以从大多数图像格式的文件中读取数据,然后写入最常见的图像格式文件中。PIL 中最重要的模块为 Image。
我们处理数学运算、绘制图表,或者在图像上绘制点、直线和曲线时,Matplotlib是个很好的类库,具有比 PIL 更强大的绘图功能。Matplotlib 可以绘制出高质量的图表,就像本书中的许多插图一样。Matplotlib 中的 PyLab 接口包含很多方便用户创建图像的函数。
我们处理数学运算、绘制图表,或者在图像上绘制点、直线和曲线时,Matplotlib是个很好的类库,具有比 PIL 更强大的绘图功能。Matplotlib 可以绘制出高质量的图表,就像本书中的许多插图一样。Matplotlib 中的 PyLab 接口包含很多方便用户创建图像的函数。
NumPy是非常有名的 Python 科学计算工具包,其中包含了大量有用的思想,比如数组对象(用来表示向量、矩阵、图像等)以及线性代数函数。NumPy 中的数组对象可以帮助你实现数组中重要的操作,比如矩阵乘积、转置、解方程系统、向量乘积和归一化,这为图像变形、对变化进行建模、图像分类、图像聚类等提供了基础。
二,直方图
图像的直方图用来表征该图像像素值的分布情况。用一定数目的小区间(bin)来指定表征像素值的范围,每个小区间会得到落入该小区间表示范围的像素数目。图像的直方图可以使用 hist() 函数绘制。hist() 函数的第二个参数指定小区间的数目。需要注意的是,因为 hist() 只接受一维数组作为输入,所以我们在绘制图像直方图之前,必须先对图像进行压平处理。flatten() 方法将任意数组按照行优先准则转换成一维数组。
代码如下:
1 from PIL import Image 2 from pylab import * 3 #读取图像到数组 4 im=array(Image.open('11.JPG').convert('L')) 5 #新建一个图像 6 figure() 7 #不使用颜色信息 8 gray() 9 #在原点的左上角显示轮廓图像 10 contour(im,origin='image') 11 axis('equal') 12 axis('off') 13 figure() 14 hist(im.flatten(),128) 15 show()
效果:
原图
轮廓图
直方图
三,高斯滤波
高斯滤波是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。其滤波核的值由如下公式得到(用当前点与中心点的欧式距离的平方代替下面的
(x2+y2):
代码如下:
1 import cv2 2 import numpy as np 3 import matplotlib.pyplot as plt 4 5 #读取图片 6 img = cv2.imread('11.JPG') 7 source = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) 8 9 #高斯滤波,这里使用15*15的卷积核 10 result = cv2.GaussianBlur(source, (15,15), 0) 11 12 #显示图形 13 titles = ['Source Image', 'GaussianBlur Image'] 14 images = [source, result] 15 for i in range(2): 16 plt.subplot(1,2,i+1), plt.imshow(images[i], 'gray') 17 plt.title(titles[i]) 18 plt.xticks([]),plt.yticks([]) 19 plt.show()
效果:
四,直方图均衡化
图像灰度变换中一个非常有用的例子就是直方图均衡化。直方图均衡化是指将一幅图像的灰度直方图变平,使变换后的图像中每个灰度值的分布概率都相同。在对图像做进一步处理之前,直方图均衡化通常是对图像灰度值进行归一化的一个非常好的方法,并且可以增强图像的对比度。在这种情况下,直方图均衡化的变换函数是图像中像素值的累积分布函数(cumulative distribution function,简写为 cdf,将像素值的范围映射到目标范围的归一化操作)。
代码:
1 import cv2 # 仅用于读取图像矩阵 2 import matplotlib.pyplot as plt 3 import numpy as np 4 from PIL import Image 5 gray_level = 256 # 灰度级 6 7 8 def pixel_probability(img): 9 """ 10 计算像素值出现概率 11 :param img: 12 :return: 13 """ 14 assert isinstance(img, np.ndarray) 15 16 prob = np.zeros(shape=(256)) 17 18 for rv in img: 19 for cv in rv: 20 prob[cv] += 1 21 22 r, c = img.shape 23 prob = prob / (r * c) 24 25 return prob 26 27 28 def probability_to_histogram(img, prob): 29 """ 30 根据像素概率将原始图像直方图均衡化 31 :param img: 32 :param prob: 33 :return: 直方图均衡化后的图像 34 """ 35 prob = np.cumsum(prob) # 累计概率 36 37 img_map = [int(i * prob[i]) for i in range(256)] # 像素值映射 38 39 # 像素值替换 40 assert isinstance(img, np.ndarray) 41 r, c = img.shape 42 for ri in range(r): 43 for ci in range(c): 44 img[ri, ci] = img_map[img[ri, ci]] 45 46 return img 47 48 49 def plot(y, name): 50 """ 51 画直方图,len(y)==gray_level 52 :param y: 概率值 53 :param name: 54 :return: 55 """ 56 plt.figure(num=name) 57 plt.bar([i for i in range(gray_level)], y, width=1) 58 59 60 if __name__ == '__main__': 61 62 img=Image.open('11.jpg') 63 img=img.convert('L') 64 img.save('111.jpg') 65 img = cv2.imread("111.jpg", 0) # 读取灰度图 66 67 prob = pixel_probability(img) 68 plot(prob, "原图直方图") 69 70 # 直方图均衡化 71 img = probability_to_histogram(img, prob) 72 cv2.imwrite("source_hist.jpg", img) # 保存图像 73 74 prob = pixel_probability(img) 75 plot(prob, "直方图均衡化结果") 76 77 plt.show()
效果:
灰度图
均衡化后的图
直方图
直方图均衡化
结论:
刚接触Python,对其还不太了解,掌握图像的处理是为接下来的功能实现作基础,希望自己加油。