python + opencv + dlib 實現(xiàn)實時唇色變換 | 虛擬上妝
點擊下方“AI算法與圖像處理”,一起進步!
重磅干貨,第一時間送達

代碼:https://github.com/ai-coodinator/lipstick
大家好,今天跟大家分享一個利用python + opencv + dlib 實現(xiàn)一個帶滑動條控制的唇色變換案例!
大致內(nèi)容包括:
1、demo展示
2、思路剖析
3、算法實現(xiàn)
如果內(nèi)容對你有所幫助的話,這次幫我點個在看分享一下吧

一、demo效果展示
demo已經(jīng)上傳到視頻號上了,可以直接點擊觀看,歡迎關(guān)注!
從demo 中可以看到,當(dāng)我們調(diào)整下方的三個RGB 滑動條的時候,可以實現(xiàn)實時的調(diào)整嘴唇的顏色。
下面看一下具體的實現(xiàn)思路!
二、思路剖析
具體的思路可以分為下面幾個部分:
1、人臉關(guān)鍵點檢測
2、嘴唇區(qū)域mask提取
3、嘴唇區(qū)域上色并與原圖融合
1、關(guān)鍵點檢測
這里使用的dlib,進行人臉關(guān)鍵點檢測(檢測到 68 個人臉關(guān)鍵點)
在項目中的 Face_Parts.py 中已實現(xiàn)了對人臉的各個區(qū)域的關(guān)鍵點和關(guān)鍵點圍成的多邊形可視化,后續(xù)如果需要對其他部分(非嘴唇區(qū)域)進行類似上色,或者變裝等,都可以自行拓展使用。

2、嘴唇區(qū)域mask提取
通過dlib 檢測到的嘴唇區(qū)域關(guān)鍵點序列(關(guān)鍵點序號48-61),提取序列并將嘴唇區(qū)域關(guān)鍵點連成一個多邊形,制作成一個mask,以便后續(xù)進行上色處理
3、嘴唇區(qū)域上色并與原圖融合
這里通過opencv 的滑動條,來進行交互,實現(xiàn)從外部輸入 自定義的 rgb 顏色,從而改變唇色,并使用 alpha 融合與原圖融合生成最終的效果(PS:這里作者使用高斯模糊處理,讓 mask 區(qū)域更加的平滑,不會那么尖銳,看起來更加自然)
滑動條的創(chuàng)建和值的獲取使用的函數(shù)分別是:
cv2.createTrackbarcv2.getTrackbarPos
三、算法實現(xiàn)
下面是具體的算法實現(xiàn),這里備注
shape_predictor_68_face_landmarks.dat
可以去 dlib 項目去下載:
https://github.com/davisking/dlib-models
import cv2import numpy as npimport dlibdetector = dlib.get_frontal_face_detector()predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")def empty(a):passcv2.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 = bboximgCrop = img[y:y+h,x:x+w]imgCrop = cv2.resize(imgCrop,(0,0),None,scale,scale)return imgCropelse:return maskwhile True:# image# 1 讀入圖片并進行人臉關(guān)鍵點檢測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).xy = landmarks.part(n).ymyPoints.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 嘴唇區(qū)域mask提取imgLips = createBox(img,myPoints[48:61],8,masked=True,cropped=False)imgColorLips = np.zeros_like(imgLips)# 3 創(chuàng)建滑動條,以及獲取滑動條的值,嘴唇區(qū)域上色并與原圖融合b = cv2.getTrackbarPos('Blue','BGR')g = cv2.getTrackbarPos('Green','BGR')r = cv2.getTrackbarPos('Red','BGR')imgColorLips[:] = b,g,rimgColorLips = cv2.bitwise_and(imgLips,imgColorLips)imgColorLips = cv2.GaussianBlur(imgColorLips,(7,7),10)#color_imageimgColorLips = 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)
好的,這樣子就實現(xiàn)我們唇色變換的功能,今天的分享就到這里了。喜歡的小伙伴記得三連支持!感謝
怕小伙伴沒注意,這里再分享一下代碼:
代碼:https://github.com/ai-coodinator/lipstick

努力分享優(yōu)質(zhì)的計算機視覺相關(guān)內(nèi)容,歡迎關(guān)注:
個人微信(如果沒有備注不拉群!) 請注明:地區(qū)+學(xué)校/企業(yè)+研究方向+昵稱
下載1:何愷明頂會分享
在「AI算法與圖像處理」公眾號后臺回復(fù):何愷明,即可下載。總共有6份PDF,涉及 ResNet、Mask RCNN等經(jīng)典工作的總結(jié)分析
下載2:終身受益的編程指南:Google編程風(fēng)格指南
在「AI算法與圖像處理」公眾號后臺回復(fù):c++,即可下載。歷經(jīng)十年考驗,最權(quán)威的編程規(guī)范!
下載3 CVPR2021
在「AI算法與圖像處理」公眾號后臺回復(fù):CVPR,即可下載1467篇CVPR 2020論文 和 CVPR 2021 最新論文
點亮
,告訴大家你也在看
