使用 RangeSlider 对图像进行阈值处理

Beginner

This tutorial is from open-source community. Access the source code

简介

本实验将演示如何在 Matplotlib 中使用 RangeSlider 小部件来控制图像的阈值处理。阈值处理的目的是将灰度图像转换为二值图像,其中像素要么是黑色,要么是白色。这对于图像分割很有用,我们希望从图像中提取某些特征。

虚拟机提示

虚拟机启动完成后,点击左上角切换到笔记本标签,以访问 Jupyter Notebook 进行练习。

有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作验证无法自动化。

如果你在学习过程中遇到问题,可以随时向 Labby 提问。课程结束后提供反馈,我们会及时为你解决问题。

生成一张虚拟图像

首先,我们将使用 NumPy 的随机模块生成一张虚拟灰度图像。我们将设置种子以确保结果可重现。

np.random.seed(19680801)
N = 128
img = np.random.randn(N, N)

显示图像及其直方图

接下来,我们将使用 Matplotlib 的imshow函数显示图像,并使用hist显示其直方图。我们将创建一个包含两个子图的图形,一个用于显示图像,另一个用于显示直方图。

fig, axs = plt.subplots(1, 2, figsize=(10, 5))
fig.subplots_adjust(bottom=0.25)

im = axs[0].imshow(img)
axs[1].hist(img.flatten(), bins='auto')
axs[1].set_title('Histogram of pixel intensities')

创建范围滑块

现在我们将创建范围滑块(RangeSlider)小部件,它将允许我们调整图像的阈值。我们将为滑块创建一个新的轴,并将其添加到图形中。

slider_ax = fig.add_axes([0.20, 0.1, 0.60, 0.03])
slider = RangeSlider(slider_ax, "Threshold", img.min(), img.max())

在直方图中添加垂直线

为了更便于观察阈值处理的效果,我们将在直方图中添加垂直线,以指示当前的阈值。我们将分别为下限和上限阈值创建两条线。

lower_limit_line = axs[1].axvline(slider.val[0], color='k')
upper_limit_line = axs[1].axvline(slider.val[1], color='k')

为滑块创建一个回调函数

我们将创建一个回调函数,每当用户使用滑块更改阈值时,该函数就会被调用。该函数将更新图像的颜色映射以及直方图上垂直线的位置。

def update(val):
    ## 由 RangeSlider 传递给回调的 val
    ## 将是一个 (min, max) 元组

    ## 更新图像的颜色映射
    im.norm.vmin = val[0]
    im.norm.vmax = val[1]

    ## 更新垂直线的位置
    lower_limit_line.set_xdata([val[0], val[0]])
    upper_limit_line.set_xdata([val[1], val[1]])

    ## 重绘图形以确保更新
    fig.canvas.draw_idle()


slider.on_changed(update)

显示图形

最后,我们将显示包含图像和滑块的图形。

plt.show()

总结

在本实验中,我们展示了如何在 Matplotlib 中使用范围滑块(RangeSlider)小部件来控制图像的阈值处理。我们展示了如何创建一个伪灰度图像、显示该图像及其直方图、创建一个滑块来调整阈值,并根据滑块值更新图像和直方图。此技术可用于图像分割以及其他需要从图像中提取特定特征的应用。