• 问答
  • 技术
  • 实践
  • 资源
python + opencv + dlib 实现实时唇色变换 | 虚拟上妆精选
来源|AI算法与图像处理


大家好,今天跟大家分享一个利用python + opencv + dlib 实现一个带滑动条控制的唇色变换案例!

大致内容包括:

1、demo展示

2、思路剖析

3、算法实现

一、demo效果展示

demo已经上传到视频号上了,欢迎关注!

image.png

视频号 AI Study

从demo 中可以看到,当我们调整下方的三个RGB 滑动条的时候,可以实现实时的调整嘴唇的颜色。

下面看一下具体的实现思路!

二、思路剖析

具体的思路可以分为下面几个部分:

1、人脸关键点检测

2、嘴唇区域mask提取

3、嘴唇区域上色并与原图融合


1、关键点检测

这里使用的dlib,进行人脸关键点检测(检测到 68 个人脸关键点)

在项目中的 Face_Parts.py  中已实现了对人脸的各个区域的关键点和关键点围成的多边形可视化,后续如果需要对其他部分(非嘴唇区域)进行类似上色,或者变装等,都可以自行拓展使用。
image.png

2、嘴唇区域mask提取

通过dlib 检测到的嘴唇区域关键点序列(关键点序号48-61),提取序列并将嘴唇区域关键点连成一个多边形,制作成一个mask,以便后续进行上色处理

3、嘴唇区域上色并与原图融合

这里通过opencv 的滑动条,来进行交互,实现从外部输入 自定义的 rgb 颜色,从而改变唇色,并使用 alpha 融合与原图融合生成最终的效果(PS:这里作者使用高斯模糊处理,让 mask 区域更加的平滑,不会那么尖锐,看起来更加自然)

滑动条的创建和值的获取使用的函数分别是:

cv2.createTrackbarcv2.getTrackbarPos

三、算法实现

下面是具体的算法实现,这里备注

shape_predictor_68_face_landmarks.dat

可以去 dlib 项目去下载:

https://github.com/davisking/dlib-models

import cv2import numpy as npimport dlib

detector = dlib.get_frontal_face_detector()predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")

def empty(a): pass
cv2.namedWindow('BGR')cv2.resizeWindow('BGR',640,240)cv2.createTrackbar('Blue','BGR',0,255,empty)cv2.createTrackbar('Green','BGR',0,255,empty)cv2.createTrackbar('Red','BGR',0,255,empty)
def createBox(img,points,scale=5,masked=False,cropped = True): if masked: mask = np.zeros_like(img) mask = cv2.fillPoly(mask,[points],(255,255,255)) img = cv2.bitwise_and(img,mask) # cv2.imshow('Mask',img)
if cropped: bbox = cv2.boundingRect(points) x,y,w,h = bbox imgCrop = img[y:y+h,x:x+w] imgCrop = cv2.resize(imgCrop,(0,0),None,scale,scale) return imgCrop else: return mask
while True: # image    # 1 读入图片并进行人脸关键点检测 img = cv2.imread('1.jpg')
img = cv2.resize(img,(0,0),None,0.5,0.5) imgOriginal = img.copy() imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = detector(imgGray)
for face in faces: x1,y1 = face.left(),face.top() x2,y2 = face.right(),face.bottom() # imgOriginal = cv2.rectangle(img, (x1,y1),(x2,y2),(0,255,0),2) landmarks = predictor(imgGray,face) myPoints =[] for n in range(68): x = landmarks.part(n).x y = landmarks.part(n).y myPoints.append([x,y]) # cv2.circle(imgOriginal,(x,y),5,(50,50,255),cv2.FILLED) # cv2.putText(imgOriginal,str(n),(x,y-10),cv2.FONT_HERSHEY_COMPLEX_SMALL,0.9,(0,0,255),1)
myPoints = np.array(myPoints)
# imgLeftEye = createBox(img,myPoints[36:42],8) # cv2.imshow('LeftEye',imgLeftEye) # 2 嘴唇区域mask提取 imgLips = createBox(img,myPoints[48:61],8,masked=True,cropped=False)
imgColorLips = np.zeros_like(imgLips)        # 3 创建滑动条,以及获取滑动条的值,嘴唇区域上色并与原图融合 b = cv2.getTrackbarPos('Blue','BGR') g = cv2.getTrackbarPos('Green','BGR') r = cv2.getTrackbarPos('Red','BGR') imgColorLips[:] = b,g,r imgColorLips = cv2.bitwise_and(imgLips,imgColorLips) imgColorLips = cv2.GaussianBlur(imgColorLips,(7,7),10)
#color_image imgColorLips = cv2.addWeighted(imgOriginal,1,imgColorLips,0.4,0)
#gray_image # imgOriginalGray = cv2.cvtColor(imgOriginal,cv2.COLOR_BGR2GRAY) # imgOriginalGray = cv2.cvtColor(imgOriginalGray,cv2.COLOR_GRAY2BGR) # imgColorLips = cv2.addWeighted(imgOriginalGray,1,imgColorLips,0.4,0)        cv2.imshow('BGR',imgColorLips) # cv2.imshow('Lips',imgLips)
print(myPoints)
cv2.imshow("Original",imgOriginal) cv2.waitKey(1)


相关推荐:

深度学习 AI 美颜系列----AI 美发算法 (美妆相机 / 天天 P 图染发特效)
百变冰冰!手把手教你实现 CVPR2021 最新妆容迁移算法

  • 0
  • 0
  • 1596
收藏
暂无评论