[深度應用]·實戰掌握Dlib人臉識別開發教程

[深度應用]·實戰掌握Dlib人臉識別開發教程

我的網站--> http://www.yansongsong.cn/python

項目GitHub地址--> https://github.com/xiaosongshine/dlib_face_recognitiongit

1.背景介紹

Dlib是一個深度學習開源工具,基於C++開發,也支持Python開發接口,功能相似於TensorFlow與PyTorch。可是因爲Dlib對於人臉特徵提取支持很好,有不少訓練好的人臉特徵提取模型供開發者使用,因此Dlib人臉識別開發很適合作人臉項目開發。github

上面所說的人臉識別開發,主要是指人臉驗證,就是輸入兩張人臉照片,系統會對比輸出0或者1,表明判斷是不是同一我的。通常的人臉識別開發能夠簡單分爲1.人臉特徵建模2.使用人臉特徵模型進行驗證(其實還應包括人臉對齊等,這些也能夠劃分到1中)。使用Dlib進行開發時,咱們直接可使用訓練好的人臉特徵提取模型,主要的工做就變成了如何進行人臉的驗證。bash

人臉的驗證其實就是計算類似度,同一我的的類似度就會大,不一樣的人就會比較小。能夠採用餘弦類似度或者歐式距離來計算類似度。其中餘弦類似度就是計算角度,歐式距離就是指平方差。均可以用來表示兩個特徵的類似度(距離)。app

 

2.環境搭建

安裝能夠參考個人這篇博客:[深度學習工具]·極簡安裝Dlib人臉識別庫,下面說一下須要注意的點::工具

此博文針對Windows10安裝,其餘平臺能夠仿照這個步驟來安裝學習

  • 安裝Miniconda

使用conda指令來安裝Dlib庫,使用Miniconda與Anaconda均可以,我習慣用Miniconda,簡單佔用內存小。
推薦使用清華源,下載安裝,選擇合適的平臺版本。python==3.6測試

  • 安裝dlib
    注意必定要以管理員身份進入CMD,執行(若是是Linux Mac 就使用 sudo)
conda install -c conda-forge dlib
  • 須要imageio 庫,可使用下述命令安裝
conda install imageio

3.開發實戰 

 

1.實現人臉檢測標記網站

face_test.pythis

import dlib
from imageio import imread
import glob


detector = dlib.get_frontal_face_detector()
win = dlib.image_window()

path = "f1.jpg"
img = imread(path)
dets = detector(img)
print('檢測到了 %d 我的臉' % len(dets))
for i, d in enumerate(dets):
	print('- %d:Left %d Top %d Right %d Bottom %d' % (i, d.left(), d.top(), d.right(), d.bottom()))

win.clear_overlay()
win.set_image(img)
win.add_overlay(dets)
dlib.hit_enter_to_continue()

  

代碼很簡單,經過imread讀取照片,而後進行檢測,輸出結果爲dets的list,有幾張人臉就會有幾個item, 每一個item都有.left(), .top(), .right(), .bottom()四個元素,表明人臉框的四個邊界位置。最後經過win.add_overlay(dets)能夠將標記的框顯示在原圖上。

原始照片
原始照片
輸出照片
輸出照片

其實咱們就可使用這個功能作一個簡單的應用,用來檢測圖片或者視頻中人臉的個數。

2.人臉特徵點提取

在實戰1的基礎上添加人臉特徵提取功能。

import dlib
from imageio import imread
import glob


detector = dlib.get_frontal_face_detector()
win = dlib.image_window()

predictor_path = 'shape_predictor_68_face_landmarks.dat'
predictor = dlib.shape_predictor(predictor_path)

path = "f2.jpg"
img = imread(path)
dets = detector(img)
print('檢測到了 %d 我的臉' % len(dets))


for i, d in enumerate(dets):
	print('- %d: Left %d Top %d Right %d Bottom %d' % (i, d.left(), d.top(), d.right(), d.bottom()))
	shape = predictor(img, d)
	# 第 0 個點和第 1 個點的座標
	print('Part 0: {}, Part 1: {}'.format(shape.part(0), shape.part(1)))
win.clear_overlay()
win.set_image(img)
win.add_overlay(dets)
win.add_overlay(shape)


dlib.hit_enter_to_continue()

  

這段代碼就是在test.py基礎上加入了shape_predictor功能,使之能夠在檢測出人臉基礎上,找到人臉的68個特徵點。反映在圖中就是藍色的線。

 

原始圖片

輸出圖片

注意運行這段代碼須要這個文件predictor_path = 'shape_predictor_68_face_landmarks.dat',我會放在個人github中,方便你們下載使用。

3.人臉識別驗證

在第二步的基礎上,咱們再進一步,實現將人臉提取爲特徵向量,從而咱們就能夠對特徵向量進行比對來實現人臉的驗證,這裏採用的是對比歐式距離的方法。

face_recognition.py

import dlib
from imageio import imread
import glob
import numpy as np

detector = dlib.get_frontal_face_detector()
predictor_path = 'shape_predictor_68_face_landmarks.dat'
predictor = dlib.shape_predictor(predictor_path)
face_rec_model_path = 'dlib_face_recognition_resnet_model_v1.dat'
facerec = dlib.face_recognition_model_v1(face_rec_model_path)


def get_feature(path):
	img = imread(path)
	dets = detector(img)
	print('檢測到了 %d 我的臉' % len(dets))
	# 這裏假設每張圖只有一我的臉
	shape = predictor(img, dets[0])
	face_vector = facerec.compute_face_descriptor(img, shape)
	return(face_vector)

def distance(a,b):
	a,b = np.array(a), np.array(b)
	sub = np.sum((a-b)**2)
	add = (np.sum(a**2)+np.sum(b**2))/2.
	return sub/add

path_lists1 = ["f1.jpg","f2.jpg"]
path_lists2 = ["趙麗穎照片.jpg","趙麗穎測試.jpg"]

feature_lists1 = [get_feature(path) for path in path_lists1]
feature_lists2 = [get_feature(path) for path in path_lists2]

print("feature 1 shape",feature_lists1[0].shape)

out1 = distance(feature_lists1[0],feature_lists1[1])
out2 = distance(feature_lists2[0],feature_lists2[1])

print("diff distance is",out1)
print("same distance is",out2) 

  

輸出結果

檢測到了 1 我的臉
檢測到了 1 我的臉
檢測到了 1 我的臉
檢測到了 1 我的臉

feature 1 shape (128, 1)

diff distance is 0.254767715912
same distance is 0.0620976363391

咱們能夠看出,每張人臉都被提取爲了128維的向量,咱們能夠理解爲128維的座標(xyz是三維,128維就是有128個軸組成),咱們下面須要作的就是計算兩個特徵的距離,設定好合適的閾值,小於這個閾值則識別爲同一我的。代碼正確運行須要這個文件face_rec_model_path = 'dlib_face_recognition_resnet_model_v1.dat',我已經放在本身的github中,方便你們使用。

咱們從上面測試的結果能夠看出,不一樣的距離爲0.25,同一我的爲0.06,閾值就能夠先設置爲其間的一個值。我這裏先設置爲0.09,這個閾值也是須要大量數據來計算的,選擇的準則爲使錯誤識別爲最低。

下面咱們把閾值設置爲0.09,來測試系統可否區分出不一樣的人:在face_recognition.py加入下面代碼

def classifier(a,b,t = 0.09):
  if(distance(a,b)<=t):
    ret = True
  else :
    ret = False
	return(ret)
print("f1 is 趙麗穎",classifier(feature_lists1[0],feature_lists2[1])) 
print("f2 is 趙麗穎",classifier(feature_lists1[1],feature_lists2[1])) 
print("趙麗穎照片.jpg is 趙麗穎測試.jpg",classifier(feature_lists2[0],feature_lists2[1]))

  

 

輸出結果

f1 is 趙麗穎 False
f2 is 趙麗穎 False
趙麗穎照片.jpg is 趙麗穎測試.jpg True

從上面能夠看出,已基本知足對人臉區分的功能,若是如要實用化則須要繼續調優閾值與代碼,調優的準則就是選擇合適的閾值使錯誤識別爲最低。

Hope this helps

我的網站--> http://www.yansongsong.cn/

項目GitHub地址--> https://github.com/xiaosongshine/dlib_face_recognition

相關文章
相關標籤/搜索