python dlib學習(八):訓練人臉特徵點檢測器
前言
前面的部落格(python dlib學習(二):人臉特徵點標定)介紹了使用dlib識別68個人臉特徵點,但是當時使用的是dlib官方給出的訓練好的模型,這次要自己訓練一個特徵點檢測器出來。當然,想要達到state-of-art的效果需要自己調參,這也是一個苦差了。後面會給出訓練和測試的程式,完整工程的下載連結我會放在博文的最後。
資料集準備
這裡可以選擇自己製作也可以使用dlib原始碼中提供的測試用的資料集。這些圖片存在原始碼目錄中的/examples/faces
裡面。
先看看原始碼中提供的資料集吧:
資料集不大,作為測試使用足夠了。如果希望達到state-of-art的效果,還是需要增大資料集,以及調試出合適的引數。
dlib中的人臉特徵點檢測演算法都是基於CVPR 2014的One Millisecond Face Alignment with an Ensemble of Regression Trees這篇論文實現。自己調參的話,還是有必要讀讀這篇論文。
訓練前還需要在資料集中打好label,這些label都儲存在那幾個xml檔案當中。
開啟training_with_face_landmarks.xml
:
裡面儲存了每張圖片中的人臉的位置,以及68個特徵點的位置資訊。
打label時需要使用到dlib提供的imglab工具。
有關imlab的使用,我在這篇博文中有介紹: python dlib學習(六):訓練自己的模型進行識別。
imglab很容易使用,在這裡不做贅述。如果想自己製作資料集訓練請自行使用imglab製作。
使用imglab開啟xml檔案看看:
密密麻麻地標註好了人臉的位置和特徵點的位置。
訓練
上程式碼。
# coding: utf-8
#
# This example program shows how to use dlib's implementation of the paper:
# One Millisecond Face Alignment with an Ensemble of Regression Trees by
# Vahid Kazemi and Josephine Sullivan, CVPR 2014
import os
import cv2
import dlib
import glob
current_path = os.getcwd()
faces_path = current_path + '/examples/faces'
# 訓練部分
# 引數設定
options = dlib.shape_predictor_training_options()
options.oversampling_amount = 300
options.nu = 0.05
options.tree_depth = 2
options.be_verbose = True
# 匯入打好了標籤的xml檔案
training_xml_path = os.path.join(faces_path, "training_with_face_landmarks.xml")
# 進行訓練,訓練好的模型將儲存為predictor.dat
dlib.train_shape_predictor(training_xml_path, "predictor.dat", options)
# 列印在訓練集中的準確率
print "\nTraining accuracy:{0}".format(dlib.test_shape_predictor(training_xml_path, "predictor.dat"))
# 匯入測試集的xml檔案
testing_xml_path = os.path.join(faces_path, "testing_with_face_landmarks.xml")
# 列印在測試集中的準確率
print "\Testing accuracy:{0}".format(dlib.test_shape_predictor(testing_xml_path, "predictor.dat"))
訓練結果
程式執行後,會列印引數資訊,隨後開始訓練:
訓練完成:
測試
我們需要匯入之前訓練好的模型檔案predictor.dat
,使用其進行識別。如何檢測並進行顯示,就不註釋了,可以參考我以前的部落格:python dlib學習(二):人臉特徵點標定。
# coding: utf-8
#
# This example program shows how to use dlib's implementation of the paper:
# One Millisecond Face Alignment with an Ensemble of Regression Trees by
# Vahid Kazemi and Josephine Sullivan, CVPR 2014
import os
import cv2
import dlib
import glob
# 測試部分
# 匯入訓練好的模型檔案
predictor = dlib.shape_predictor("predictor.dat")
detector = dlib.get_frontal_face_detector()
print("Showing detections and predictions on the images in the faces folder...")
for f in glob.glob(os.path.join(faces_path, "*.jpg")):
print("Processing file: {}".format(f))
img = cv2.imread(f)
img2 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
dets = detector(img2, 1)
print("Number of faces detected: {}".format(len(dets)))
for index, face in enumerate(dets):
print('face {}; left {}; top {}; right {}; bottom {}'.format(index, face.left(), face.top(), face.right(), face.bottom()))
# left = face.left()
# top = face.top()
# right = face.right()
# bottom = face.bottom()
# cv2.rectangle(img, (left, top), (right, bottom), (0, 255, 0), 3)
# cv2.namedWindow(f, cv2.WINDOW_AUTOSIZE)
# cv2.imshow(f, img)
shape = predictor(img, face)
# print(shape)
# print(shape.num_parts)
for index, pt in enumerate(shape.parts()):
print('Part {}: {}'.format(index, pt))
pt_pos = (pt.x, pt.y)
cv2.circle(img, pt_pos, 2, (255, 0, 0), 1)
#print(type(pt))
#print("Part 0: {}, Part 1: {} ...".format(shape.part(0), shape.part(1)))
cv2.namedWindow(f, cv2.WINDOW_AUTOSIZE)
cv2.imshow(f, img)
cv2.waitKey(0)
cv2.destroyAllWindows()