为什么我不能使用 cv2.split 结果作为我的 cv2.bitwise_and 的掩码?
Why I could not use cv2.split result as masking for my cv2.bitwise_and?
我想知道为什么这不起作用?我尝试通过将 OpenCV 徽标拆分为 R、G 和 B 来进行简单操作,然后我尝试使用按位和将红色蒙版应用于原始图像,但为什么我没有只得到图像的红色部分?我做错了什么?谢谢。
代码在这里:
您要执行的操作需要 cv2.bitwise_and()
method, not the cv2.bitwise_or()
方法。
尝试:
masked = cv2.bitwise_and(image, image, mask=R)
cv2.imshow('mask', masked)
参考:OpenCV - Apply mask to a color image。
很可能是您的原始样本“不够干净”。
看起来黑色的 R
通道的值接近于零,但 不是 零。
当 cv2.bitwise_and
或 cv2.bitwise_or
与 mask
一起使用时,掩码中所有不等于零的值都被视为“真”(当掩码 != 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
而不是 +1
: image = 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
:
如你所见image
和R
看起来一样,但masked
结果完全不同。
建议的解决方案:
- 您可能会找到更好的输入图像。
- 您可以将 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
:
我想知道为什么这不起作用?我尝试通过将 OpenCV 徽标拆分为 R、G 和 B 来进行简单操作,然后我尝试使用按位和将红色蒙版应用于原始图像,但为什么我没有只得到图像的红色部分?我做错了什么?谢谢。
代码在这里:
您要执行的操作需要 cv2.bitwise_and()
method, not the cv2.bitwise_or()
方法。
尝试:
masked = cv2.bitwise_and(image, image, mask=R)
cv2.imshow('mask', masked)
参考:OpenCV - Apply mask to a color image。
很可能是您的原始样本“不够干净”。
看起来黑色的 R
通道的值接近于零,但 不是 零。
当 cv2.bitwise_and
或 cv2.bitwise_or
与 mask
一起使用时,掩码中所有不等于零的值都被视为“真”(当掩码 != 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
而不是 +1
: image = 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
:
如你所见image
和R
看起来一样,但masked
结果完全不同。
建议的解决方案:
- 您可能会找到更好的输入图像。
- 您可以将 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
: