Segmentation - Understanding Images Better

在前面的章节,我们已经看了一些发现图像特征的技术,这些技术能够帮助我们描述图像中的各种各样的物体。我们也介绍了Haar Cascades,它能帮助我们识别图像中的脸部。关于这些算法的一个很有趣的事情是它们的局部本质。所有这些算法都会查看其邻域中的点,以将某个像素标记为特征像素。在本章,我们将向前推进一步,尝试从一个不同的角度来分析一张给定的图片。我们将看看有助于我们查看更大的图像区域的技术,并从中得出有意义的结论。这将帮助我们将图像分割为诸如背景,前景,水域和草地等区域

下列是本章涉及的算法和技术列表:

  • Contour detection
  • Watershed algorithm
  • Superpixels
  • Graph cut

Introduction to segmentation

分割的意思究竟是什么?分割图像是将图像分解成更小的具有有意义的信息的区域的过程,并帮助我们理解图像的整体内容。例如,让我们看看下面的图片(图1)。左侧是原始图像,在右侧看到对应的分割图像。正如我们所看到的,该算法成功将图像的相似的区域组成一起。比如整个灌木背景被分组为深绿色。黄色的草地和动物前方的草地被染成了一块。在本章中,我们将看看将帮助我们实现类似结果的不同技术。并非所有技术都适用于所有情况,因此有必要了解些不同的技术:

在我们专门研究每种算法之前,一个很好的提示是所有这些算法在内部是如何使用基于其颜色值的像素聚类的。这些算法之间的唯一区别是用于聚类的参数。有些使用欧几里德距离,有些使用更复杂的公式,我们将在接下来的章节中看到。

Contour detection

让我们以一个最简单的分隔技术开始:轮廓。只有输入,轮廓法除了图像中物体的边界之外,没有其他输入。比如,在图片中,你有不同类型的瓶子,你想要将他们每一个都分隔出来。轮廓检测算法将尝试追踪每个瓶子的边界并形成闭环。图像中的每一个闭环表示一个轮廓。你可能会想,轮廓不是和边缘相似么?他们有一些微小的差异。轮廓总是形成闭环,然而边缘可以是打开的。一个轮廓检测算法将尝试把边缘组合起来形成一个闭环。

下述代码用来抽取图像中的轮廓。为了得到更好的结果,我们首先把图像转化为灰度图,然后使用sobel边缘检测:

from skimage import measure
from skimage.io import imread
from skimage.color import rgb2gray
from skimage.filters import sobel
import matplotlib.pyplot as plt

# Read an image
img = imread('contours.png')

# Convert the image to grayscale
img_gray = rgb2gray(img)

# Find edges in the image
img_edges = sobel(img_gray)

# Find contours in the image
contours = measure.find_contours(img_edges, 0.2)

# Display the image and plot all contours found
fig, ax = plt.subplots()
ax.imshow(img_edges, interpolation='nearest', cmap=plt.cm.gray)
for n, contour in     enumerate(contours):
    ax.plot(contour[:, 1], contour[:, 0], linewidth=2)
    ax.axis('image')
    ax.set_xticks([])
    ax.set_yticks([])
plt.show()

正如我们看到的,该算法能够完美地检测到圆和正方形。The two-color boundary that you see in the output consists of the inner and the outer edges for each shape.

As the image gets more complicated, the results are not that good. You can try an experiment with Lenna’s image and see the results yourself. So how do we tackle more complicated images? Simple! By using more sophisticated algorithms. Let’s look at the Watershed algorithm next.

如果图片变得复杂一些,结果可能没有那么好。你可以尝试用Lena的图片做一下实验,然后看一下结果。那么我们如何处理更复杂的图片呢?很简单,使用更精细的算法。下面让我们看一下分水岭算法。

The Watershed algorithm

这是一个有趣的算法,它从物理世界中提取类比。在研究论文和其他文章中解释这种算法的最常用方式是与地理浮雕相比较。想象一个有许多陨石坑的地区(例如月球表面),我们希望为这些陨石坑填充不同颜色的水。我们最初从标记每个火山口的中心开始,然后继续用彩色的水填充火山口,直到水位达到刚好接触相邻火山口边界的点(假设所有火山口都靠近)。在我们用彩色水填充所有陨石坑后,我们已经成功地分割出了我们表面上的每个坑。够简单!

Superpixels

Normalized Graph cut

Summary