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

OpenCV图像叠加时如何将目标轮廓外区域设置为透明消除黑边

解决方案

你需要为提取的目标生成对应轮廓掩码,叠加时仅将掩码覆盖的目标区域替换到背景上,即可完全消除轮廓外的黑边问题,具体修改后的代码如下:

import cv2
import numpy as np
from matplotlib import pyplot as plt
from skimage import io

# 导入卡片和背景图
card = io.imread('https://i.ebayimg.com/thumbs/images/g/BZoAAOSwj0RfkZuD/s-l225.jpg') 
background = io.imread('https://www.robots.ox.ac.uk/~vgg/data/dtd/images/cracked/cracked_0049.jpg') 

# 检测卡片轮廓
edged=cv2.Canny(card,30,200)
contours, hierarchy=cv2.findContours(edged,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
contour = [c for c in contours if c.size >=1300][0]

# 裁剪卡片区域
x,y,w,h = cv2.boundingRect(contour)
card_cropped = card[y:y+h, x:x+w]

# 生成裁剪区域对应的轮廓掩码
mask = np.zeros(card_cropped.shape[:2], dtype=np.uint8)
# 将原轮廓坐标转换为裁剪区域的相对坐标
relative_contour = contour - [x, y]
cv2.fillPoly(mask, [relative_contour], 255)

# 同时缩放卡片和掩码
card_cropped_resized = cv2.resize(card_cropped, (int(card_cropped.shape[1]/0.8), int(card_cropped.shape[0]/0.8)))
mask_resized = cv2.resize(mask, (int(card_cropped.shape[1]/0.8), int(card_cropped.shape[0]/0.8)))

# 灰度转换
card_cropped_resized_grayscale = cv2.cvtColor(card_cropped_resized, cv2.COLOR_RGB2GRAY)
background_grayscale = cv2.cvtColor(background, cv2.COLOR_RGB2GRAY)

h, w = card_cropped_resized_grayscale.shape[:2]
hh, ww = background_grayscale.shape[:2]

yoff = round(hh/4)
xoff = round(ww/4)

xMin = xoff
yMin = yoff
xMax = xoff+w
yMax = yoff+h

scene = background_grayscale.copy()
# 仅替换掩码覆盖的目标区域,保留背景其他区域不变
scene[yMin:yMax, xMin:xMax][mask_resized > 0] = card_cropped_resized_grayscale[mask_resized > 0]

plt.imshow(cv2.cvtColor(scene,cv2.COLOR_GRAY2RGB))
plt.show()

扩展适配说明

如果后续需要对目标做旋转、滤波等变换,只要对掩码做完全相同的变换操作,保证掩码和目标物体始终对齐,该方案就可以正常生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 18:24:04