1. 程式人生 > >Dlib人臉檢測及關鍵點描述的python實現

Dlib人臉檢測及關鍵點描述的python實現

首先,安裝dlib、skimage前;先安裝libboost

sudo apt-get install libboost-python-dev cmake

接下來到dlib官網dlib.net下載最新的dlib版本(我下的是dlib-19.7),進入檔案所在目錄解壓

bzip2 -d dlib-19.7.tar.bz2
tar xvf dlib-19.7.tar

這是一個二級解壓過程,解壓得到檔案dlib-19.7,進入該目錄下,執行如下命令安裝dlib

python setup.py install

安裝完成後,切換到python,鍵入import dlib,無異常提示表明安裝成功!


接著安裝skimage

sudo apt-get install python-skimage

接下來,dlib的應用先從人臉檢測說起:

import sys
import dlib
from skimage import io

detector = dlib.get_frontal_face_detector() 
window = dlib.image_window()  
img = io.imread("face/0294.jpg")

dets = detector(img, 1)  
print("Number of faces detected: {}".format(len(dets))) 
for i, d in
enumerate(dets): print("Detection {}: Left: {} Top: {} Right: {} Bottom: {}".format(i, d.left(), d.top(), d.right(), d.bottom())) window.clear_overlay() window.set_image(img) window.add_overlay(dets) dlib.hit_enter_to_continue()

首先呼叫dlib.get_frontal_face_detector() 來載入dlib自帶的人臉檢測器
dets = detector(img, 1)將檢測器應用在輸入圖片上,結果返回給dets(引數1表示對圖片進行上取樣一次,有利於檢測到更多的人臉);
dets的個數即為檢測到的人臉的個數;
遍歷dets可以獲取到檢測到的每個人臉四個座標極值。
為了框出檢測到的人臉,用dlib.image_window()來載入顯示視窗,window.set_image(img)先將圖片顯示到視窗上,再利用window.add_overlay(dets)來繪製檢測到的人臉框;
dlib.hit_enter_to_continue()用於等待點選(類似於opencv的cv2.waitKey(0),不加這個會出現閃退)。
檢測結果如下圖:
這裡寫圖片描述

接下來講一下關鍵點的提取:

# -*- coding: utf-8 -*-

import dlib
import numpy
from skimage import io

predictor_path = "shape_predictor_68_face_landmarks.dat"
faces_path = "face/0294.jpg"

'''載入人臉檢測器、載入官方提供的模型構建特徵提取器'''
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(predictor_path)

win = dlib.image_window()
img = io.imread(faces_path)

win.clear_overlay()
win.set_image(img)

dets = detector(img, 1)
print("Number of faces detected: {}".format(len(dets)))

for k, d in enumerate(dets):
    shape = predictor(img, d) 
    landmark = numpy.matrix([[p.x, p.y] for p in shape.parts()])
    print("face_landmark:")
    print (landmark)  # 列印關鍵點矩陣
    win.add_overlay(shape)  #繪製特徵點

dlib.hit_enter_to_continue()

首先通過dlib.shape_predictor(predictor_path)從路徑中載入模型,返回的predictor就是特徵提取器
對dets遍歷,用predictor(img, d)計算檢測到的每張人臉的關鍵點;
獲取每個關鍵點座標shape.parts()的x,y值,存入landmark矩陣(模型預設提取68個關鍵點,所以landmark為68×2矩陣)。
關鍵點提取結果如下:
這裡寫圖片描述

最後講一下關鍵點位置的描述:

只要將上面for迴圈內win.add_overlay(shape)的後面加上如下程式碼就行了!

for idx, point in enumerate(landmarks):
    pos = (point[0, 0], point[0, 1])
    cv2.putText(img,str(idx),pos,fontFace=cv2.FONT_HERSHEY_SCRIPT_SIMPLEX,
                fontScale=0.3,color=(0,255,0))
    #cv2.circle(img, pos, 3, color=(0, 255, 0))
win.set_image(img)

用pos來儲存每個關鍵點的座標對(x,y);
再利用opencv的putText()函式按順序為每個關鍵點新增描述;
關鍵點描述如下圖所示(為了使關鍵點順序清晰,換了張嘴部特徵較明顯的圖):
這裡寫圖片描述