在Python中使用OpenCV将图像与另一个包含黑色像素的非矩形图像叠加在一起

时间:2019-05-15 08:36:04

标签: python opencv image-processing overlay

我想以编程方式叠加图像,例如非常熟悉的Windows XP墙纸:

Windows XP wallpaper

与另一个包含黑色像素的非矩形图像,例如标准的大光标图标:

enter image description here

thisthis教程复制粘贴代码,它们都使用OpenCV逐位屏蔽魔术,我到达了:

import cv2 as cv

# Load two images
img1 = cv.imread('bliss.png') # The image I want the overlay to be diplayed on.
img2 = cv.imread('cursor.png') # The image I want to overlay with, containing black pixels.

# 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, 20, 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()

在尝试为cv.threshold(包括thres and maxval argumentsthresholding types)找到正确参数的天真排列过程中,我总是发现原始图像中存在大量黑色像素从覆盖的一个丢失。在下面左侧的放大图片中,您可以看到覆盖的光标,而右侧是原始复制的光标:

enter image description here

我认为这种像素损失是由于灰度转换和/或逆(?)遮罩引起的,但无法确定上面代码中的更改方式或更改方式。在上面链接的教程中,我使用了不包含黑色像素的图像作为叠加层,结果看起来不错。是否可以对包含黑色像素的图像执行相同的操作?

1 个答案:

答案 0 :(得分:2)

这里的问题是,您在cursor.png的{​​{1}}中丢失了黑色像素。其余的仅是白色像素,因此您的遮罩太小了。由于cv.threshold(img2gray, 20, 255, cv.THRESH_BINARY)中存储有透明度信息,因此您可以将其alpha通道用作遮罩。

这是您的代码,进行了相应的修改(我删除了所有注释;注释显示了我的更改):

cursor.png

希望输出的图像看起来像您期望的样子:

Output