Python图像处理--直方图,高斯滤波,直方图均衡化

一,PIL(Python Imaging Library Python,图像处理类库)提供了通用的图像处理功能,以及大量有用的基本图像操作,比如图像缩放、裁剪、旋转、颜色转换等。利用 PIL 中的函数,我们可以从大多数图像格式的文件中读取数据,然后写入最常见的图像格式文件中。PIL 中最重要的模块为 Image。
  我们处理数学运算、绘制图表,或者在图像上绘制点、直线和曲线时,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,对其还不太了解,掌握图像的处理是为接下来的功能实现作基础,希望自己加油。

 
posted @ 2020-02-22 15:54  cenyan  阅读(2658)  评论(0编辑  收藏  举报