[英]How to merge one RGBA and one RGB images in opencv
I have two images.我有两张图片。 In one image, the white pixels are set to be transparent (or colorless) by editing the channel
A
in RGBA
image format.在一幅图像中,通过以
RGBA
图像格式编辑通道A
,将白色像素设置为透明(或无色)。 Suppose this image name is image_rgba.png
and the other image is image.jpg
.假设这个图像名称是
image_rgba.png
而另一个图像是image.jpg
。 Now, I want to put the image_rgba.png
image in a specific location of the image.jpg
using the following python code现在,我想使用以下 python 代码将
image_rgba.png
图像放在image.jpg
的特定位置
import cv2
import numpy as np
import matplotlib.pyplot as plt
image = cv2.imread('image.jpg')
label = cv2.imread('image_rgba.png')
label = cv2.cvtColor(label, cv2.COLOR_BGR2RGBA)
new_image = image.copy()
new_image = cv2.cvtColor(new_image, cv2.COLOR_BGR2RGBA)
new_image[200:290, 300:384, :] = label
When I write this image, the edges of the image_rgba.png
which is colorless, are set to be white in the output image (the white edges of the green box in the following image).当我写这个图像时,无色的
image_rgba.png
的边缘在 output 图像中设置为白色(下图中绿色框的白色边缘)。
I want the white edges of the green box label does not to show and instead the background image shown in that pixels.我希望绿色框 label 的白色边缘不显示,而是显示在该像素中的背景图像。 I found the similar question but it does not help me to solve my problem.
我发现了类似的问题,但它并不能帮助我解决我的问题。 I would be appreciated it if anybody can help me.
如果有人可以帮助我,我将不胜感激。
Here's how you can do it.这是你如何做到的。 I'm not an OpenCV expert, so there might be simpler approaches.
我不是 OpenCV 专家,所以可能有更简单的方法。 Comments in the code explain what it does.
代码中的注释解释了它的作用。 The overall idea is:
总体思路是:
import cv2
def alphaMerge(small_foreground, background, top, left):
"""
Puts a small BGRA picture in front of a larger BGR background.
:param small_foreground: The overlay image. Must have 4 channels.
:param background: The background. Must have 3 channels.
:param top: Y position where to put the overlay.
:param left: X position where to put the overlay.
:return: a copy of the background with the overlay added.
"""
result = background.copy()
# From everything I read so far, it seems we need the alpha channel separately
# so let's split the overlay image into its individual channels
fg_b, fg_g, fg_r, fg_a = cv2.split(small_foreground)
# Make the range 0...1 instead of 0...255
fg_a = fg_a / 255.0
# Multiply the RGB channels with the alpha channel
label_rgb = cv2.merge([fg_b * fg_a, fg_g * fg_a, fg_r * fg_a])
# Work on a part of the background only
height, width = small_foreground.shape[0], small_foreground.shape[1]
part_of_bg = result[top:top + height, left:left + width, :]
# Same procedure as before: split the individual channels
bg_b, bg_g, bg_r = cv2.split(part_of_bg)
# Merge them back with opposite of the alpha channel
part_of_bg = cv2.merge([bg_b * (1 - fg_a), bg_g * (1 - fg_a), bg_r * (1 - fg_a)])
# Add the label and the part of the background
cv2.add(label_rgb, part_of_bg, part_of_bg)
# Replace a part of the background
result[top:top + height, left:left + width, :] = part_of_bg
return result
background = cv2.imread('image.jpg')
# Read the image "unchanged" to get the alpha channel as well
label = cv2.imread('image_rgba.png', cv2.IMREAD_UNCHANGED)
result = alphaMerge(label, background, 100, 200)
cv2.imshow("result", result)
cv2.waitKey()
I tested with the following background:我在以下背景下进行了测试:
And this foreground:而这个前景:
Result as shown by the Python code:结果如 Python 代码所示:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.