【问题标题】:How to separate regions of a GrayScale image equal to threshold value?如何分隔灰度图像的区域等于阈值?
【发布时间】:2019-10-23 06:05:10
【问题描述】:

我正在尝试提取灰度图像中像素值等于阈值的那些区域。是否可以使用 numpy 函数真正做到这一点。

我已经试过了:

ig=cv2.imread("000000000078.png")
b= np.where(ig>84)
print(b)
plt.imshow(b[0])

输出是:

(array([  0,   0,   0, ..., 611, 611, 611]), array([  0,   0,   0, ..., 611, 611, 611]), array([0, 1, 2, ..., 0, 1, 2]))

这是一个数组的元组。我尝试绘制 b[0] 但它没有产生我所要求的区域。有没有其他方法可以这样做?

【问题讨论】:

标签: python numpy opencv matplotlib


【解决方案1】:

有几个问题。首先

ig=cv2.imread("000000000078.png")

为您提供 3 通道图像,而不是灰度图像。你需要加载它灰度:

ig = cv2.imread("000000000078.png", cv2.IMREAD_GRAYSCALE)

然后,您可以使用以下任一方法进行阈值处理:

mask = cv2.threshold(ig, 84, 255, cv2.THRESH_BINARY)

或:

mask = np.uint8(ig>84)

那么区域可以被提取为:

filtered_img = cv2.bitwise_and(ig, ig, mask=mask)

plt.imshow(filtered_img)

【讨论】:

  • 很好,优雅的答案
  • 谢谢!它工作正常,但有没有办法将区域与图像分开?
  • 对于每个标签,您可以选择具有该标签的所有像素(请参阅其他答案)。然后你可以使用boundingRect 来切出图片部分。
  • @QuangHoang 到目前为止,我已经完成了以下操作。 rt=img[region==True] rect=cv2.boundingRect(rt) 但它返回为 rect = (0,0,1,36833) 这是什么意思?我做错了吗?
【解决方案2】:

...提取灰度图像中像素值等于到阈值的区域。

您可以使用 NumPy 的 equal 完成工作。

import numpy as np
from skimage import io
import matplotlib.pyplot as plt

img = io.imread('https://i.stack.imgur.com/qFzHW.png')

threshold = 32
region = np.equal(img, threshold)

fig, ax = plt.subplots(1, 2)
ax[0].imshow(img, cmap='gray')
ax[1].imshow(region, cmap='gray')
for a in ax:
    a.set_axis_off()
plt.show(fig)

请注意,为了这个演示,摄影师图像已被量化,因此img 中只有 4 个不同的强度值,即 32、64、96 和 128。

根据 cmets,我猜 OP 希望使用 region 作为 PNG 图像的透明图层蒙版。这是执行此操作的相关代码:

separate = np.stack([img, img, img, 255*np.uint8(region)], axis=-1)
io.imsave("filename.png", separate)

【讨论】:

  • 谢谢!它工作正常,但有没有办法将区域与图像分开?
  • 你这是什么意思?
  • 我想基本上从像素值等于阈值的图像中提取区域。
  • 在这种情况下,您可以使用 region 作为 PNG 图像的透明图层蒙版。
  • 我刚刚编辑了我的答案以更好地满足您的需求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-22
  • 1970-01-01
  • 1970-01-01
  • 2011-09-23
  • 2012-07-21
相关资源
最近更新 更多