使用 Python 和 OpenCV 合并这两张裁剪皮肤和原始自拍的图像?

Posted

技术标签:

【中文标题】使用 Python 和 OpenCV 合并这两张裁剪皮肤和原始自拍的图像?【英文标题】:Use Python and OpenCV to merge these two images of cropped skin and original selfie? 【发布时间】:2018-08-02 13:41:08 【问题描述】:

因此,我们的想法是将这两张图片合并在一起。 和 。

现在我尝试了以下内容:

img1 = cv2.imread("/home/victor/GammaAdjustedImage.jpg")
img2 = cv2.imread("/home/victor/VE/OriginalSelfie.jpg")

dst = cv2.addWeighted(img1, 0.5 , img2, 0.4, 0)

cv2.imshow('dst',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

然而,不幸的是,代码产生了以下错误:

error: OpenCV(3.4.1) /io/opencv/modules/core/src/arithm.cpp:659: error: (-209) 该操作既不是'array op array'(其中数组具有相同的大小和相同数量的通道),也不是 'array op scalar',也不是函数 arithm_op 中的 'scalar op array'

第一张图片如标题所说,我使用dlib、opencv和convexhull裁剪出来的面部皮肤,然后通过gamma校正进行numpy和美白。

第二张是原图。如何组合这两个图像,以使第二个图像始终保持不变,但具有第一个的变白皮肤?谢谢!

注意:第二张图片的眼睛、嘴唇和眉毛必须保持原样(不应像第一张图片那样被涂黑)。我只是想要以某种方式将变白的皮肤粘贴到第二张图像上。其他一切都保持不变

【问题讨论】:

【参考方案1】:

error: OpenCV(3.4.1) /io/opencv/modules/core/src/arithm.cpp:659: error: (-209) 该操作既不是'array op array'(其中数组的大小相同和相同数量的通道),也不是 'array op scalar',也不是函数 arithm_op 中的 'scalar op array'

当您尝试添加具有不同形状(通道、大小)的图像时,通常会出现该错误。

您可以通过执行img.shape 来验证图像的形状,这会返回类似于(100,100,3)(表示100X100、3 通道图像)的内容。你的两张图片的形状肯定不一样。

要解决此问题,您只能添加具有相同形状的图像。如果自拍和调整后的图像形状不一样,您必须获取并在最大图像的感兴趣区域 (ROI) 上与较小图像的形状完全匹配才能进行操作.

要从您的img2 获得 ROI,您可以使用 Python 切片,类似于roi = img2[0:50, 0:50](从图像的原点开始获得 50 x 50 的区域)。

【讨论】:

感谢您的建议。我刚才尝试的是使用 addWeighted 函数,但它给了我一个非常糟糕的结果。结果是图像太亮或太暗,具体取决于提供的参数。 ROI 是处理此类任务的最佳方式还是有替代方案? @VictorSimon 没有看到难以分辨的结果(可以将其添加到您的帖子中)。 Addweighted 和 add 是不同的,当我看到结果时,我可能能够提供更多帮助。 ROI 是您的图像具有不同大小的唯一方法,因此您可以将它们两者相等(或者使较小的 img 更大)【参考方案2】:

AddWeighted 不是正确的解决方案。你想要一个直接的“over”复合函数。我拼凑了一些东西来演示:

import cv2
import numpy as np

#convert to float to make things easier
img2 = cv2.imread("img2.jpg"),-1)
img1 = cv2.imread("img1.jpg"),-1)
img1 = img1.astype('float')
img2 = img2.astype('float')
img1/=255
img2/=255

#mask a mask based on the black or white pixels
#all black and white pixels become black in the mask
#everything else becomes white
mask = np.copy(img1)
b,g,r = cv2.split(mask)
mask = (b+g+r)/3
#using .2 and .9 because there are compression artifacts in the image
mask[mask>=.9] = 0
mask[mask<=.2] = 0
mask[mask!=0] = 1

#making mask 3 channels to make composite easier
mask = cv2.merge([mask,mask,mask])
#over operation = (img1*alpha) + (background*(1-alpha))
output = (img1*mask) + (img2*(1-mask))

输出仍然很糟糕。为什么:

面罩不准确 蒙版应在边缘融合以平滑 过渡。这可以通过腐蚀过滤器和模糊来完成 筛选。您应该使用 11 到 21 的大内核大小,可能更大,具体取决于您的输入图像大小。 您的 Gamma 调整太强了。

【讨论】:

以上是关于使用 Python 和 OpenCV 合并这两张裁剪皮肤和原始自拍的图像?的主要内容,如果未能解决你的问题,请参考以下文章

opencv 怎么把两张图片合并到一起?

Python笔记-使用SSIM找两张图不同及使用Opencv显示

两个excel表,有一列内容相同,怎么把这两张表合并?

LINQ Group By操作

使用 OpenCV Python 检测和可视化两个图像之间的差异

A1118 Birds in Forest (25分)