使用OpenCV+Dlib操作人脸

使用OpenCV+Dlib操作人脸_第1张图片

这是一个关于如何使用OpenCV和DLIB在图像上应用虚拟唇膏的快速教程。同样的原理也可以推广到其他面部特征,比如某人的眼睛、鼻子、下巴……。

为了获得上图所示的结果,我们需要执行以下一系列步骤:

  1. 检测面部标志

  2. 使用由嘴标志组成的凸多边形创建掩码

  3. 使用形态学操作增强掩码,并使其模糊,以获得更好的混合效果

  4. 隔离嘴唇和脸部

  5. 将颜色变换应用于嘴唇

  6. 把嘴唇和脸放在一起

首先要做的是检测人脸的面部标志。库Dlib提供了一种方便的方法来实现这一点;但是,请记住,被摄对象的面部需要面对摄影机。如果头部姿势不正确,检测结果将不好。

使用OpenCV+Dlib操作人脸_第2张图片

在这个例子中,我们只对嘴唇的点感兴趣。下图显示了Dlib返回的面部标志点的索引。如你所见,我们对48点到60点(嘴唇的外部“轮廓”)感兴趣。

使用OpenCV+Dlib操作人脸_第3张图片

利用这些点,我们可以制作一个掩码,让我们在不影响面部整体外观的情况下处理嘴唇的颜色。

但是,等一下。在开始操作这些颜色之前,我们需要改进掩码。在这个例子中,一个带有4x4矩形内核的形态学闭合操作就足够了。

注意下面的图片,这个步骤填补了由cv2生成的原始多边形右上角的一个空白。

右:使用唇部创建的凸多边形/左:关闭操作后的多边形

使用OpenCV+Dlib操作人脸_第4张图片

为了获得自然的效果,我们还需要模糊掩码。模糊掩码将产生更好的混合效果。我们将cv2.GaussianBlur应用于掩码。最后,我们反转掩码(我们需要两个,一个用于嘴唇,一个用于面部)。

右:模糊掩码/左:模糊反向掩码

使用OpenCV+Dlib操作人脸_第5张图片

我们将应用这些掩码,方法是将它们从0–255(uint8)转换为0–1(float)范围,然后将它们与图像相乘。右下方的图像是原始图像乘以反转掩码。左侧的图像是原始图像上的颜色变换乘以掩码的结果。颜色变换由cv2.applyColorMap(im, cv2.COLORMAP_INFERNO)给出。

右:原始图像和反向模糊掩码的位与运算/左:颜色变换图像和模糊掩码的位与运算

使用OpenCV+Dlib操作人脸_第6张图片

现在,剩下要做的就是将这两个图像相加。

右:原始图像/左:结果图像

使用OpenCV+Dlib操作人脸_第7张图片

这是代码。

import cv2
import dlib
import faceBlendCommon as face
import numpy as np

# 加载图像
im = cv2.imread("cv2/girl-no-makeup.jpg")

# 检测人脸关键点
PREDICTOR_PATH = r"C:\Users\felipe.cunha\Documents\venv\cv2\week1-pyton\data\models\shape_predictor_68_face_landmarks.dat"
faceDetector = dlib.get_frontal_face_detector()
landmarkDetector = dlib.shape_predictor(PREDICTOR_PATH)
landmarks = face.getLandmarks(faceDetector, landmarkDetector, im)

# 为嘴唇制作一个掩码
lipsPoints = landmarks[48:60]
mask = np.zeros((im.shape[0], im.shape[1], 3), dtype=np.float32)
cv2.fillConvexPoly(mask, np.int32(lipsPoints), (1.0, 1.0, 1.0))
mask = 255*np.uint8(mask)

# 应用闭合操作改善掩码
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (40,40))
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, 1)

# 模糊掩码以获得自然效果
mask = cv2.GaussianBlur(mask,(15,15),cv2.BORDER_DEFAULT)

# 计算逆掩码
inverseMask = cv2.bitwise_not(mask)

# 将掩码转换为浮点以执行混合
mask = mask.astype(float)/255
inverseMask = inverseMask.astype(float)/255

# 为嘴唇应用颜色贴图
lips = cv2.applyColorMap(im, cv2.COLORMAP_INFERNO)

# 将嘴唇和人脸转换为0-1范围
lips = lips.astype(float)/255
ladyFace = im.astype(float)/255

# 用掩码调整嘴唇和脸
justLips = cv2.multiply(mask, lips)
justFace = cv2.multiply(inverseMask, ladyFace)

# 加上脸和嘴唇
result = justFace + justLips

# 显示结果
cv2.imshow("", result)
cv2.waitKey(0)

☆ END ☆

如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 woshicver」,每日朋友圈更新一篇高质量博文。

扫描二维码添加小编↓

使用OpenCV+Dlib操作人脸_第8张图片

你可能感兴趣的:(人脸识别,java,opencv,python,opengl)