如何使用Python对图片进行阈值分割

介绍

在计算机视觉中,图像处理和分析是应用最广泛的技术之一。对于一张图像来说,阈值分割是最基本的处理方法之一。其作用是将灰度图像二值化。算法会将所有大于或等于指定阈值的像素设置为1,将小于该阈值的所有像素设置为0。

本文将介绍如何使用Python对图像进行阈值分割。而且,我们将使用Python Imaging Library(PIL)——一种基于Python的图像处理库。

准备工作

首先,我们需要安装PIL。我们可以使用pip进行安装。

pip install Pillow

现在我们已经安装了PIL,我们需要导入相关库。

from PIL import Image, ImageFilter

我们导入了 Image 和 ImageFilter 模块。 Image 模块是PIL库的核心模块,提供了图像处理基础功能。 ImageFilter 模块提供了一些过滤器,可以让我们在对图像进行操作时使用。

加载图像

在我们进行阈值分割之前,首先需要加载图像。可以使用Image.open()方法打开一张图片。我们可以使用以下代码加载名为“image.jpg”的图像。

img = Image.open("image.jpg")

img.show()

该代码将打开名为“image.jpg”的图像,并通过img.show()方法将其显示出来。

注:在运行Python代码时,上述操作需要确保图像在同一目录下。

灰度图像

在执行所有图像操作之前,我们需要将彩色图像转换为灰度图像。使用convert()方法将彩色图像转换为灰度图像。这是由于我们的目标是将灰度图像二值化。

grayscale_img = img.convert("L")

grayscale_img.show()

该代码将彩色图像转换为灰度图像,并使用 grayscale_img.show() 方法将其显示出来。

阈值分割

确定阈值

在执行阈值分割之前,我们需要选择合适的阈值。通常,选择阈值是基于直方图分析进行的。直方图显示了图像像素值出现的频率。我们可以使用matplotlib和numpy库在Python中创建直方图。

我们可以使用以下代码创建直方图:

import numpy as np

from matplotlib import pyplot as plt

plt.hist(np.array(grayscale_img).ravel(), bins=256, color='black')

plt.show()

上述代码将创建一个表示灰度图像像素值出现频率的直方图。

注意: 我们需要使用 numpy 模块中的 ravel() 方法将图像转换为一维数组。 bins 参数表示该图中将出现多少个柱形。

我们可以使用以下代码创建图像直方图:

如图所示,像素大部分分布在 100-220 之间。此外,有一个较大的峰值。根据上述图形形状,我们选择一个阈值为 127。

二值化

在选择阈值之后,我们可以将灰度图像二值化。我们可以使用 point() 方法将灰度图像中的所有像素设置为0或1。这可以通过检查像素值与阈值之间的关系实现。

以下代码演示了将所有像素0或1的操作:

threshold_value = 127

binary_img = grayscale_img.point(lambda x: 0 if x < threshold_value else 255, '1')

binary_img.show()

注意: point() 方法返回一个图像副本,并且不能原地修改图像对象。这就是为什么我们在二值化操作后返回 binary_img 对象的原因。

上述代码将图像基于阈值进行二值化,并使用 binary_img.show() 方法将其显示出来。

以下是完整代码:

from PIL import Image, ImageFilter

import numpy as np

from matplotlib import pyplot as plt

img = Image.open("image.jpg")

img.show()

grayscale_img = img.convert("L")

grayscale_img.show()

plt.hist(np.array(grayscale_img).ravel(), bins=256, color='black')

plt.show()

threshold_value = 127

binary_img = grayscale_img.point(lambda x: 0 if x < threshold_value else 255, '1')

binary_img.show()

后端开发标签