繁体   English   中英

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

[英]Overlaying an image with another non-rectangular image containing black pixels using OpenCV in Python

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

Windows XP壁纸

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

在此处输入图片说明

复制-从牧养的码其中都使用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和maxval参数以及阈值类型 )的幼稚排列过程中,我总是发现原始图像中存在大量黑色像素,这些像素在重叠图像中丢失了。 在下面左侧的放大图片中,您可以看到覆盖的光标,而右侧是原始复制的光标:

在此处输入图片说明

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

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

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

import cv2 as cv

img1 = cv.imread('bliss.png')
img2 = cv.imread('cursor.png', cv.IMREAD_UNCHANGED)         # Added cv.IMREAD_UNCHANGED parameter to maintain alpha channel information

alpha = img2[:, :, 3]                                       # Save alpha channel for later use
_, alpha = cv.threshold(alpha, 5, 255, cv.THRESH_BINARY)    # Threshold alpha channel to prevent gradual transparency
img2 = cv.cvtColor(img2, cv.COLOR_BGRA2BGR)                 # Remove alpha channel information, so that code below still works

rows, cols, channels = img2.shape
roi = img1[0:rows, 0:cols ]

                                                            # img2gray no longer needed
mask = alpha                                                # Mask is just the alpha channel saved above
mask_inv = cv.bitwise_not(mask)

img1_bg = cv.bitwise_and(roi, roi, mask = mask_inv)

img2_fg = cv.bitwise_and(img2, img2, mask = mask)

dst = cv.add(img1_bg, img2_fg)
img1[0:rows, 0:cols ] = dst
cv.imshow('res',img1)
cv.waitKey(0)
cv.destroyAllWindows()

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

输出量

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM