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

Pra*_*dal 5 python opencv computer-vision python-3.x opencv3.0

我正在编写一个代码来改变一个人面部图片中头发的颜色。这样做我做了一个模型,并且能够得到头发部分的面具。但是现在我遇到了如何改变它的颜色的问题。

下面是传递的输出掩码和输入图像。

在此处输入图片说明 在此处输入图片说明

你能告诉我可以用来把头发的颜色变成不同颜色的方法吗?

yat*_*atu 14

由于它们具有相同的形状,因此您可以使用遮罩图像遮罩脸部图像。我们首先需要对其进行二进制阈值处理,因此可以将其用作黑白掩码。然后我们可以根据一个值是否为0or来执行布尔索引255,并分配一个新的颜色,比如 green?

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))
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

现在我们可以使用 将新图像与原始图像结合起来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))
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

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

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')
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

  • 嗯...时尚! (2认同)
  • 是的,考虑了一下,更新了。尽管考虑到当前的面具@Tyson,局限性很明显 (2认同)
  • 哇,看起来不错!比我预期的要好得多。另一个想法可能是将她的头发转换为 HSV 颜色空间,稍微改变一下色调,然后在将其遮盖之前将其转换回 BGR。这可能会改善她头发的深色区域,使其不会变得太亮绿色。 (2认同)
  • 这听起来像一个好主意。当我有更多时间时会尝试一下:)再次感谢@Tyson (2认同)