【问题标题】:Applying Sobel filter from SciPy.ndimage从 SciPy.ndimage 应用 Sobel 过滤器
【发布时间】:2019-03-11 17:07:03
【问题描述】:

我正在尝试应用 SciPy.ndimage 中的 Sobel 运算符并复制 Wikipedia 上显示的结果,但图像非常不同。

维基百科上显示的结果显示边缘更加明显。

下面列出了我正在使用的代码。可以更改此代码以与 Wikipedia 上显示的结果一致吗?下面附上来自维基百科的原始图像和结果图像。

import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
from scipy.ndimage import filters


# Images from https://en.wikipedia.org/wiki/Sobel_operator
im_original = np.array(Image.open('Valve_original_(1).PNG').convert('L'))
im_sobel = np.array(Image.open('Valve_sobel_(3).PNG').convert('L'))

# Construct two ndarrays of same size as the input image
imx = np.zeros(im_original.shape)
imy = np.zeros(im_original.shape)

# Run the Sobel operator
# See https://docs.scipy.org/doc/scipy/reference/generated/scipy.ndimage.sobel.html
filters.sobel(im_original,1,imx,cval=0.0)  # axis 1 is x
filters.sobel(im_original,0,imy, cval=0.0) # axis 0 is y

magnitude = np.sqrt(imx**2+imy**2)

# Construct the plot

fig = plt.figure(figsize=(10,8))

ax1 = fig.add_subplot(221)
ax1.set_title('Original (Wikipedia)')
ax1.axis('off')
ax1.imshow(im_original, cmap='gray')

ax2 = fig.add_subplot(222)
ax2.set_title('Sobel operator - as shown on Wikipedia')
ax2.axis('off')
ax2.imshow(im_sobel, cmap='gray')

ax3 = fig.add_subplot(224)
ax3.set_title('Sobel operator - from scipy.ndimage')
ax3.axis('off')
ax3.imshow(magnitude, cmap='gray')

plt.savefig('sobel.png')
plt.show()

图片

原始图片:Valve_original_(1).PNG

维基百科上显示的结果:Valve_sobel_(3).PNG

【问题讨论】:

  • 我认为与不确定如何处理的随机图像进行比较并不是特别有用。看起来它只是为了更好地显示边缘而进行了标准化——这并不意味着他们使用了“更好”的 Sobel 实现或任何东西。 Wiki 上图片的作者丢失了生成他们上传的多张图片的代码,因此很可能不再存在可比较的来源。如果有的话,这些文章中的图像实际上应该经过编辑,以提供真实的结果,并提供一个指向实时代码存储库的链接,以显示它们是如何生成的,IMO。
  • 我的意思是,甚至无法知道它们是先转换为灰度,还是更改为 L*a*b* 并取 L 通道或其他东西;很难准确地重建作者使用的过程。更好的问题; 为什么你要复制它?
  • 这纯粹是一个学习练习。公平地说,我在代码中所做的是对灰度转换后的图像进行 Sobel 过滤,并且有了这些信息,其他人应该能够独立于基础算法的确切实现来重现结果?
  • @AlexanderReynolds 是正确的——不知道图像是如何进行预处理和后处理的,很难匹配维基百科图像。这是一个更接近一点的想法。如果您检查magnitude(例如plt.hist(magnitude.ravel(), bins=50))的直方图,您会看到它有一个长尾,最大值约为 3.5,但大多数值都在 0 和 1.0 之间。如果您绘制 magnitude 并将较大的值裁剪为 1.0(例如 ax3.imshow(magnitude, cmap='gray', vmax=1.0)),则该图更接近于维基百科图像。 (根据需要调整 vmax 的值。)
  • @John 绝对,您的图像看起来像您所期望的那样,应该或多或少与 OpenCV 完全相同。如果我做了 Sobel 并在一个新库中获得了 Wikipedia 结果,我会担心它正在对值进行规范化或裁剪。请注意,您也可以尝试与 Sobel 内核稍有不同的 Scharr 内核,并且(通常)给出更准确的导数近似。 This page 有一些在 scikit-image 中常用的不同边缘过滤器。

标签: python scipy sobel


【解决方案1】:

为了解决这个问题,我根据上面的 cmets 发布了一个答案。

Wikipedia 上显示的蒸汽机的 Sobel 过滤图像已以未指定的其他方式处理,因此无法完全复制。最有可能的是,原始 RGB 图像首先被转换为灰度,然后被钳制。

查看从 SciPy.ndiamage 获得的 Sobel 过滤图像的强度直方图,请参见下图,大多数像素的中心在强度 3.5 附近。应用 50 的钳位值会生成更接近 Wikipedia 页面上显示的图像。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-16
    • 2015-07-31
    • 2019-03-27
    • 2015-02-14
    • 2017-11-19
    • 2015-07-29
    • 1970-01-01
    相关资源
    最近更新 更多