如何使用opencv或PIL用原始目标图像颜色为图像蒙版的部分着色?

时间:2019-12-06 11:08:49

标签: python opencv python-imaging-library

我需要帮助创建图像的遮罩,其中由于遮罩,图像的某些部分为黑色,但有些部分仍保留图像的原始颜色。想象一下,一个戴着滑雪面具的恶棍,其中一部分眼睛和嘴巴是恶棍的皮肤,而其余的脸都被滑雪面具覆盖了。 example

基本上我想要的是眉毛,眼睛和嘴唇部分应保留原始图像,但其余的蒙版仍保持白色,如上图所示。 到目前为止,通过使用PIL,我已经成功创建了一个蒙版并用黑色填充了“眼睛”部分的内部

def getmask(img,jawline,eyebrows,eyes,mouth):
    img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    imArray = np.asarray(img)
    # create mask
    polygon = jawline.flatten().tolist()
    maskIm = Image.new('L', (imArray.shape[1], imArray.shape[0]), 0)
    ImageDraw.Draw(maskIm).polygon(polygon, outline=1, fill='white')
    #ImageDraw.Draw(maskIm).polygon(polygon, outline=(1))
    # draw eyes
    righteyes=eyes[0:6].flatten().tolist()
    ImageDraw.Draw(maskIm).polygon(righteyes, outline=1,fill='black')
    lefteyes=eyes[6:].flatten().tolist()
    ImageDraw.Draw(maskIm).polygon(lefteyes, outline=1,fill='black')
    mask = np.array(maskIm)
    # draw eyebrows
    rightbrows=eyebrows[0:6].flatten().tolist()
    ImageDraw.Draw(maskIm).polygon(rightbrows, outline=2, fill='black')
    leftbrows=eyebrows[6:].flatten().tolist()
    ImageDraw.Draw(maskIm).polygon(leftbrows, outline=2, fill='black')
    # draw mouth
    mouth=mouth.flatten().tolist()
    ImageDraw.Draw(maskIm).polygon(mouth, outline=1, fill='black')

    mask = np.array(maskIm)
    return mask

那些下巴,眉毛,眼睛,嘴巴包含脸部相关部分的(x,y)坐标,我只需要保留眉毛,眼睛和嘴巴部分的颜色即可。我希望有人能帮助我解决问题

1 个答案:

答案 0 :(得分:0)

如果您有一个遮罩,要保留的区域在白色区域,则只需在原始图像上对其进行bitwise_or

在您的情况下,我们必须反转遮罩,以使背景为黑色,而ROI为白色。

mask = cv2.bitwise_not(mask)
masked = cv2.bitwise_or(image, image, mask=mask)

以下是输出示例:
masked image
要使他的其余脸变黑,您只需将ROI外的所有值都设置为蒙版中的黑色。一种方法是使用
提供的坐标 np.where(mask != 0)

示例代码:
https://colab.research.google.com/drive/1vCMhgDXmuFMJpxChuLN6TDEqgXi7V8CT