在 Python 中执行图像分割
在本教程中,我们将学习如何使用 scikit-image
库在 Python 中执行图像分割。
图像分割将图像分成许多层,每一层都由一个智能的像素级掩码表示。根据图像的集成级别组合、阻止和拆分图像。
在 Python 中安装 scikit-image
模块
pip install scikit-image
安装完成后,我们将转换图像格式进行分割。
在 Python 中转换图像格式
应用过滤器和其他处理技术所需的输入是二维向量,即单色图像。
我们将使用 skimage.color.rgb2gray()
函数将 RGB 图像转换为灰度格式。
from skimage import data, io, filters
from skimage.color import rgb2gray
import matplotlib.pyplot as plt
image = data.coffee()
plt.figure(figsize=(15, 15))
gray_coffee = rgb2gray(image)
plt.subplot(1, 2, 2)
plt.imshow(gray_coffee, cmap="gray")
plt.show()
我们在上面的代码中将 scikit
库中的示例咖啡图像转换为灰度。
让我们看一下图像的灰度版本。
我们将使用两种技术进行分割,即监督和无监督分割。
Python 中的监督分割
这种形式的分割需要外部输入才能起作用。我们将使用两种方法执行此类型。
阈值分割——Python 中的手动输入
使用 0-255 的外部像素值来区分图像和背景。结果,图像被更改为大于或小于给定阈值。
我们将使用以下代码执行此方法。
from skimage import data
from skimage import filters
from skimage.color import rgb2gray
import matplotlib.pyplot as plt
coffee = data.coffee()
gray_coffee = rgb2gray(coffee)
plt.figure(figsize=(15, 15))
for i in range(10):
binarized_gray = (gray_coffee > i * 0.1) * 1
plt.subplot(5, 2, i + 1)
plt.title("Threshold: >" + str(round(i * 0.1, 1)))
plt.imshow(binarized_gray, cmap="gray")
plt.show()
plt.tight_layout()
现在让我们看看上面代码的输出,我们可以看到使用各种阈值分割的图像。
让我们学习另一种称为主动轮廓分割的监督分割方法。
Python 中的主动轮廓分割
活动轮廓是一种分割方法,可将感兴趣的像素与图像的其余部分分开,以便使用能量力和限制进行进一步处理和分析。通过将蛇拟合到图像特征,skimage.segmentation.active_contour()
函数创建活动轮廓。
我们将使用以下代码来应用此方法。
import numpy as np
import matplotlib.pyplot as plt
from skimage.color import rgb2gray
from skimage import data
from skimage.filters import gaussian
from skimage.segmentation import active_contour
astronaut = data.astronaut()
gray_astronaut = rgb2gray(astronaut)
gray_astronaut_noiseless = gaussian(gray_astronaut, 1)
x1 = 220 + 100 * np.cos(np.linspace(0, 2 * np.pi, 500))
x2 = 100 + 100 * np.sin(np.linspace(0, 2 * np.pi, 500))
snake = np.array([x1, x2]).T
astronaut_snake = active_contour(gray_astronaut_noiseless, snake)
fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(111)
ax.imshow(gray_astronaut_noiseless)
ax.plot(astronaut_snake[:, 0], astronaut_snake[:, 1], "-b", lw=5)
ax.plot(snake[:, 0], snake[:, 1], "--r", lw=5)
plt.show()
我们使用 skimage
中的示例宇航员图像在上述代码中执行主动轮廓分割。我们圈出我们看到分割发生的部分。
让我们看看这种技术的输出。
现在让我们探索无监督分割技术。
Python 中的无监督分割
我们在这种类型的分割中采用的第一种方法是标记边界方法。
Python 中的标记边界方法
这种方法提供了一个图像,在标记部分之间具有突出的边界。skimage.segmentation.mark_boundaries()
函数返回带有标记区域边界的图像。
我们将使用下面的代码来使用这种技术。
from skimage.segmentation import slic, mark_boundaries
from skimage.data import astronaut
import matplotlib.pyplot as plt
plt.figure(figsize=(15, 15))
astronaut = astronaut()
astronaut_segments = slic(astronaut, n_segments=100, compactness=1)
plt.subplot(1, 2, 1)
plt.imshow(astronaut)
plt.subplot(1, 2, 2)
plt.imshow(mark_boundaries(astronaut, astronaut_segments))
plt.show()
使用上述代码为以下技术获得分割图像。
这种方法中的第二种技术是 Felzenszwalb 的分割。
在 Python 中 Felzenszwalb 的分割
Felzenszwalb 的分割使用快速的、基于最小生成树的聚类来过度分割图像网格上的 RGB 图片。在这种方法中使用像素之间的欧几里得距离。
Felzenszwalb 高效的基于图形的图像分割是使用 skimage.segmentation.felzenszwalb()
函数计算的。
让我们看看下面的代码来执行这种类型的分割。
from skimage.segmentation import felzenszwalb, mark_boundaries
from skimage.color import label2rgb
from skimage.data import astronaut
import matplotlib.pyplot as plt
plt.figure(figsize=(15, 15))
astronaut = astronaut()
astronaut_segments = felzenszwalb(astronaut, scale=2, sigma=5, min_size=100)
plt.subplot(1, 2, 1)
plt.imshow(astronaut)
# Marking the boundaries of
# Felzenszwalb's segmentations
plt.subplot(1, 2, 2)
plt.imshow(mark_boundaries(astronaut, astronaut_segments))
plt.show()
上面代码的输出如下。
因此,我们通过在有监督和无监督分割方法中采用多种技术,成功地使用 scikit-image
模块在 Python 中执行了图像分割。