如何使用遮罩更改图像的颜色?

时间:2020-07-14 09:22:19

标签: python python-3.x opencv computer-vision opencv3.0

我正在编写代码来更改人的面部图片中头发的颜色。为此,我制作了一个模型,并能够获得头发各部分的遮罩。但是现在我陷入了一个如何更改其颜色的问题。

下面是输出蒙版和传递的输入图像。

enter image description here enter image description here

您能建议我将头发的颜色更改为不同颜色的方法吗?

1 个答案:

答案 0 :(得分:5)

由于它们都具有相同的形状,因此可以使用遮罩图像遮罩脸部图像。我们首先需要对其执行二进制阈值处理,因此可以将其用作黑白蒙版。然后,我们可以根据值是0还是255进行布尔索引,并分配新的颜色,例如绿色?

import cv2
mask = cv2.imread('eBB2Q.jpg')
face = cv2.imread('luraB.jpg')

_, mask = cv2.threshold(mask, thresh=180, maxval=255, type=cv2.THRESH_BINARY)
# copy where we'll assign the new values
green_hair = np.copy(face)
# boolean indexing and assignment based on mask
green_hair[(mask==255).all(-1)] = [0,255,0]

fig, ax = plt.subplots(1,2,figsize=(12,6))
ax[0].imshow(cv2.cvtColor(face, cv2.COLOR_BGR2RGB))
ax[1].imshow(cv2.cvtColor(green_hair, cv2.COLOR_BGR2RGB))

enter image description here

现在,我们可以使用cv2.addWeighted将新图像与原始图像合并,这将返回两个图像的加权和,因此,我们只会在蒙版区域看到差异:

green_hair_w = cv2.addWeighted(green_hair, 0.3, face, 0.7, 0, green_hair)

fig, ax = plt.subplots(1,2,figsize=(12,6))
ax[0].imshow(cv2.cvtColor(face, cv2.COLOR_BGR2RGB))
ax[1].imshow(cv2.cvtColor(green_hair_w, cv2.COLOR_BGR2RGB))

enter image description here

请注意,您可以通过alphabeta参数设置加权总和中的权重,具体取决于您希望新颜色占主导地位的数量。注意,如前所述,新图像将从加权和dst = src1*alpha + src2*beta + gamma中获得。让我们尝试另一种颜色,并将权重设置为具有0.50.9之类的alpha值的凸组合:

green_hair = np.copy(face)
# boolean indexing and assignment based on mask
green_hair[(mask==255).all(-1)] = [0,0,255]
fig, axes = plt.subplots(2,2,figsize=(8,8))
for ax, alpha in zip(axes.flatten(), np.linspace(.6, .95, 4)):
    green_hair_w = cv2.addWeighted(green_hair, 1-alpha, face, alpha, 0, green_hair_w)
    ax.imshow(cv2.cvtColor(green_hair_w, cv2.COLOR_BGR2RGB))
    ax.axis('off')

enter image description here