Filters and Features

在理解了图像处理的基础之后,我们来看看一些基本的概率以增强我们的理解,如,kernels,convolution,filters,和基本的 image features。
我们将学习不同类型的image filters,如,Gaussian filter 和 Sobel。以及 edge detection 和 Hough transformations,它们是计算机视觉应用中很基本的预处理步骤。

Image derivatives

Understanding image filters

Gaussian blur

Median filter

Dilation and erosion

Customs filters

Image thresholding

Edge detection

在图像里,检测边缘是一个很重要的概念,并且有很多应用。检测边缘可以帮助我们知道关于图像的结构和图像中物体的边界。
边是图像中那些像素值有很大变化的部分。也就是说,随着我们从左往右扫描图片,如果前一个像素的值会比目前像素的值低很多,那么目前的像素可能是边的一个像素。
正如我们在前一章中提到的,图像的导数是一种寻找像素值改变的方法,因此它可能是寻找图像中的边界的最简单的方法。不过只使用图像的导数并不是非常的rubost,因为具有很多噪音的图像会产生很多假边,这样就会降低视觉系统的整体质量。
目前有许多复杂的边缘检测技术,比如,Sobel和Canny边缘检测器,这些检测器更robust,会产生比较少的假边。

Sobel edge detector

Sobel边缘检测器背后的思想是寻找有较大梯度值的像素。我们不仅希望像素值有改变,还希望改变(梯度)的程度比较大。
我们通过计算图像在x方向和y方向的导数的平方和的平常根来衡量导数的量级,即以下导数的公式:
$$\Delta f=\frac { \partial f }{ \partial x } i+\frac { \partial f }{ \partial y } j+\frac { \partial f }{ \partial z } k$$
为了决定多大的值应该被考虑,我们设置一个threshold。在求出梯度之后,我们只考虑那些超出某个threshold的梯度值。

Sobel edge detector 算法使用的kernels如下:
sobel_h, sobel_v

from skimage import io, filters, color

img = io.imread("../image.jpg")
img = color.rgb2gray(img) 
edge = filters.sobel(img) # find edges using the scikit-image
io.imshow(edge)
io.show()

注意:Sobel算子使用2D数组作为输入,因此首先需要把图像转化为灰度图。

Canny edge detector

Canny边缘检测器是另外一个非常重要的算法。它和Sobel边缘检测器一样,使用了梯度的概念,但是在Sobel中,我们只考虑了梯度的量级。在Canny边缘检测器中,我们还会使用梯度的方向来寻找边。
该算法会使用四个主要的步骤:
1、Smoothing:
在这一步,我们会使用Gaussian filter来减少图像中的噪声。
2、Finding the gradient:
在去除噪声之后,需要通过计算x方向的导数和y方向的导数来求出梯度量级和方向。方向很重要,因为梯度总是垂直于边。因此,如果我们知道梯度的方向,我们也可以找到边的方向。
3、Nonmaximal suppression
在这一步,我们检查哪里的梯度相比它的邻居点来说是最大的,也就是说哪一个点在梯度的方向是局部最大值。如果不是局部最大值,那么该点就不是边的一部分。
4、Thresholding
在Canny算法中,我们会使用两个阈值:高阈值,低阈值,不像在Sobel中我们只使用一个阈值。这叫做 hysteresis thresholding。我们选择所有高于阈值的点作为边的点,然后看看这些点的邻居是否低于高阈值但高于低阈值;如果是,那么这些邻居也将成为边缘的一部分。但是,如果边缘的所有点都低于高阈值,则不会选择这些点。

from skimage import io, color, feature

img = io.imread("../image.jpg")
img = color.rgb2gray(img)

# The function takes the image and standard deviation for the Gaussian filter as the input.
edge = feature.canny(img, 3)  
   io.imshow(edge)
   io.show()

至此,我们已经使用了一些filters来寻找物体的边缘。我们能否检测出图像中的某些特定的形状呢?比如,圆,直线,甚至是椭圆。下面我们将使用Hough transform来看看如何检测图像中特定的形状。Hough transformation是一种通用的框架,给定某种形状的参数方程,它能够检测出图形中的这些形状。

Hough line

在数学中,我们使用两个参数来定义线:斜率和截距。在霍夫线算法中,我们利用相同的概念,并尝试找出图像中存在的线段的斜率和截距。

Hough circle

霍夫圆和霍夫线相似,只是参数方程改变了。对于霍夫圆来说,我们使用下列圆的参数方程:
$$(x-h)^2 + (y-k)^2 = r^2$$
这里(h,k)是圆的中心,r是半径。和斜率,截距不同,霍夫圆会使用图像中的点找到圆的中心和半径。

霍夫线的另外一个变体叫做概率霍夫线(probabilistic Hough line),基本上它做同样的事情,但是是用不同的方法来计算线段的参数,它使用了更复杂的数学。

Summary

本节,我们首先学习了图像filters和convolutions,接着看了一些fillets的例子,比如:Gaussian blur, median filter, dilation, 和 erosion。这些通常都作为大型计算机视觉系统的预处理步骤,很少单独使用。然后介绍了一些有趣的概念,如:边缘检测,主要了解了Canny和Sobel边缘检测器。边缘检测在计算机视觉中有很重要的作用。最后,我们学习了如何使用Hough transformation检测图像中的特定形状。