SciPy库

SciPy库,与之前我们使用的NumPy和Matplotlib,都是scipy.org提供的用于科学计算方面的核心库。相对NumPy,SciPy库提供了面向更高层应用的算法和函数(其实也是基于NumPy实现的),并以子模块的形式组织,每个子模块对应不同的应用领域,下面列出我们关心的一部分进行说明:
constants:物理和数学常量
fftpack:快速傅里叶(立)变换
integrate: 积分和方程
interpolate: 插值
linalg: 线性代数
ndimage: N维图像处理
optimize: 优化及根求解

安装

sudo apt-get install python-scipy

图像模糊数学原理

以灰度图像为例,把图像的每个像素的灰度值,变换为它周围邻近的N个像素值的平均值,得出的图像就有了模糊效果,但这种效果不理想,体现不出边缘(不够自然吧),所以提出了一种比较理想的方法,就是使用加权平均值,因为对某个像素而言,离它越近的像素,与它的关联性越高,所以权值应该越大,相反,离它越远的像素,与它的关联性越低,权值应该越小。

那分配权值应该使用什么样的算法呢?最常用的就是高斯分布函数

高斯分布函数其实应该是高斯分布的概率密度函数,简称高斯分布函数正态分布函数,它的二维空间的形态像一个,如图:
512px-Gaussian_2d.svg.png

这里我们只关心二维的高斯分布函数,因为等下我们要把它应用在二维图像的像素的权值分配上。下面是二维空间的高斯分布函数公式:
图片描述

这个公式被称作高斯核。如果我们给定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模糊程度对比:
图片描述

小结

下一个笔记将记录有关图像边缘检测的实现,还会继续运用模板卷积运算,将涉及到图像导数,以及用于边缘检测的常用算子的介绍。

参考资料
维基百科:高斯模糊
高斯模糊浅析
高斯模糊的算法
[计算机视觉特征提取与图像处理(第三版)]


jk_v1
1.8k 声望198 粉丝

Linux爱好者,技术积累主要在Linux、Qt、Android,后以Android开发为主,从上层(kotlin,java)到底层(jni,linux)有一定的工作经验和理解,擅长快速学习和知识关联梳理,整合不同技术资源为客户提供合适的解决方案。