

python + opencv + dlib 实现实时唇色变换 | 虚拟上妆
source link: https://bbs.cvmart.net/articles/5171
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

大家好,今天跟大家分享一个利用python + opencv + dlib 实现一个带滑动条控制的唇色变换案例!
大致内容包括:
1、demo展示
2、思路剖析
3、算法实现
一、demo效果展示
demo已经上传到视频号上了,欢迎关注!
视频号 AI Study
从demo 中可以看到,当我们调整下方的三个RGB 滑动条的时候,可以实现实时的调整嘴唇的颜色。
下面看一下具体的实现思路!
二、思路剖析
具体的思路可以分为下面几个部分:
1、人脸关键点检测
2、嘴唇区域mask提取
3、嘴唇区域上色并与原图融合
1、关键点检测
这里使用的dlib,进行人脸关键点检测(检测到 68 个人脸关键点)
在项目中的 Face_Parts.py 中已实现了对人脸的各个区域的关键点和关键点围成的多边形可视化,后续如果需要对其他部分(非嘴唇区域)进行类似上色,或者变装等,都可以自行拓展使用。
2、嘴唇区域mask提取
通过dlib 检测到的嘴唇区域关键点序列(关键点序号48-61),提取序列并将嘴唇区域关键点连成一个多边形,制作成一个mask,以便后续进行上色处理
3、嘴唇区域上色并与原图融合
这里通过opencv 的滑动条,来进行交互,实现从外部输入 自定义的 rgb 颜色,从而改变唇色,并使用 alpha 融合与原图融合生成最终的效果(PS:这里作者使用高斯模糊处理,让 mask 区域更加的平滑,不会那么尖锐,看起来更加自然)
滑动条的创建和值的获取使用的函数分别是:
cv2.createTrackbar
cv2.getTrackbarPos
三、算法实现
下面是具体的算法实现,这里备注
shape_predictor_68_face_landmarks.dat
可以去 dlib 项目去下载:
https://github.com/davisking/dlib-models
import cv2
import numpy as np
import 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
1281

Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK