如何将图像的掩膜部分叠加到一个新图像上?

3

非常抱歉这个问题很基础,但是我对OpenCV和图像处理一般都不熟悉,花费了一些时间也无法解决。

这是我想要做的事情:

我有一个透明的PNG图像:

原始图像

我从中创建了一个二值掩模,其中透明区域为黑色,物体为白色:

二值掩模

现在,我有另一个具有相同尺寸的图像:

图案化的图像

现在,我希望将第一个图像中的白色掩蔽部分(实际对象)叠加到该图像上。我该如何做?


1
C++语法中有一个mat.copyTo(mat, mask)函数。不确定Python语法是否有此函数。确保两个图像具有相同的大小,或使用子图像。 - Micka
1
也许这篇博客文章 https://sourcecodezoneseven.blogspot.com/2019/05/opencv-create-transparent-background.html 可以帮到你,它也在做类似的事情。 - CodeDezk
2个回答

4

以下是一种实现方式:

import cv2

# Load images
bg     = cv2.imread('bg.png')                                                                 
obj = cv2.imread('object.png')                                                         
mask   = cv2.imread('mask.png')                                                             

# Zero background where we want to overlay
bg[mask>0]=0                                                                              

# Add object to zeroed out space
bg += obj*(mask>0)                                                                     

cv2.imwrite('result.png',bg)  

enter image description here


3

利用手头上已有的numpy数组,我们可以先将掩码扩展到三个维度:

# Case 1: original mask is OpenCV mask (foreground values 255)
mask = np.dstack([(mask > 0)]*3)
# Case 2: original mask is already boolean
mask = np.dstack([mask]*3)

随后使用蒙版将图像复制过去:

np.copyto(background, foreground, where=mask)

是的,我只是想分享一般的想法。在C++ OpenCV Mat对象中它是这样工作的,但是在Python中使用ndarrays需要做更多的工作。你可以在第三个维度上扩展掩码。我有这方面的Python代码,稍后可以发布。 - ypnos
哦,我明白了!非常感谢!我会尝试扩展掩码的维度。 - Train Heartnet
1
为了扩展掩码,我做了这个:_, extended_mask = np.broadcast_arrays(source1, mask[..., None])。它起作用了。我也会尝试你的代码,看看能否让它更快。谢谢你的帮助! :) - Train Heartnet
谢谢 @ypnos!也可以使用 np.copyto 来叠加带有透明度的掩码吗?例如,如果我们想要在 RGBA 图像的意义上将船上物体叠加在背景上,并带有一定程度的透明度。 - Luca Clissa
不,这种方法不能用于alpha合成。但是有一个很好的OpenCV教程可供使用:https://docs.opencv.org/3.4/d5/dc4/tutorial_adding_images.html - ypnos
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接