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

PythonPythonBeginner
立即练习

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

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

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