如何选择 NumPy 数组中的所有非黑色像素?

新手上路,请多包涵

我正在尝试使用 NumPy 获取与特定颜色不同的图像像素列表。

例如,在处理以下图像时:

在此处输入图像描述

我设法使用以下方法获得了所有黑色像素的列表:

 np.where(np.all(mask == [0,0,0], axis=-1))

但是当我尝试这样做时:

 np.where(np.all(mask != [0,0,0], axis=-1))

我得到一个很奇怪的结果:

在此处输入图像描述

看起来 NumPy 只返回了 R、G 和 B 非 0 的索引

这是我正在尝试做的一个最小示例:

 import numpy as np
import cv2

# Read mask
mask = cv2.imread("path/to/img")
excluded_color = [0,0,0]

# Try to get indices of pixel with different colors
indices_list = np.where(np.all(mask != excluded_color, axis=-1))

# For some reason, the list doesn't contain all different colors
print("excluded indices are", indices_list)

# Visualization
mask[indices_list] = [255,255,255]

cv2.imshow(mask)
cv2.waitKey(0)

原文由 ofir dubi 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 501
2 个回答

对于选择除黑色像素以外的所有像素的第二种情况,您应该使用 np.any 而不是 np.all

 np.any(image != [0, 0, 0], axis=-1)

或者简单地通过 ~ 反转布尔数组来获得黑色像素的补充:

 black_pixels_mask = np.all(image == [0, 0, 0], axis=-1)
non_black_pixels_mask = ~black_pixels_mask

工作示例:

 import numpy as np
import matplotlib.pyplot as plt

image = plt.imread('example.png')
plt.imshow(image)
plt.show()

在此处输入图像描述

 image_copy = image.copy()

black_pixels_mask = np.all(image == [0, 0, 0], axis=-1)

non_black_pixels_mask = np.any(image != [0, 0, 0], axis=-1)
# or non_black_pixels_mask = ~black_pixels_mask

image_copy[black_pixels_mask] = [255, 255, 255]
image_copy[non_black_pixels_mask] = [0, 0, 0]

plt.imshow(image_copy)
plt.show()

在此处输入图像描述


如果有人使用 matplotlib 绘制结果并得到完全黑色的图像或警告,请参阅这篇文章: 将所有非黑色像素转换为一种颜色不会产生预期的输出

原文由 Georgy 发布,翻译遵循 CC BY-SA 4.0 许可协议

必要性:需要具有这种形状的矩阵 = (any,any,3)

解决方案:

 COLOR = (255,0,0)
indices = np.where(np.all(mask == COLOR, axis=-1))
indexes = zip(indices[0], indices[1])
for i in indexes:
    print(i)

解决方案 2:

获取特定颜色的间隔,例如红色:

 COLOR1 = [250,0,0]
COLOR2 = [260,0,0] # doesnt matter its over limit

indices1 = np.where(np.all(mask >= COLOR1, axis=-1))
indexes1 = zip(indices[0], indices[1])

indices2 = np.where(np.all(mask <= COLOR2, axis=-1))
indexes2 = zip(indices[0], indices[1])

# You now want indexes that are in both indexes1 and indexes2

解决方案 3 - 证明有效

如果以前的方法不起作用,那么有一种解决方案可以 100% 起作用

从 RGB 通道转换为 HSV。从 3D 图像制作 2D 蒙版。二维蒙版将包含色调值。比较色调比 RGB 更容易,因为色调是 1 个值,而 RGB 是具有 3 个值的向量。在你拥有带有 Hue 值的 2D 矩阵之后,像上面那样做:

 HUE1 = 0.5
HUE2 = 0.7

indices1 = np.where(HUEmask >= HUE1)
indexes1 = zip(indices[0], indices[1])

indices2 = np.where(HUEmask <= HUE2)
indexes2 = zip(indices[0], indices[1])

您可以为饱和度和价值做同样的事情。

原文由 Martin 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题