简体   繁体   English

如何使用OpenCV将图像的一部分复制到另一个?

[英]how to copy a part of image to another with OpenCV?

I have a model that predicts the human face segmentation. 我有一个预测人脸分割的模型。

图片描述

But unfortunately the model is not trained to predict the hair with the face. 但是不幸的是,该模型没有经过训练来预测面部的头发。 So now I have the above images as numpy arrays. 所以现在我将以上图像作为numpy数组。 Is it possible to add the hair from the original photo (The one on the left) to the prediction mask (in the middle) or directly to the result prediction (the one on the right) ? 是否可以将原始照片中的头发(左侧的头发)添加到预测蒙版(中间)或直接添加到结果预测中(右侧的头发)?

Basically I just need to deal with the original image to get a little bit from the head above the prediction mask and add it to the prediction so that way at least I'll have a part of the hair in the result. 基本上,我只需要处理原始图像,以从预测蒙版上方的头部得到一点点,然后将其添加到预测中,这样至少可以在结果中保留一部分头发。

The code used to create the previous figure: 用于创建上图的代码:

fn = "images/beard.jpg"
im = cv2.cvtColor(cv2.imread(fn), cv2.COLOR_BGR2RGB)
im = auto_downscaling(im)

# vgg_preprocess: output BGR channel w/ mean substracted.
inp_im = vgg_preprocess(im)

# Predicting the face segmentation
out = model.predict([inp_im])

out_resized = cv2.resize(np.squeeze(out), (im.shape[1],im.shape[0]))
out_resized_clipped = np.clip(out_resized.argmax(axis=2), 0, 1).astype(np.float64)
mask = cv2.GaussianBlur(out_resized_clipped, (7,7), 6)


plt.figure(figsize=(12,6))
plt.subplot("131")
plt.axis('off')
plt.imshow(im)
plt.subplot("132")
plt.axis('off')
plt.imshow(out_resized_clipped, cmap='gray')
plt.subplot("133")
plt.axis('off')
plt.imshow((mask[:,:,np.newaxis]*im.astype(np.float64)).astype(np.uint8))
plt.show()

To demonstrate what you want i tested this. 为了演示您想要什么,我对此进行了测试。 First I create some function to create similar sized images from the inputs. 首先,我创建一些函数来根据输入创建相似大小的图像。

import cv2
import numpy as np

def resize(img, dim=(300, 300)):
    # perform the actual resizing of the image and show it
    frame = cv2.resize(img, dim, interpolation=cv2.INTER_AREA)
    return frame

Then read and resize the images separately 然后分别阅读和调整图像大小

img1 = resize(cv2.imread('img1.png'))
img2 = resize(cv2.imread('img2.png'))
dst = cv2.addWeighted(img1,0.7,img2,0.3,0)

The cv2.addWeighted function will helps me achieve the result. cv2.addWeighted函数将帮助我获得结果。 then you can do as you need with the output 然后您可以根据需要执行输出

cv2.imwrite('out.png', dst)

So Applying this same principle to your code would be something like. 因此,将相同的原理应用于您的代码将是类似的事情。 I see that you have similar sized images there. 我看到那里有类似尺寸的图像。

fn = "images/beard.jpg"
im = cv2.cvtColor(cv2.imread(fn), cv2.COLOR_BGR2RGB)
im = auto_downscaling(im)

# vgg_preprocess: output BGR channel w/ mean substracted.
inp_im = vgg_preprocess(im)

# Predicting the face segmentation
out = model.predict([inp_im])

out_resized = cv2.resize(np.squeeze(out), (im.shape[1],im.shape[0]))
out_resized_clipped = np.clip(out_resized.argmax(axis=2), 0, 1).astype(np.float64)
out_resized_clipped = cv2.GaussianBlur(out_resized_clipped, (7,7), 6)

mask = cv2.addWeighted(out_resized, 0.7, out_resized_clipped,0.3,0)
mask = cv2.GaussianBlur(out_resized_clipped, (7,7), 6)

plt.figure(figsize=(12,6))
plt.subplot("131")
plt.axis('off')
plt.imshow(im)
plt.subplot("132")
plt.axis('off')
plt.imshow(out_resized_clipped, cmap='gray')
plt.subplot("133")
plt.axis('off')
plt.imshow((mask[:,:,np.newaxis]*im.astype(np.float64)).astype(np.uint8))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM