【问题标题】:How to replace a masked part of an image with another image using openCV python?如何使用openCV python将图像的蒙版部分替换为另一个图像?
【发布时间】:2019-03-03 23:16:17
【问题描述】:

目标是用另一个图像替换图像的一部分。我打算做的是获取原始照片的segment map,并将原始照片的选定部分替换为另一张图像。

例如,这是一张原始照片的segment map的照片:

我想用另一个人模型(不同的人)替换那个粉红色的片段蒙版:

我应该怎么做呢?我正在考虑根据粉红色 (RGB 值为 192,128,128)bitwise_and 这两个图像来选择 ROI?但我不太确定如何做到这一点,或者这是否是最好的方法。

我知道粉红色面具和样本人并不完全适合,但我只想能够先将模型适合粉红色部分,然后再缩放或变换它。

任何建议都会很棒!谢谢!

【问题讨论】:

  • 所有图片的背景都是纯黑色的吗?
  • @Jello 实际上再三考虑,也许不是.. 但它总是纯色.. 有帮助吗?
  • @Jello 或者,我可以使背景为纯黑色,但蒙版是实际图像(不是彩色分割...)。所以有点像男模特的照片。除了我会用另一个人代替一个人。这有意义吗?
  • 啊,是的,这是有道理的,您应该能够重新缩放替换图像,抓取所有具有非零值的像素并将它们拍打在目标图像的中心(在这种情况下,目标没有一定需要一个面具,可以全黑)
  • @Jello 这确实让我想到了!不过我有一个问题,我如何获得目标图像的中心?

标签: python opencv image-processing image-replacement


【解决方案1】:

加载库并读取图像

from __future__ import division
import cv2
import numpy as np

guy_img = cv2.imread('path')
target_img = cv2.imread('path')

获取该人(每个非零像素)和目标蒙版(粉红色区域)的边界框。

a = np.where(guy_img > 0)
b = np.where(target_img == 129)  # picked one of the channels in your image
bbox_guy = np.min(a[0]), np.max(a[0]), np.min(a[1]), np.max(a[1])
bbox_mask = np.min(b[0]), np.max(b[0]), np.min(b[1]), np.max(b[1])

注意,当我加载目标图像时,值与您提供的值不同。图像边缘还有一些白色像素。这可能只是由于图像被上传到 imgur 并下载。如果你的值是正确的并且你的图像的其余部分是完全黑色的,除了粉红色区域你可以得到所有非零像素,就像我用 np.where(target_img > 0) 为家伙图像所做的那样。

现在只获取家伙和蒙版区域的值

guy = guy_img[bbox_guy[0]:bbox_guy[1], bbox_guy[2]:bbox_guy[3],:]
target = target_img[bbox_mask[0]:bbox_mask[1], bbox_mask[2]:bbox_mask[3],:]

将人的大小调整为与面具相同的比例/形状

guy_h, guy_w, _ = guy.shape
mask_h, mask_w, _ = target.shape
fy = mask_h / guy_h
fx = mask_w / guy_w
scaled_guy = cv2.resize(guy, (0,0), fx=fx,fy=fy)

用男人图像值重新分配目标图像的蒙版区域

for i, row in enumerate(range(bbox_mask[0], bbox_mask[1])):
    for j, col in enumerate(range(bbox_mask[2], bbox_mask[3])):
        target_img[row,col,:] = scaled_guy[i,j,:]

cv2.imshow('', target_img)
cv2.waitKey(0)

【讨论】:

  • 嗨果冻感谢您的帮助!关于获取照片的中心,您提供的方法仅适用于人类始终站在图像中间的情况,对吗?但是对于人可能站在照片中不同位置的情况,我应该如何处理呢?
  • @Jenny,我更新了我的回复,您正在寻找更多内容吗?
  • 我非常感谢更新后的回复,是的,这就是我要找的!最后一个问题(抱歉打扰),但是您是如何确定b = np.where(target_img == 129) 中的值 129 的?
  • 查看我上面贴的note,有意义吗?
  • 知道了:)!非常感谢!
【解决方案2】:

在继续实施之前,您首先需要考虑几件事情。

  • 蒙版图像的背景一致?蒙面斑点的颜色是否一致?
  • 要添加图像的蒙版和对象的大小。

我建议您首先在粉红色分段图像上找到 ROI 的大小、颜色和位置。根据蒙版图像缩放对象(男孩图像)的尺寸,因此更容易将对象图像蒙版到粉红色部分。

然后您可以创建一个尺寸类似于蒙版图像的图像(让我们称之为第一步图像)。将缩放的对象图像添加到从粉红色斑点分析获得的位置。这样,您将拥有两个具有相似尺寸和相似比例的图像。

对于第一步的图像和粉色 ROI 应该很容易在视觉上重叠。

如果您想要精确的粉红色,则如果蒙版图像上的同一位置像素为黑色,则将第一步图像上的所有像素替换为黑色像素。否则就让它成为它的样子。

if(mask[i][j] == black){ step_one[i][j] = black }

这使得粉红色部分被对象图像掩盖。

【讨论】:

  • 感谢您的解释!我能够在脑海中想象它。一个问题,我如何获得粉红色段的投资回报率的位置?有没有我可以使用的功能?
  • 斑点分析函数通常会为您提供斑点的半径中心和其他特征。看看这个例子链接another question for blob analysisfull example
猜你喜欢
  • 2013-12-03
  • 2019-05-24
  • 1970-01-01
  • 2021-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-24
相关资源
最近更新 更多