我在查看OpenCV的文档时发现了一些我不理解的内容。我试图在网络上找到它,但找不到任何令人满意的东西。您能帮我写一行代码吗? 这是代码:
# Load two images
img1 = cv.imread('messi5.jpg')
img2 = cv.imread('opencv-logo-white.png')
# I want to put logo on top-left corner, So I create a ROI
rows,cols,channels = img2.shape
roi = img1[0:rows, 0:cols ]
# Now create a mask of logo and create its inverse mask also
img2gray = cv.cvtColor(img2,cv.COLOR_BGR2GRAY)
ret, mask = cv.threshold(img2gray, 10, 255, cv.THRESH_BINARY)
mask_inv = cv.bitwise_not(mask)
# Now black-out the area of logo in ROI
img1_bg = cv.bitwise_and(roi,roi,mask = mask_inv)
# Take only region of logo from logo image.
img2_fg = cv.bitwise_and(img2,img2,mask = mask)
# Put logo in ROI and modify the main image
dst = cv.add(img1_bg,img2_fg)
img1[0:rows, 0:cols ] = dst
cv.imshow('res',img1)
cv.waitKey(0)
cv.destroyAllWindows()
我实际上不明白的是这两行
img1_bg = cv.bitwise_and(roi,roi,mask = mask_inv)
img2_fg = cv.bitwise_and(img2,img2,mask = mask)
这些行实际做什么以及如何应用遮罩?
如果任何人都可以解释在bitwise_and操作中应用的遮罩,将非常有帮助。谢谢
答案 0 :(得分:1)
如果您查看tutorial。
遮罩是OpenCV徽标的黑白图像,它是通过对OpenCV徽标应用阈值而创建的。
bitwise_and
操作是logical and operation
在这种情况下,它采用两个8位数字表示一个像素,并对这些数字应用and操作。
Documentation描述了此功能的作用。
由于前两个参数相同(roi
或img2
),如果不使用遮罩,结果将是相同的图像。遮罩为黑色的位置与目标图像相同。
在这种情况下,没有提供目标图像,因此OpenCV会为功能中使用的目标图像分配一个黑色图像(零)(这通常是在未为Matrix提供功能时OpenCV的工作方式)。>
具体来说,img1_bg = cv.bitwise_and(roi,roi,mask = mask_inv)
将创建在该函数中使用的黑矩阵,该黑矩阵随后将成为输出img1_bg
。 mask_inv
中的像素仅填充了该黑色图像中与roi
中的白色像素匹配的部分。这意味着在mask_inv中存在白色像素的位置。 roi值将复制到该函数在相应坐标中生成的纯黑色图像中。
类似地,img2_fg = cv.bitwise_and(img2,img2,mask = mask)
将创建在该函数中使用的黑矩阵,该黑矩阵随后成为输出img2_fg
。只有mask
中的像素填充了该黑色图像中与img2
中的白色像素匹配的部分。
因此,当您添加img1_bg
和img2_fg
时,结果只是每个图像中被遮盖的部分。
我个人认为,这是bitwise_and
的令人困惑的用法。我认为,要演示bitwise_and
的功能,可以更清楚地删除mask参数,如下所示:img1_bg = cv.bitwise_and(roi, mask_inv)
。这样会得到相同的结果,遮罩为黑色的位置为零,而遮罩为黑色的像素则返回ROI值。
如果您不愿意演示bitwise_and
的用法,那么在python中,我认为使用逻辑索引将更加清晰,如下所示:
output = np.zeros(img1.shape, np.uint8)
output[mask_inv] = img1_bg[mask_inv]
output[mask] = img2_fg[mask]