[ Dlib ] 利用 Dlib進行臉部捕捉
為了更高品質的臉部數據,特別研究了一下 Face Alignment,相較 Haar等方式,似乎 Dlib更能有效地捕捉臉部,再利用 Face Alignment能有效地將捕捉的臉部校正,以取得更高的數據品質。
Dlib安裝稍微有點複雜,可以參考由 Adrian Rosebrock寫的 "How to install dlib"。
利用 detector = dlib.get_frontal_face_detector()預測灰化後的圖像,評估有幾張臉在這張圖像中。
利用 predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")在捕捉的臉部預測臉部 landmarks。
用 Haar的方式,在條件非常寬鬆的條件下,只有辨識到一張臉,甚至左下角也誤將商標誤認為臉部。
相較之下,Dlib較能正確得辨識出圖中的兩張臉,另位臉部 landmarks也能有效的識別。
能有效的辨識 landmarks就能使用 FaceAligner功能將臉部對齊。
FaceAligner是利用 landmarks雙眼的部分將圖像調整為雙眼在水平的狀態。
對齊後直接就可以透過 OpenCV輸出。
fa.align參數分別是要擷取的圖像、要被辨識的圖像(灰階)、要對齊的圖像。
對齊前的圖像雖有抓到臉部,但可能有各種角度,且臉部呈現並不完整,這樣的數據可能會使訓練的難度提升。
對齊後的圖像有效得將臉部對齊,且將臉部整個輪廓完整呈現,也許能幫助訓練時更有效的找到特徵。
稍微修改一下就可以拿來捕捉影片中的臉部圖像。
之前沒有提到,利用影片捕捉可能會得到過多相似度太高的圖像,利用這些數據訓練可能會使權重失衡。
歡迎參考 "利用 PhotoHash篩選相似度過高的圖像",利用 Hamming distance對相似度過高的圖像進行篩選。
本篇參考了 Adrian Rosebrock寫的 "Facial landmarks with dlib, OpenCV, and Python" 和 "Face Alignment with OpenCV and Python"。 文中介紹的更加詳細,有興趣的朋友可以去拜訪 Adrian Rosebrock的網站。
Dlib安裝稍微有點複雜,可以參考由 Adrian Rosebrock寫的 "How to install dlib"。
from imutils import face_utils import numpy as np import imutils import dlib import cv2 face_cascade = cv2.CascadeClassifier('./cascades/haarcascade_frontalface_default.xml') def detect_haar(filename): img = cv2.imread(filename) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=3,) for (x,y,w,h) in faces: img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),3) cv2.imwrite('./haar.png', img) detector = dlib.get_frontal_face_detector() predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat") def detect_face_landmarks(filename): img = cv2.imread(filename) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = detector(gray, 1) for face in faces: shape = predictor(gray, face) shape = face_utils.shape_to_np(shape) (x, y, w, h) = face_utils.rect_to_bb(face) cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 3) for (x, y) in shape: cv2.circle(img, (x, y), 5, (0, 0, 255), -1) # 圖像、圓心、半徑、顏色、第五個參數正數為線的粗細,負數則為填滿 cv2.imwrite('./face_landmarks.png', img) filename = "twice.jpg" detect_haar(filename) detect_face_landmarks(filename)代碼中使用的 shape_predictor_68_face_landmarks.dat,可以點擊這裡下載。
利用 detector = dlib.get_frontal_face_detector()預測灰化後的圖像,評估有幾張臉在這張圖像中。
利用 predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")在捕捉的臉部預測臉部 landmarks。
相較之下,Dlib較能正確得辨識出圖中的兩張臉,另位臉部 landmarks也能有效的識別。
能有效的辨識 landmarks就能使用 FaceAligner功能將臉部對齊。
FaceAligner是利用 landmarks雙眼的部分將圖像調整為雙眼在水平的狀態。
from imutils.face_utils import FaceAligner from imutils.face_utils import rect_to_bb import numpy as np import imutils import dlib import cv2 detector = dlib.get_frontal_face_detector() predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat") fa = FaceAligner(predictor, desiredFaceWidth=200) face_filename = 1 def detect_face_landmarks(filename): img = cv2.imread(filename) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = detector(gray, 1) for face in faces: (x, y, w, h) = rect_to_bb(face) faceOrig = imutils.resize(img[y : y+h, x : x+w], width=200) faceAligned = fa.align(img, gray, face) global face_filename cv2.imwrite('./faceOrig_{0}.png'.format(face_filename), faceOrig) cv2.imwrite('./faceAligned_{0}.png'.format(face_filename), faceAligned) face_filename += 1 filename = "twice.jpg" detect_face_landmarks(filename)FaceAligner導入 predictor辨識臉部 landmarks,就能有效將臉部對齊。
對齊後直接就可以透過 OpenCV輸出。
fa.align參數分別是要擷取的圖像、要被辨識的圖像(灰階)、要對齊的圖像。
對齊前的圖像雖有抓到臉部,但可能有各種角度,且臉部呈現並不完整,這樣的數據可能會使訓練的難度提升。
稍微修改一下就可以拿來捕捉影片中的臉部圖像。
from imutils.face_utils import FaceAligner from imutils.video import count_frames import imutils import numpy as np import dlib import cv2 detector = dlib.get_frontal_face_detector() predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat") fa = FaceAligner(predictor, desiredFaceWidth=64) face_filename = 1 def detect(img, idx, totle): gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = detector(gray, 1) for face in faces: faceAligned = fa.align(gray, gray, face) global face_filename cv2.imwrite('./face/{0}.png'.format(face_filename), faceAligned) face_filename += 1 print('Working with {0} frame. completed {1:.2f} %'.format(idx, idx/float(totle)*100)) detect_video = 'tzuyu.mp4' videoCapture = cv2.VideoCapture(detect_video) success, frame = videoCapture.read() frame_counter = 1 frame_totle = count_frames(detect_video) while success: detect(frame, frame_counter, frame_totle) success, frame = videoCapture.read() frame_counter += 1 print("Done!!")雖然利用 Dlib捕捉臉部精準度提升了許多,但還是有不少捕捉錯誤、臉部沒對齊和轉場效果等的需要手動移除。
之前沒有提到,利用影片捕捉可能會得到過多相似度太高的圖像,利用這些數據訓練可能會使權重失衡。
歡迎參考 "利用 PhotoHash篩選相似度過高的圖像",利用 Hamming distance對相似度過高的圖像進行篩選。
本篇參考了 Adrian Rosebrock寫的 "Facial landmarks with dlib, OpenCV, and Python" 和 "Face Alignment with OpenCV and Python"。 文中介紹的更加詳細,有興趣的朋友可以去拜訪 Adrian Rosebrock的網站。
留言
張貼留言