SciPy库
SciPy库,与之前我们使用的NumPy和Matplotlib,都是scipy.org提供的用于科学计算方面的核心库。相对NumPy,SciPy库提供了面向更高层应用的算法和函数(其实也是基于NumPy实现的),并以子模块的形式组织,每个子模块对应不同的应用领域,下面列出我们关心的一部分进行说明:
constants:物理和数学常量
fftpack:快速傅里叶(立)变换
integrate: 积分和方程
interpolate: 插值
linalg: 线性代数
ndimage: N维图像处理
optimize: 优化及根求解
安装
sudo apt-get install python-scipy
图像模糊数学原理
以灰度图像为例,把图像的每个像素的灰度值,变换为它周围邻近的N个像素值的平均值,得出的图像就有了模糊效果,但这种效果不理想,体现不出边缘(不够自然吧),所以提出了一种比较理想的方法,就是使用加权平均值,因为对某个像素而言,离它越近的像素,与它的关联性越高,所以权值应该越大,相反,离它越远的像素,与它的关联性越低,权值应该越小。
那分配权值应该使用什么样的算法呢?最常用的就是高斯分布函数。
高斯分布函数其实应该是高斯分布的概率密度函数,简称高斯分布函数或正态分布函数,它的二维空间的形态像一个钟,如图:
这里我们只关心二维的高斯分布函数,因为等下我们要把它应用在二维图像的像素的权值分配上。下面是二维空间的高斯分布函数公式:
这个公式被称作高斯核。如果我们给定sigma(如0.84089642)的值,以及高斯分布的(范围)大小,就可以得出一个矩阵如:
注意中心元素 (4,4)处有最大值,随着距离中心越远,数值一圈圈地对称减小。这样,矩阵的每个元素相对中心点的权值就已经知道了,如果我们把这个矩阵的中心对应到图像的每个点,就可以知道中心点对应的像素应该如何通过周围的点来计算。
如果矩阵的中心对应到原图像边沿的像素点,那么可能有一部分矩阵的元素落到图像之外,为保证能正常运算,一种简单的处理就是把图像一边的数据复制到缺少的一边去。
对原图像的每个像素点,运用上面的权值矩阵,算出加权平均值,作为新图像的像素值,这个运算可以用原图像与矩阵的卷积来表示,而参与卷积的这个矩阵,叫模板,这种卷积运算,叫模板卷积。模板也称为算子。上面示例的这个矩阵,其实就是高斯平均算子。
高斯模糊
使用高斯平均算子来实现的图像模糊叫高斯模糊(Gaussian blurring,也叫高斯平滑)
被认为是一种最优的图像平滑处理。除了模糊,还可以用来磨皮(美颜)、制作景深、实现梦幻效果等。下面我们使用Python来对一幅图像进行模糊处理。
我们不必自己实现高斯模糊的计算过程,因为前面介绍的scipy的ndimage子模块中就包含了高斯滤波器,它是一个函数:
scipy.ndimage.filters.gaussian_filter(input, sigma, order=0, ...
多维高斯滤波器
input: ndarray
sigma: 高斯核标准偏差,越大越模糊
order: 默认0,使用高斯核进行计算,还可以指定不同值使用高斯一阶、二阶导数,以后再说
以下代码示例以sigma为2,5,10分别对一张图像进行模糊,我们使用的是GRB图像,有3个通道,必须对每个通道都应用滤波器:
from PIL import Image
import numpy as np
from scipy.ndimage import filters
import matplotlib.pyplot as plt
im = np.array(Image.open('Penguins.jpg'))
index = 141 #画1行四列的图,与 1,4,1 同
plt.subplot(index)
plt.imshow(im)
for sigma in (2, 5, 10):
im_blur = np.zeros(im.shape, dtype=np.uint8)
for i in range(3): #对图像的每一个通道都应用高斯滤波
im_blur[:,:,i] = filters.gaussian_filter(im[:,:,i], sigma)
index += 1
plt.subplot(index)
plt.imshow(im_blur)
plt.show()
不同的sigma模糊程度对比:
小结
下一个笔记将记录有关图像边缘检测的实现,还会继续运用模板卷积运算,将涉及到图像导数,以及用于边缘检测的常用算子的介绍。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。