qq_39483237 2022-03-28 09:30 采纳率: 0%
浏览 427

使用OpenCV将一个PNG图片叠加到另一个PNG图片上

我在网上找到过不少将一个png叠加到一个jpg图片上的教程(如相关代码所示),但是没找到如何将一个PNG图片叠加到另一个(没有任何颜色、完全透明,但是尺寸更大的)PNG图片上。我用将png叠加到jpg上的代码应用在png叠加到png上时,背景的png变成了黑色(如图所示),而我希望的结果是背景依旧是透明

请问如何实现将一个PNG叠加到另一个PNG上?

import cv2
import numpy as np
from PIL import Image

def overlay_image_alpha(img, img_overlay, x, y, alpha_mask):
    """Overlay `img_overlay` onto `img` at (x, y) and blend using `alpha_mask`.

    `alpha_mask` must have same HxW as `img_overlay` and values in range [0, 1].
    """
    # Image ranges
    y1, y2 = max(0, y), min(img.shape[0], y + img_overlay.shape[0])
    x1, x2 = max(0, x), min(img.shape[1], x + img_overlay.shape[1])

    # Overlay ranges
    y1o, y2o = max(0, -y), min(img_overlay.shape[0], img.shape[0] - y)
    x1o, x2o = max(0, -x), min(img_overlay.shape[1], img.shape[1] - x)

    # Exit if nothing to do
    if y1 >= y2 or x1 >= x2 or y1o >= y2o or x1o >= x2o:
        return

    # Blend overlay within the determined ranges
    img_crop = img[y1:y2, x1:x2]
    img_overlay_crop = img_overlay[y1o:y2o, x1o:x2o]
    alpha = alpha_mask[y1o:y2o, x1o:x2o, np.newaxis]
    alpha_inv = 1.0 - alpha

    img_crop[:] = alpha * img_overlay_crop + alpha_inv * img_crop


# Prepare inputs
x, y = 0, 0
img = np.array(Image.open("template.png"))
img_overlay_rgba = np.array(Image.open("../outimages/input.png"))

# Perform blending
alpha_mask = img_overlay_rgba[:, :, 3] / 255.0
img_result = img[:, :, :3].copy()
img_overlay = img_overlay_rgba[:, :, :3]
overlay_image_alpha(img_result, img_overlay, x, y, alpha_mask)

# Save result
Image.fromarray(img_result).save("img_result.png")

输入图片1:

img

输入图片2(纯透明):

img

结果:

img

展开全部

  • 写回答

3条回答 默认 最新

  • 卡尔曼的BD SLAMer 计算机视觉领域新星创作者 2022-03-28 09:44
    关注

    参考;import cv2
    import os
    import random

    def put_the_png_to_webcam(frame, num, img, step, right):
    """
    Arguments:
    frame: the webcam's one frame
    num: the number to record the frequency of the frame
    img: the png image to put.
    step: distance to move each frame
    right: the location for the image to put
    Returns:
    frame: the frames after processed
    """
    h, w= img.shape[:2]
    # method 1 使用位操作:
    # 创建掩膜
    imggray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, mask = cv2.threshold(imggray, 10, 255, cv2.THRESH_BINARY)
    mask_inv = cv2.bitwise_not(mask)

    # 保留除png图像外的背景
    roi = frame[num*step:h+num*step,right:right+w]
    frame_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)
    img_fg = cv2.bitwise_and(img, img, mask=mask)
    
    dst = cv2.add(frame_bg, img_fg)  # 进行融合
    frame[num*step:h+num*step,right:right+w] = dst  # 融合后放在原图上
     
    # method 2 使用带权重的图像融合:
    # alpha = 0.5
    # added_image = cv2.addWeighted(frame[num*step:h+num*step,right:right+w,:], alpha, img[0:h,0:w,:], 1-alpha, 0)
    # frame[num*step:h+num*step,right:right+w,:] = added_image
    
    return frame
    

    if name == "main":
    video = cv2.VideoCapture(0)
    if not video.isOpened():
    print("can't open the camera!")

    png_dir = 'textures'  # png图像存放目录
    num = 0 # 记录帧数,当达到一定帧数后消失
    step = 8  # 每帧移动 8px
    img_path = os.path.join(png_dir, "1.png")  # png图片的存储地址
    img = cv2.imread(img_path)
    right = 480
    while True:
        _, frame = video.read()
        
        if num < 28:  # 28帧后图片消失
            # 调用函数,将png放在视频流中
            frame = put_the_png_to_webcam(frame, num, img, step, right)
        
        cv2.imshow("vedio", frame)
        if cv2.waitKey(1) == 27 :  # 按ESC键退出程序
            break
        num += 1
    
    video.release()
    cv2.destroyAllWindows() 
    

    展开全部

    评论
  • Qt学视觉 2022-04-03 10:24
    关注

    直接使用add

    评论
  • gvhq82 2022-10-02 09:20
    关注

    png背景为黑色,是因为你读入图片的时候,没有读入透明通道。
    错误例子(黑色背景):
    Image<Bgr, byte> src = new Image<Bgr, byte>(@“D://123.png”);
    正确例子(透明背景):
    Image<Bgra, byte> src = new Image<Bgra, byte>(@“D://123.png”);

    评论
编辑
预览

报告相同问题?

问题事件

  • 创建了问题 3月28日

悬赏问题

  • ¥15 WIN10批处理删除指定该文件夹下的所有文件和文件夹bat
  • ¥20 如何延长抓取实时信号的时间
  • ¥15 C# 一个项目中引用了两个外部dll,这两个dll平台不相同什么解决?
  • ¥200 webots中人形机器人调试
  • ¥15 关于#ios#的问题:我如何证明我的iPhone手机在一段时间里面是处于关机状态的
  • ¥15 关于波形反演中torch相关框架程序
  • ¥15 大恒水星相机SDK二次开发遇到的问题
  • ¥15 centos7.9 shell统计数量问题
  • ¥80 求合作科研!计算机方面
  • ¥20 ubutu双系统安装失败
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部