【问题标题】:Why I could not use cv2.split result as masking for my cv2.bitwise_and?为什么我不能使用 cv2.split 结果作为 cv2.bitwise_and 的掩码?
【发布时间】:2021-09-07 22:19:37
【问题描述】:

我想知道为什么这不起作用?我尝试通过将 OpenCV 徽标拆分为 R、G 和 B 来进行简单操作,然后尝试使用按位和将红色蒙版应用于原始图像,但为什么我没有只得到图像的红色部分?我做错了什么?谢谢。

代码在这里:

【问题讨论】:

  • 你写了bitwise_and,但你的(你的)代码显示bitwise_or!?
  • 对不起,我都试过了,结果还是一样。
  • @IvanSuryaHutomo 你能添加一个链接到你原来的 OpenCV 标志图像吗?

标签: python opencv bitwise-operators mask


【解决方案1】:

您的原始样本很可能不够“干净”。
看起来黑色的R 通道的值接近于零,但不是零。

cv2.bitwise_andcv2.bitwise_ormask 一起使用时,掩码中所有不等于0 的值都被视为“真”(当掩码!= 0 时,该值类似于255)。


仔细检查您发布的图像后发现黑色像素的值实际上是1 而不是0


我从here 下载了一个“干净”的 OpenCV 徽标,它按预期工作:

import cv2
import numpy as np

image = cv2.imread('OpenCV_Logo.png')

B, G, R = cv2.split(image)

# Using bitwise_or and bitwise_and gives the same result.
masked = cv2.bitwise_or(image, image, mask=R)  

cv2.imshow('Red', R)
cv2.imshow('masked', masked)
cv2.waitKey()
cv2.destroyAllWindows()

OpenCV_Logo:

R:

masked:

如您所见,边缘周围有剩余物,因为边缘不是“纯”零。


重现您的问题很简单:
我们可以将1 添加到image 的所有元素中。
为了避免溢出,我使用了cv2.add 而不是+1image = cv2.add(image, np.ones_like(image)

代码示例:

import cv2
import numpy as np

image = cv2.imread('OpenCV_Logo.png')

image = cv2.add(image, np.ones_like(image))

B, G, R = cv2.split(image)

masked = cv2.bitwise_or(image, image, mask=R)

cv2.imshow('image', image)
cv2.imshow('Red', R)
cv2.imshow('masked', masked)
cv2.waitKey()
cv2.destroyAllWindows()

结果:

image:

R:

masked:

如您所见,imageR 看起来相同,但 masked 结果完全不同。


建议的解决方案:

  1. 您可能会找到更好的输入图像。
  2. 您可以将cv2.threshold 应用于R 以将所有低值设置为零。

cv2.threshold 应用阈值,结果是二值图像 - 所有值都为零或 255。

cv2.threshold使用示例:

import cv2
import numpy as np

image = cv2.imread('OpenCV_Logo.png')

image = cv2.add(image, np.ones_like(image))  # Modify the image for the example.

B, G, R = cv2.split(image)

# cv2.THRESH_OTSU finds the threshold automatically, you may use manual threshold instead.
R = cv2.threshold(R, 0, 255, cv2.THRESH_OTSU)[1]

masked = cv2.bitwise_or(image, image, mask=R)

cv2.imshow('image', image)
cv2.imshow('Red', R)
cv2.imshow('masked', masked)
cv2.waitKey()
cv2.destroyAllWindows()

结果:

masked:

【讨论】:

  • 哇,谢谢。这真是一个很好的解释。
【解决方案2】:

您要执行的操作需要 cv2.bitwise_and() 方法,而不是 cv2.bitwise_or() 方法。

试试:

masked = cv2.bitwise_and(image, image, mask=R)
cv2.imshow('mask', masked)

请参阅:OpenCV - Apply mask to a color image 以供参考。

【讨论】:

  • 我已经尝试过 bitwise_and 但结果还是一样。我不知道为什么。
猜你喜欢
  • 1970-01-01
  • 2021-12-22
  • 2021-12-24
  • 2012-11-09
  • 2017-12-04
  • 2015-07-06
  • 2018-06-11
  • 1970-01-01
  • 2019-12-30
相关资源
最近更新 更多