如何使用openCV python将图像的蒙版部分替换为另一个图像?

时间:2019-03-01 16:37:01

标签: python opencv image-processing image-replacement

目标是用另一个图像替换图像的一部分。我计划要做的是获取原始照片的分段图,并用另一张图像替换原始选择的部分。

例如,这是原始照片分段图的照片:

Segment map of original photo

我想用另一个男模特(不同的人)代替那个粉红色的口罩:

Sample guy to replace

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

我知道粉红色口罩和样本人员并不完全吻合,但我只想能够首先将模型适合粉红色段,然后再缩放或变换。

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

2 个答案:

答案 0 :(得分: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)

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

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)

答案 1 :(得分:0)

首先,您需要考虑一些事项,然后再继续实施。

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

我建议您首先在粉红色分割的图像上找到ROI的大小,颜色和位置。根据蒙版图像缩放对象(男孩图像)的尺寸,这样可以更轻松地将对象图像蒙版为粉红色部分。

然后,您可以创建尺寸类似于遮罩图像的图像(称为第一步图像)。将缩放后的对象图像添加到从粉红色斑点分析获得的位置。这样,您将获得两张尺寸和比例相似的图像。

第一步,图像和粉红ROI应该很容易在视觉上重叠。

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

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

这将粉红色的部分遮盖在对象图像之外。