在 Python 中执行图像分割

Preet Sanghavi 2024年2月15日
  1. 在 Python 中安装 scikit-image 模块
  2. 在 Python 中转换图像格式
  3. Python 中的监督分割
  4. Python 中的无监督分割
在 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()

上面代码的输出如下。

Felzenszwalb 的分割

因此,我们通过在有监督和无监督分割方法中采用多种技术,成功地使用 scikit-image 模块在 Python 中执行了图像分割。

作者: Preet Sanghavi
Preet Sanghavi avatar Preet Sanghavi avatar

Preet writes his thoughts about programming in a simplified manner to help others learn better. With thorough research, his articles offer descriptive and easy to understand solutions.

LinkedIn GitHub

相关文章 - Python Image