You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在OpenCV中将图像叠加到另一张图像的指定区域

问题描述

我想在目标图像最右侧叠加一块黑色补丁,已经调整好两张图像的尺寸,尝试提取叠加层的非白色部分粘贴到指定坐标,但没得到预期结果。知道cv2.addWeighted但不知道怎么指定粘贴坐标,求指导如何用OpenCV实现。

我的代码

vr_overlay = "/Users/templates/vertical_overlay.png"
show_image = "/Users/templates/image_3.png"

vr_overlay_co = (0, 0, 100, 412)
img_size = (0, 0, 440, 412)

img = cv2.imread(show_image)
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

v_overlay = cv2.imread(vr_overlay)

resize_v_overlay = cv2.resize(v_overlay, (vr_overlay_co[2], vr_overlay_co[3]))

plt.imshow(resize_v_overlay, cmap='gray')
plt.axis('off')
plt.show()

resize_img = cv2.resize(img_rgb, (img_size[2], img_size[3]))

plt.imshow(resize_img, cmap='gray')
plt.axis('off')
plt.show()

resize_img[vr_overlay_co[1]: vr_overlay_co[1] + 
           vr_overlay_co[3],vr_overlay_co[0]: vr_overlay_co[0] + 
           vr_overlay_co[2]] = np.where(resize_v_overlay != [0, 0, 0],
                                        resize_img[vr_overlay_co[1]: vr_overlay_co[1] 
                                                   + vr_overlay_co[3], vr_overlay_co[0]: 
                                                   vr_overlay_co[0] + vr_overlay_co[2],], resize_v_overlay)

plt.imshow(resize_img, cmap='gray')
plt.axis('off')
plt.show()

相关图像

原图像:
原图像

叠加层图像:
叠加层图像

预期结果:
预期结果


解决方案

你的代码有两个核心问题:

  1. 坐标位置错误:你设置的vr_overlay_co是(0,0,100,412),这会把补丁贴在图像左上角,但你要贴在最右侧,应该把x坐标设为img_size[2] - vr_overlay_co[2](也就是440-100=340)。
  2. np.where的逻辑颠倒:你当前的逻辑是“如果叠加层不是黑色,就保留原图像像素,否则用叠加层”,这和你想要的“保留叠加层的非白色部分,覆盖原图像”完全相反。

修正后的代码如下:

import cv2
import numpy as np
import matplotlib.pyplot as plt

vr_overlay = "/Users/templates/vertical_overlay.png"
show_image = "/Users/templates/image_3.png"

# 补丁尺寸:宽100,高412;贴在最右侧,x坐标=图像宽度-补丁宽度
patch_w, patch_h = 100, 412
img_w, img_h = 440, 412
patch_x = img_w - patch_w
patch_y = 0  # 垂直方向顶部对齐

# 读取并转换图像
img = cv2.imread(show_image)
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
v_overlay = cv2.imread(vr_overlay)

# 调整尺寸
resize_v_overlay = cv2.resize(v_overlay, (patch_w, patch_h))
resize_img = cv2.resize(img_rgb, (img_w, img_h))

# 提取叠加层的非白色区域(白色为[255,255,255])
mask = np.all(resize_v_overlay != [255, 255, 255], axis=2)

# 获取原图像中要替换的区域
roi = resize_img[patch_y:patch_y+patch_h, patch_x:patch_x+patch_w]

# 将叠加层的非白色区域覆盖到原图像的ROI上
roi[mask] = resize_v_overlay[mask]

# 显示结果
plt.imshow(resize_img)
plt.axis('off')
plt.show()

关键说明

  • 坐标计算:通过img_w - patch_w直接得到最右侧的x起始坐标,确保补丁贴在图像最右边。
  • 掩码生成:用np.all(..., axis=2)检查每个像素的三个通道是否都不是白色,生成布尔掩码,精准定位需要替换的区域。
  • ROI替换:直接操作原图像的感兴趣区域(ROI),用掩码筛选出叠加层的有效像素覆盖到原图像上,逻辑清晰且效率高。

如果你的叠加层中“非白色”实际是黑色([0,0,0]),也可以把掩码条件改成np.all(resize_v_overlay == [0,0,0], axis=2),效果一致。

内容的提问来源于stack exchange,提问作者Explorer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 12:22:41