介绍
在计算机视觉中,图像处理和分析是应用最广泛的技术之一。对于一张图像来说,阈值分割是最基本的处理方法之一。其作用是将灰度图像二值化。算法会将所有大于或等于指定阈值的像素设置为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()