国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

基于OpenCV和Dlib的深度學(xué)習(xí)人臉識(shí)別技術(shù)實(shí)踐與應(yīng)用

這篇具有很好參考價(jià)值的文章主要介紹了基于OpenCV和Dlib的深度學(xué)習(xí)人臉識(shí)別技術(shù)實(shí)踐與應(yīng)用。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

一、背景介紹

計(jì)算機(jī)視覺(jué)技術(shù)在當(dāng)前人工智能發(fā)展進(jìn)程中已然達(dá)到較高成熟度,一系列基礎(chǔ)算法與應(yīng)用場(chǎng)景獲得廣泛實(shí)踐與驗(yàn)證。在算法層面,圖像處理、目標(biāo)檢測(cè)、語(yǔ)義分割等多個(gè)領(lǐng)域的技術(shù)不斷突破,準(zhǔn)確率與效率持續(xù)提升。在應(yīng)用上,人臉識(shí)別、車牌識(shí)別、醫(yī)學(xué)圖像分析等已步入商業(yè)化應(yīng)用階段,被廣泛應(yīng)用于安防監(jiān)控、智能駕駛、醫(yī)療輔助診斷等領(lǐng)域,大幅提升效率并創(chuàng)造新的應(yīng)用形式。

基于此,結(jié)合公司規(guī)劃與業(yè)務(wù)需求,我們決定在人臉識(shí)別領(lǐng)域進(jìn)行自主研發(fā)與應(yīng)用。具體來(lái)看,公司主要面臨以下應(yīng)用需求:

  • 業(yè)務(wù)背景:主要應(yīng)用于一些智能終端設(shè)備上,在進(jìn)行權(quán)限驗(yàn)證和流程控制上需要進(jìn)行人臉識(shí)別驗(yàn)證

  • 平臺(tái)架構(gòu):平臺(tái)整體架構(gòu)以云+端的模式,一個(gè)云平臺(tái)部署在地市或者省廳,下屬分局和派出所等場(chǎng)所部署N個(gè)終端設(shè)備,每臺(tái)設(shè)備配置雙目攝像頭,連接云端平臺(tái),實(shí)現(xiàn)人臉相關(guān)功能。

  • 部署架構(gòu):平臺(tái)主要部署在地市和省廳,平臺(tái)系統(tǒng)整體并發(fā)量并不算特別高,一般地市也就在20 ~ 30 QPS。但需要部署在專網(wǎng),所以人臉?lè)?wù)需可做本地私有化部署,無(wú)法使用SaaS服務(wù)。

  • 功能需求:軟件平臺(tái)包括人臉庫(kù)的管理,和人臉數(shù)據(jù)采集。終端設(shè)備主要包括人臉識(shí)別、人臉比對(duì)(1:1和1:N)、活體檢測(cè)。

  • 人臉底庫(kù):根據(jù)實(shí)際部署需求,底庫(kù)從萬(wàn)級(jí)到千萬(wàn)級(jí)不等。具體根據(jù)項(xiàng)目規(guī)模來(lái)。

通過(guò)自主研發(fā),我們不僅能充分考量業(yè)務(wù)場(chǎng)景的特點(diǎn),實(shí)現(xiàn)針對(duì)性的技術(shù)創(chuàng)新與效率優(yōu)化,也能隨時(shí)針對(duì)算法與模型進(jìn)行調(diào)整升級(jí),為公司整體技術(shù)實(shí)力與核心競(jìng)爭(zhēng)力的提升奠定堅(jiān)實(shí)基礎(chǔ)。

本文將介紹如何使用 Dlib 庫(kù)和深度學(xué)習(xí)來(lái)實(shí)現(xiàn)人臉識(shí)別,如何利用預(yù)訓(xùn)練網(wǎng)絡(luò)和OpenCV庫(kù)進(jìn)行圖像處理。OpenCV 庫(kù)將用于執(zhí)行一些簡(jiǎn)單的圖像處理任務(wù),例如將圖像轉(zhuǎn)換為灰度、調(diào)整圖像大小等,從而輕松地在各種場(chǎng)景中應(yīng)用人臉識(shí)別技術(shù)。

我們將使用 Dlib 提供的預(yù)訓(xùn)練網(wǎng)絡(luò)。該網(wǎng)絡(luò)已在超過(guò) 300 萬(wàn)張圖像的數(shù)據(jù)集上進(jìn)行了訓(xùn)練。該網(wǎng)絡(luò)稱為 ResNet-34。

二、人臉識(shí)別概述

人臉識(shí)別是一種通過(guò)分析個(gè)人面部特征來(lái)識(shí)別或驗(yàn)證身份的技術(shù)。它在驗(yàn)證個(gè)人身份、尋找失蹤人員、識(shí)別罪犯等方面發(fā)揮著重要作用。該技術(shù)利用已知人臉的數(shù)據(jù)庫(kù),將其與未知人臉進(jìn)行比較,以找到匹配并預(yù)測(cè)其身份。

為了實(shí)現(xiàn)這一目標(biāo),人臉識(shí)別采用了多種算法,包括特征臉、局部二進(jìn)制模式和深度學(xué)習(xí)等。本文將深入探討如何運(yùn)用深度學(xué)習(xí)方法來(lái)進(jìn)行人臉識(shí)別,以提高準(zhǔn)確性和效率。通過(guò)學(xué)習(xí)這些技術(shù),您將能夠更好地理解人臉識(shí)別的原理和應(yīng)用,并在實(shí)際場(chǎng)景中應(yīng)用它們。無(wú)論是保障安全、提升便捷性還是推動(dòng)科技創(chuàng)新,人臉識(shí)別都具有廣闊的前景和潛力。

三、人臉識(shí)別步驟

人臉識(shí)別一般分為以下4步:

  1. 人臉檢測(cè):人臉識(shí)別流程的第一步是檢測(cè)圖像中的所有人臉。通過(guò)使用不同的人臉檢測(cè)器(如Haar級(jí)聯(lián)、HOG或基于深度學(xué)習(xí)的檢測(cè)器),我們可以檢測(cè)圖像中的人臉。本文我們將使用 Dlib 提供的 HOG 人臉檢測(cè)器實(shí)現(xiàn)。

  2. 面部對(duì)齊(可選):使用面部標(biāo)志來(lái)對(duì)齊或標(biāo)準(zhǔn)化面部,以提高識(shí)別系統(tǒng)的準(zhǔn)確性。本文將跳過(guò)此步驟。

  3. 面部編碼:將面部圖像傳遞給模型,并提取面部特征。

  4. 人臉識(shí)別:將提取的人臉特征與已知人臉特征的數(shù)據(jù)庫(kù)進(jìn)行比較,嘗試找到匹配。常用的算法包括K最近鄰(KNN)、支持向量機(jī)(SVM)和隨機(jī)森林等。

四、人臉識(shí)別算法及基本原理?

基于深度學(xué)習(xí)的人臉識(shí)別算法是建立在卷積神經(jīng)網(wǎng)絡(luò)(CNN)的基礎(chǔ)上的。這些算法中的一種被稱為孿生網(wǎng)絡(luò),它由兩個(gè)或多個(gè)相同的子網(wǎng)絡(luò)組成。每個(gè)子網(wǎng)絡(luò)共享相同的權(quán)重和參數(shù)。這種架構(gòu)使得模型能夠比較輸入圖像并找到它們之間的相似性,這對(duì)于人臉識(shí)別非常重要。

基于dlib的人臉識(shí)別模塊化設(shè)計(jì),AI編程實(shí)戰(zhàn),AI應(yīng)用實(shí)戰(zhàn),opencv,深度學(xué)習(xí),人工智能

?目前,有許多先進(jìn)的孿生網(wǎng)絡(luò)架構(gòu)被用于人臉識(shí)別,其中一些包括:

  1. VGG-Face:基于VGGNet的人臉識(shí)別模型,具有較高的準(zhǔn)確性和魯棒性。

  2. Dlib的基于ResNet的人臉識(shí)別模型:使用ResNet架構(gòu),該模型在人臉識(shí)別領(lǐng)域表現(xiàn)出色。

  3. FaceNet:通過(guò)將人臉圖像映射到高維空間中的特征向量來(lái)實(shí)現(xiàn)人臉識(shí)別。

  4. OpenFace:采用深度神經(jīng)網(wǎng)絡(luò)進(jìn)行人臉識(shí)別,具有較高的準(zhǔn)確性和魯棒性。

  5. Facebook DeepFace:Facebook開(kāi)發(fā)的人臉識(shí)別系統(tǒng),利用深度學(xué)習(xí)技術(shù)實(shí)現(xiàn)高精度的人臉識(shí)別。

  6. DeepID:通過(guò)多層神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)人臉特征,實(shí)現(xiàn)準(zhǔn)確的人臉識(shí)別。

  7. ArcFace:采用角度余弦損失函數(shù)來(lái)提高人臉識(shí)別的準(zhǔn)確性。

  8. SFace:結(jié)合了判別性特征學(xué)習(xí)和度量學(xué)習(xí)的人臉識(shí)別算法,具有較高的魯棒性和準(zhǔn)確性。

在本文中,我們將使用Dlib基于ResNet-34架構(gòu)的人臉識(shí)別模型。該模型通過(guò)深度學(xué)習(xí)技術(shù)實(shí)現(xiàn)了對(duì)人臉的準(zhǔn)確識(shí)別,并在實(shí)際應(yīng)用中取得了良好的效果。通過(guò)研究和理解這些基于深度學(xué)習(xí)的人臉識(shí)別算法及其工作原理,我們可以更好地應(yīng)用它們于實(shí)際場(chǎng)景,并推動(dòng)人臉識(shí)別技術(shù)的發(fā)展和創(chuàng)新。

在網(wǎng)絡(luò)訓(xùn)練過(guò)程中,該模型使用了三個(gè)圖像進(jìn)行輸入:

  1. "錨點(diǎn)"圖像:這是給定的人物圖像,作為訓(xùn)練的基準(zhǔn)。

  2. "正樣本"圖像:這是與錨點(diǎn)圖像相同人物的圖像,用于訓(xùn)練網(wǎng)絡(luò)識(shí)別相似人物。

  3. "負(fù)樣本"圖像:這是不同人物的圖像,用于訓(xùn)練網(wǎng)絡(luò)區(qū)分不同人物。

通過(guò)將這三個(gè)圖像輸入到網(wǎng)絡(luò)中,網(wǎng)絡(luò)會(huì)為每個(gè)圖像生成一個(gè)128維的嵌入向量。

在訓(xùn)練過(guò)程中,神經(jīng)網(wǎng)絡(luò)使用損失函數(shù)來(lái)衡量嵌入向量之間的距離。如果相似人物的嵌入向量(即錨點(diǎn)和正樣本圖像)之間的距離較大,或者兩個(gè)不同人物的嵌入向量(即錨點(diǎn)和負(fù)樣本圖像)之間的距離較小,則網(wǎng)絡(luò)會(huì)受到懲罰。

通過(guò)這種訓(xùn)練方式,網(wǎng)絡(luò)逐漸學(xué)習(xí)生成更接近的嵌入向量來(lái)表示相同人物的圖像,同時(shí)將不同人物的圖像生成更遠(yuǎn)離的嵌入向量。這樣,網(wǎng)絡(luò)就能夠通過(guò)嵌入向量的距離來(lái)判斷圖像之間的相似性,從而實(shí)現(xiàn)準(zhǔn)確的人臉識(shí)別。通過(guò)不斷優(yōu)化網(wǎng)絡(luò)的訓(xùn)練過(guò)程,可以提高人臉識(shí)別算法的準(zhǔn)確性和魯棒性,使其在實(shí)際應(yīng)用中更加可靠和有效。

基于dlib的人臉識(shí)別模塊化設(shè)計(jì),AI編程實(shí)戰(zhàn),AI應(yīng)用實(shí)戰(zhàn),opencv,深度學(xué)習(xí),人工智能
孿生網(wǎng)絡(luò)的訓(xùn)練過(guò)程示例

一旦網(wǎng)絡(luò)訓(xùn)練完成,我們可以利用它為新圖像生成嵌入向量。這些嵌入向量可用于訓(xùn)練人臉識(shí)別分類器,而分類器可以采用各種機(jī)器學(xué)習(xí)算法,如K最近鄰(KNN)、支持向量機(jī)(SVM)和隨機(jī)森林等。在本文中,我們將使用K最近鄰算法。

然而,需要說(shuō)明的是,我們并不需要從頭開(kāi)始訓(xùn)練模型,因?yàn)槲覀兛梢允褂靡粋€(gè)預(yù)訓(xùn)練好的模型。因此,我們的任務(wù)是獲取這個(gè)預(yù)訓(xùn)練好的模型,并利用它為我們自己的數(shù)據(jù)集生成特征(也稱為嵌入向量)。接著,我們將這些特征存儲(chǔ)在數(shù)據(jù)庫(kù)或文件中。

當(dāng)我們獲得一張新的圖像時(shí),我們會(huì)檢測(cè)圖像中的人臉,并從圖像中提取出人臉區(qū)域,然后將其輸入到模型中。模型會(huì)生成一個(gè)128維的嵌入向量。

最后,我們使用K最近鄰算法計(jì)算這個(gè)新人臉嵌入向量與我們數(shù)據(jù)庫(kù)中所有人臉嵌入向量之間的距離。距離最接近的人就是新圖像中的人。

通過(guò)這樣的流程,我們能夠快速準(zhǔn)確地識(shí)別人臉,實(shí)現(xiàn)高效的人臉識(shí)別應(yīng)用。這種基于深度學(xué)習(xí)的人臉識(shí)別算法在安全領(lǐng)域、人臉支付、人臉門禁等多個(gè)領(lǐng)域具有廣泛的應(yīng)用前景。

五、人臉識(shí)別服務(wù)開(kāi)發(fā)

5.1、安裝必要依賴庫(kù)

為了實(shí)現(xiàn)人臉識(shí)別功能,我們需要安裝一些必要的依賴庫(kù),包括OpenCVDlibNumpy(在安裝之前,請(qǐng)確保已經(jīng)安裝了CMake)。

這些庫(kù)都可以通過(guò)使用pip命令來(lái)進(jìn)行安裝。

首先,我們需要?jiǎng)?chuàng)建一個(gè)虛擬環(huán)境。然后,激活該虛擬環(huán)境,并使用pip命令來(lái)安裝所需的庫(kù)。

$ python3 -m venv venv
$ source venv/bin/activate
$ pip install -r requirements.txt

5.2、準(zhǔn)備人臉數(shù)據(jù)集

本文將使用Labeled Faces in the Wild (LFW)數(shù)據(jù)集進(jìn)行人臉識(shí)別任務(wù)。該數(shù)據(jù)集包含了超過(guò)13,000張從網(wǎng)絡(luò)上收集的面部圖像。

這個(gè)數(shù)據(jù)集被分成了5749個(gè)目錄,每個(gè)目錄中包含了一個(gè)人的1到530張圖像。因此,整個(gè)數(shù)據(jù)集中包含了5749個(gè)不同的人。

要下載這個(gè)數(shù)據(jù)集,您可以前往LFW數(shù)據(jù)集網(wǎng)站并點(diǎn)擊"Download"按鈕。

基于dlib的人臉識(shí)別模塊化設(shè)計(jì),AI編程實(shí)戰(zhàn),AI應(yīng)用實(shí)戰(zhàn),opencv,深度學(xué)習(xí),人工智能

然后單擊All images as gzipped tar file鏈接進(jìn)行下載,下載完成后。會(huì)得到一個(gè)名為lfw.tgz的壓縮文件。

基于dlib的人臉識(shí)別模塊化設(shè)計(jì),AI編程實(shí)戰(zhàn),AI應(yīng)用實(shí)戰(zhàn),opencv,深度學(xué)習(xí),人工智能

解壓縮lfw.tgz文件后,您將獲得數(shù)據(jù)集中的所有圖像。在本文中,我們將僅選擇4個(gè)不同的人來(lái)執(zhí)行人臉識(shí)別任務(wù)。我選擇的人物是:阿諾·施瓦辛格、讓·克雷蒂安、小泉純一郎和雷杰普·塔伊普·埃爾多安。

基于dlib的人臉識(shí)別模塊化設(shè)計(jì),AI編程實(shí)戰(zhàn),AI應(yīng)用實(shí)戰(zhàn),opencv,深度學(xué)習(xí),人工智能

?同時(shí),我們還刪除了那些包含多張面孔的圖像,因?yàn)槲覀兊乃惴僭O(shè)每張圖像中只有一個(gè)或多個(gè)屬于同一個(gè)人的面孔。

5.3、項(xiàng)目整體結(jié)構(gòu)

本教程的項(xiàng)目結(jié)構(gòu)如下:

tree --filelimit 10 --dirsfirst
├── dataset
│   ├── Arnold_Schwarzenegger  [35 entries]
│   ├── Jean_Chretien  [48 entries]
│   ├── Junichiro_Koizumi  [47 entries]
│   └── Recep_Tayyip_Erdogan  [24 entries]
├── examples  [14 entries]
├── models
│   ├── dlib_face_recognition_resnet_model_v1.dat
│   └── shape_predictor_68_face_landmarks.dat
├── venv
├── encodings.pickle
├── face_encoding.py
├── face_recognition_images.py
├── face_recognition_videos.py
├── requirements.txt
└── utils.py

以下是每個(gè)目錄/文件的簡(jiǎn)要說(shuō)明:

  • dataset/:包含我們想要識(shí)別的人的圖像。

  • example/:包含一些示例圖像,我們將使用它們來(lái)測(cè)試我們的人臉識(shí)別系統(tǒng)。

  • models/:包含我們將用于生成人臉嵌入的預(yù)訓(xùn)練模型。

  • venv/:我們的虛擬環(huán)境。

  • codings.pickle:包含我們數(shù)據(jù)集中的人臉嵌入的文件。這些嵌入將由face_encoding.py腳本生成。

  • face_encoding.py:此文件包含用于生成數(shù)據(jù)集中的人臉嵌入的代碼。

  • face_recognition_images.py:該文件包含用于對(duì)圖像執(zhí)行人臉識(shí)別的代碼。

  • face_recognition_videos.py:此文件包含對(duì)視頻執(zhí)行人臉識(shí)別的代碼。

  • requirements.txt:包含我們需要安裝的庫(kù)的列表。您可以使用命令pip install -rrequirements.txt安裝它們。

  • utils.py:為了使我們的代碼更有條理,我們將把所有實(shí)用函數(shù)放在這個(gè)文件中。

5.4、提取人臉特征

在進(jìn)行人臉識(shí)別之前,我們首先需要加載待識(shí)別人物的圖像。然后,我們將從這些圖像中提取出面部區(qū)域,并為每個(gè)面部區(qū)域生成相應(yīng)的面部嵌入。接下來(lái),讓我們導(dǎo)入所需的包和模型。請(qǐng)打開(kāi)utils.py文件,并編寫以下代碼:

import dlib
from glob import glob 
import cv2
import numpy as np
import os

# 加載人臉檢測(cè)器、關(guān)鍵點(diǎn)預(yù)測(cè)器和人臉識(shí)別模型
face_detector = dlib.get_frontal_face_detector()
shape_predictor = dlib.shape_predictor("models/shape_predictor_68_face_landmarks.dat")
face_encoder = dlib.face_recognition_model_v1("models/dlib_face_recognition_resnet_model_v1.dat")

人臉檢測(cè)器(face_ detector)用于檢測(cè)輸入圖像中的人臉區(qū)域。

地標(biāo)預(yù)測(cè)器 ( ***shape_predictor*** ) 用于定位面部區(qū)域中的面部地標(biāo)。我們需要面部標(biāo)志來(lái)生成面部嵌入。

人臉編碼器模型(face_encoder)用于生成人臉嵌入。

接下來(lái),我們將獲取數(shù)據(jù)集中圖像的路徑。讓我們?yōu)榇藙?chuàng)建一個(gè)輔助函數(shù):

# 更改此處以包括您想要支持的其他圖像格式(例如.bmp)
VALID_EXTENSIONS = ['.png', '.jpg', '.jpeg']

def get_image_paths(root_dir, class_names):
    """ 獲取數(shù)據(jù)集中圖像的路徑"""
    image_paths = []

get_image_paths **()函數(shù)有兩個(gè)參數(shù):root_dirclass_names。rootdir是數(shù)據(jù)集路徑。classnames是我們想要識(shí)別每個(gè)人的姓名列表。class_names**列表如下所示:

>>> class_names
[‘Huangjiaju’, 'Zhangguorong', 'Recep_Tayyip_Erdogan', 'Jean_Chretien', 'Junichiro_Koizumi', 'Arnold_Schwarzenegger']

現(xiàn)在,我們將循環(huán)遍歷類名,對(duì)于每個(gè)類名,我們將循環(huán)遍歷目錄中的圖像,并將圖像的路徑添加到 image_paths 列表

    # 循環(huán)遍歷類名
    for class_name in class_names:
        # 獲取當(dāng)前類目錄中文件的路徑
        class_dir = os.path.sep.join([root_dir, class_name])
        class_file_paths = glob(os.path.sep.join([class_dir, '*.*']))

        # 循環(huán)遍歷當(dāng)前類目錄中的文件路徑
        for file_path in class_file_paths:
            # 提取當(dāng)前文件的文件擴(kuò)展名
            ext = os.path.splitext(file_path)[1]

            # 如果文件擴(kuò)展名不在有效擴(kuò)展名列表中,則忽略該文件
            if ext.lower() not in VALID_EXTENSIONS:
                print("Skipping file: {}".format(file_path))
                continue

            # 將當(dāng)前圖像的路徑添加到圖像路徑列表中
            image_paths.append(file_path)

    return image_paths

glob **()**函數(shù)返回當(dāng)前類目錄中文件的路徑列表。我們循環(huán)遍歷文件路徑并提取當(dāng)前文件的文件擴(kuò)展名。如果文件擴(kuò)展名無(wú)效(不是圖像),我們將跳過(guò)它并繼續(xù)下一個(gè)。

如果文件擴(kuò)展名有效(圖像),我們將當(dāng)前圖像的路徑添加到image_paths列表中。讓我們測(cè)試一下get_image_paths()函數(shù)。

>>> from utils import get_image_paths
>>> class_names = ['Recep_Tayyip_Erdogan', 'Jean_Chretien', 'Junichiro_Koizumi', 'Arnold_Schwarzenegger']
>>> image_paths = get_image_paths("dataset", class_names)
>>> image_paths
['dataset/Recep_Tayyip_Erdogan/Recep_Tayyip_Erdogan_0017.jpg', 'dataset/Recep_Tayyip_Erdogan/Recep_Tayyip_Erdogan_0013.jpg', 'dataset/Recep_Tayyip_Erdogan/Recep_Tayyip_Erdogan_0012.jpg', ...]

如您所見(jiàn),get_image_paths()函數(shù)返回?cái)?shù)據(jù)集中圖像的路徑列表。接下來(lái),我們將創(chuàng)建一個(gè)輔助函數(shù)來(lái)從圖像中提取面部區(qū)域。為此,我們將使用 Dlib 人臉檢測(cè)器。

def face_rects(image):
    # 將圖像轉(zhuǎn)換為灰度圖像
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    # 在灰度圖像中檢測(cè)人臉
    rects = face_detector(gray, 1)
    # 返回邊界框
    return rects

face_rects **()**函數(shù)將圖像作為輸入并將我們的面部檢測(cè)器應(yīng)用于它。它返回圖像中面部區(qū)域的邊界框?,F(xiàn)在我們有了邊界框,我們可以使用它們來(lái)應(yīng)用地標(biāo)預(yù)測(cè)器并獲取面部地標(biāo)。

def face_landmarks(image):
    return [shape_predictor(image, face_rect) for face_rect in face_rects(image)]

該函數(shù)循環(huán)遍歷每個(gè)面部區(qū)域的邊界框。對(duì)于每個(gè)面部區(qū)域,它應(yīng)用地標(biāo)預(yù)測(cè)器。它返回一個(gè)包含每個(gè)面部區(qū)域的面部標(biāo)志的列表?,F(xiàn)在,最后一步是為每個(gè)面部區(qū)域生成面部嵌入。同樣,我們將為此創(chuàng)建一個(gè)輔助函數(shù)。

def face_encodings(image):
    # 計(jì)算每個(gè)人臉的面部嵌入。`compute_face_descriptor`函數(shù)返回一個(gè)描述圖像中人臉的128維向量
    return [np.array(face_encoder.compute_face_descriptor(image, face_landmark)) 
            for face_landmark in face_landmarks(image)]

因此,這里的face_encodings()函數(shù)將圖像作為輸入并循環(huán)遍歷每個(gè)面部區(qū)域的面部標(biāo)志。對(duì)于每個(gè)面部區(qū)域,它應(yīng)用面部編碼器并生成面部嵌入。它返回一個(gè)包含每個(gè)面部區(qū)域的面部嵌入的列表。讓我們測(cè)試一下我們的face_encodings()函數(shù)。

>>> from utils import face_encodings
>>> import cv2
>>> image = cv2.imread("dataset/Recep_Tayyip_Erdogan/Recep_Tayyip_Erdogan_0017.jpg")
>>> face_encodings(image)
[array([-0.06507568,  0.09282234, -0.05310396,  0.02033956, -0.05189228,
        0.0038331 ,  0.02058978, -0.16266678,  0.16215618, -0.07854272,
        0.22294444, -0.02746225, -0.21170133, -0.10646843,  0.12207212,
        0.08830512, -0.1529105 , -0.15543598, -0.13133761, -0.07789465,
       -0.01266594, -0.03342287, -0.07684287, -0.01465143, -0.16457887,
       -0.29837033, -0.07858203, -0.06912123,  0.10793255, -0.06668072,
        0.05952527, -0.01771747, -0.18992454, -0.10981462,  0.09109481,
        0.06847958, -0.06725877, -0.02276845,  0.15260877, -0.05116167,
       -0.13816157, -0.05038669,  0.10000665,  0.25293767,  0.11579101,
        0.09511411,  0.05221565, -0.10308918, ...])]
>>> face_encodings(image)[0].shape
(128,)

如您所見(jiàn),face_encodings()函數(shù)返回一個(gè)列表,其中包含圖像中每個(gè)人臉區(qū)域的人臉嵌入。每個(gè)人臉嵌入都是一個(gè) 128 維的 Numpy 數(shù)組。

我們將從數(shù)據(jù)集中的每個(gè)圖像生成人臉嵌入開(kāi)始。然后我們將面部嵌入存儲(chǔ)在字典中。字典的鍵將是數(shù)據(jù)集中每個(gè)人的姓名,值將是該人的每個(gè)圖像的面部嵌入列表。

最后,我們將字典保存到磁盤。打開(kāi)face_encoding.py文件并添加以下代碼:

import pickle
import cv2
import os

from utils import get_image_paths
from utils import face_encodings


root_dir = "dataset"
class_names = os.listdir(root_dir)

# 獲取圖像的路徑
image_paths = get_image_paths(root_dir, class_names)
# 初始化一個(gè)字典來(lái)存儲(chǔ)每個(gè)人的姓名和相應(yīng)的編碼
name_encondings_dict = {}

我們將使用pickle模塊將字典保存到文件中,以便稍后在測(cè)試人臉識(shí)別系統(tǒng)時(shí)使用它。這里我們使用get_image_paths()函數(shù)來(lái)獲取數(shù)據(jù)集中圖像的路徑。我們還初始化一個(gè)字典來(lái)存儲(chǔ)標(biāo)簽(每個(gè)人的名字)和相應(yīng)的面部嵌入?,F(xiàn)在,我們將循環(huán)圖像的路徑并為每個(gè)圖像生成面部嵌入。

# 初始化處理的圖像數(shù)量
nb_current_image = 1
# 現(xiàn)在我們可以循環(huán)遍歷圖像路徑,定位人臉并對(duì)其進(jìn)行編碼
for image_path in image_paths:
    print(f"Image processed {nb_current_image}/{len(image_paths)}")
    # 加載圖像
    image = cv2.imread(image_path)
    # 獲取人臉嵌入
    encodings = face_encodings(image)
    # 從圖像路徑中獲取姓名
    name = image_path.split(os.path.sep)[-2]
    # 獲取當(dāng)前姓名的編碼
    e = name_encondings_dict.get(name, [])
    # 更新當(dāng)前姓名的編碼列表
    e.extend(encodings)
    # 更新當(dāng)前姓名的編碼列表
    name_encondings_dict[name] = e
    nb_current_image += 1

所以這里我們循環(huán)遍歷圖像的路徑。對(duì)于每條路徑,我們使用 OpenCV 加載圖像并使用face_encodings()函數(shù)生成人臉嵌入。

回想一下,在內(nèi)部,face_encodings()函數(shù)應(yīng)用面部檢測(cè)器來(lái)獲取圖像中面部區(qū)域的邊界框,然后應(yīng)用標(biāo)志預(yù)測(cè)器來(lái)獲取面部標(biāo)志。最后,它使用面部標(biāo)志應(yīng)用面部編碼器來(lái)生成面部嵌入。

我們還從圖像的路徑中獲取人名。圖像路徑的格式為 dataset /RecepTayyipErdogan/RecepTayyipErdogan_0017.jpg。因此,我們可以通過(guò)使用目錄分隔符 ( os.path.sep )分割路徑并獲取列表的倒數(shù)第二個(gè)元素來(lái)獲取人員的姓名。

接下來(lái),我們嘗試從字典中獲取當(dāng)前人的面部嵌入列表。如果字典中沒(méi)有這個(gè)人的名字,我們會(huì)為面部嵌入初始化一個(gè)空列表。

然后,我們使用為當(dāng)前圖像生成的人臉嵌入來(lái)擴(kuò)展嵌入列表。最后,我們使用當(dāng)前人的新面部嵌入列表更新字典。

循環(huán)之后,我們將擁有一個(gè)字典,其中包含每個(gè)人的姓名以及該人的每個(gè)圖像的相應(yīng)面部嵌入列表。

字典看起來(lái)像這樣:

>>> name_encondings_dict
{'Recep_Tayyip_Erdogan': [array([-0.05895536,  0.07766615,  ...]), 
                          array([-0.04809677,  0.08508434,  ...]),
                          ...], 
'Jean_Chretien': [array([-0.18319653,  -0.18853943, ...]),
                  array([-0.065067637,  0.13090725, ...]),
                  ...],
'Junichiro_Koizumi': [array([-0.18313943, 0.07619441, ...]),
                      array([-0.18313943,  0.0761441, ...]),
                      ...],
'Arnold_Schwarzenegger': [array([-0.117762501,  0.152411991, ...]),
                          array([-0.117625501,  0.152341991, ...]),
                          ...],
}

最后一步是使用pickle模塊將字典保存到文件中。

# 將名稱編碼字典保存到磁盤
with open("encodings.pickle", "wb") as f:
    pickle.dump(name_encondings_dict, f)

現(xiàn)在,我們可以運(yùn)行face_encoding.py腳本來(lái)為數(shù)據(jù)集中的每個(gè)圖像生成人臉嵌入。打開(kāi)終端,導(dǎo)航到項(xiàng)目目錄,然后運(yùn)行以下命令:

$ python face_encoding.py
Image processed 1/162
Image processed 2/162
Image processed 3/162
...
Image processed 160/162
Image processed 161/162
Image processed 162/162

腳本運(yùn)行完成后,您應(yīng)該在項(xiàng)目目錄中看到一個(gè)名為encodings.pickle的文件。該文件包含帶有每個(gè)人的姓名的字典以及該人的每個(gè)圖像的相應(yīng)面部嵌入列表。

5.5、人臉識(shí)別比對(duì)

現(xiàn)在我們有了面部嵌入,我們可以開(kāi)始識(shí)別圖像中的面部。我們將在face_recognition_images.py文件中編寫以下代碼:

import pickle
import cv2

from utils import face_rects
from utils import face_encodings

# 加載編碼 + 名稱字典
with open("encodings.pickle", "rb") as f:
    name_encodings_dict = pickle.load(f)

# 加載輸入圖像
image = cv2.imread("examples/18.jpeg")
# 為輸入圖像中的每個(gè)人臉獲取128維面部嵌入
encodings = face_encodings(image)
# 此列表將包含圖像中檢測(cè)到的每個(gè)人臉的名稱
names = []

我們首先加載包含每個(gè)人的姓名和相應(yīng)的面部嵌入列表的字典。接下來(lái),我們使用 OpenCV 加載輸入圖像,并使用face_encodings()函數(shù)為圖像中的每個(gè)人臉生成人臉嵌入。

下一步是循環(huán)面部嵌入并將其與數(shù)據(jù)集中每個(gè)人的面部嵌入進(jìn)行比較。我們需要另一個(gè)輔助函數(shù)來(lái)計(jì)算當(dāng)前面部嵌入與數(shù)據(jù)集中每個(gè)人的面部嵌入之間的距離。

如果當(dāng)前人臉嵌入與數(shù)據(jù)庫(kù)中的人臉嵌入之間的距離小于閾值,則該人臉被視為匹配,因此我們將當(dāng)前人的“匹配數(shù)”增加 1。

通過(guò)查看代碼更容易理解這個(gè)邏輯。打開(kāi)utils.py文件并添加以下代碼:

def nb_of_matches(known_encodings, unknown_encoding):
    # 計(jì)算當(dāng)前人臉編碼與數(shù)據(jù)庫(kù)中所有人臉編碼之間的歐氏距離
    distances = np.linalg.norm(known_encodings - unknown_encoding, axis=1)
    # 僅保留小于閾值的距離
    small_distances = distances <= 0.6
    # 返回匹配數(shù)量
    return sum(small_distances)

nb_of_matches **()**函數(shù)采用兩個(gè)參數(shù):數(shù)據(jù)集中每個(gè)人的面部嵌入列表 ( known_encodings ) 和輸入圖像中當(dāng)前面部的面部嵌入 ( unknown_encoding )。

它計(jì)算當(dāng)前人臉編碼與數(shù)據(jù)庫(kù)中所有人臉編碼之間的歐幾里德距離。然后,它僅保留小于閾值的距離(如果距離小于閾值,則認(rèn)為面部匹配)。

最后,將距離小于閾值的次數(shù)相加,得到當(dāng)前人臉的匹配數(shù)?,F(xiàn)在,我們可以循環(huán)輸入圖像中每個(gè)人臉的人臉嵌入,并使用nb_of_matches()函數(shù)來(lái)獲取每個(gè)人臉的匹配數(shù)。

# 導(dǎo)入輔助函數(shù)
from utils import nb_of_matches

# 循環(huán)遍歷編碼
for encoding in encodings:
    # 初始化一個(gè)字典來(lái)存儲(chǔ)人名和匹配次數(shù)
    counts = {}
    # 循環(huán)遍歷已知編碼
    for (name, encodings) in name_encodings_dict.items():
        # 計(jì)算當(dāng)前編碼與已知人臉編碼之間的匹配次數(shù),并將匹配次數(shù)存儲(chǔ)在字典中
        counts[name] = nb_of_matches(encodings, encoding)
    # 檢查所有匹配次數(shù)是否都等于0,如果沒(méi)有任何名稱匹配,則將名稱設(shè)置為"Unknown"
    if all(count == 0 for count in counts.values()):
        name = "Unknown"
    # 否則,獲取匹配次數(shù)最高的名稱
    else:
        name = max(counts, key=counts.get)

    # 將名稱添加到名稱列表中
    names.append(name)

因此,我們首先初始化一個(gè)字典來(lái)跟蹤每個(gè)人的匹配次數(shù)。然后,使用已知編碼的字典,我們調(diào)用nb_of_matches()函數(shù)來(lái)獲取當(dāng)前面部編碼的匹配次數(shù),并將其存儲(chǔ)在計(jì)數(shù)字典中。

接下來(lái),我們使用counts字典來(lái)獲取匹配次數(shù)最多的人的名字。如果沒(méi)有任何人匹配(所有匹配次數(shù)等于0),我們將名稱設(shè)置為“未知”。然后,我們將該名稱添加到名稱列表中。

最后一步是在輸入圖像中的每個(gè)人臉周圍繪制一個(gè)矩形,并在矩形頂部寫下人的名字。

# 使用`face_rects`函數(shù)循環(huán)遍歷輸入圖像中人臉的矩形
for rect, name in zip(face_rects(image), names):
    # 使用`rect`變量獲取每個(gè)人臉的邊界框
    x1, y1, x2, y2 = rect.left(), rect.top(), rect.right(), rect.bottom()
    # 繪制人臉的邊界框以及人名
    cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
    cv2.putText(image, name, (x1, y1 - 10), 
            cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 255, 0), 2)

# 顯示輸出圖像
cv2.imshow("image", image)
cv2.waitKey(0)

我們使用 face_rects() 函數(shù)返回輸入圖像中每個(gè)面的矩形列表。這些矩形由Dlib庫(kù)提供。我們遍歷矩形并獲取每個(gè)面的邊界框。然后,我們?cè)诿繌埬樦車嬕粋€(gè)矩形,并在矩形頂部寫下人的名字。最后,我們使用OpenCV顯示輸出圖像。

現(xiàn)在,是時(shí)候測(cè)試我們的人臉識(shí)別算法了。我已經(jīng)在示例文件夾中添加了一些圖像。以下是我們的人臉識(shí)別算法的輸出示例:

基于dlib的人臉識(shí)別模塊化設(shè)計(jì),AI編程實(shí)戰(zhàn),AI應(yīng)用實(shí)戰(zhàn),opencv,深度學(xué)習(xí),人工智能

?在這個(gè)例子中,我測(cè)試了示例文件夾內(nèi)的一些圖像。正如您所看到的,算法正確識(shí)別了圖像中每個(gè)人的面孔。現(xiàn)在,如果輸入圖像中有多個(gè)人怎么辦?讓我們看一個(gè)例子:

基于dlib的人臉識(shí)別模塊化設(shè)計(jì),AI編程實(shí)戰(zhàn),AI應(yīng)用實(shí)戰(zhàn),opencv,深度學(xué)習(xí),人工智能

正如您所看到的,算法正確識(shí)別了同一圖像中的三張臉。如果某個(gè)人的面孔不在我們的數(shù)據(jù)集中怎么辦?讓我們看一個(gè)例子:

基于dlib的人臉識(shí)別模塊化設(shè)計(jì),AI編程實(shí)戰(zhàn),AI應(yīng)用實(shí)戰(zhàn),opencv,深度學(xué)習(xí),人工智能

?我們的數(shù)據(jù)集不包含右側(cè)人的圖像,但我們的算法足夠聰明,可以將他標(biāo)記為Unknown人。關(guān)于視頻中的人臉識(shí)別,代碼與圖像代碼幾乎相同。唯一的區(qū)別是我們需要循環(huán)播放視頻的幀。

六、總結(jié)

本文介紹了人臉識(shí)別技術(shù)在計(jì)算機(jī)視覺(jué)領(lǐng)域的應(yīng)用和發(fā)展。首先,文章提到了計(jì)算機(jī)視覺(jué)技術(shù)在人工智能中的成熟度和廣泛應(yīng)用,特別是在圖像處理、目標(biāo)檢測(cè)和語(yǔ)義分割等領(lǐng)域的突破。然后,文章指出了公司在人臉識(shí)別領(lǐng)域進(jìn)行自主研發(fā)與應(yīng)用的需求和背景,包括業(yè)務(wù)背景、平臺(tái)架構(gòu)、部署架構(gòu)和功能需求等。接著,文章介紹了如何使用Dlib庫(kù)和深度學(xué)習(xí)來(lái)實(shí)現(xiàn)人臉識(shí)別,并利用預(yù)訓(xùn)練網(wǎng)絡(luò)和OpenCV庫(kù)進(jìn)行圖像處理。最后,文章概述了人臉識(shí)別的定義、應(yīng)用和步驟,包括人臉檢測(cè)、面部對(duì)齊、面部編碼和人臉識(shí)別。文章還提到了基于深度學(xué)習(xí)的人臉識(shí)別算法及其工作原理。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-773166.html

到了這里,關(guān)于基于OpenCV和Dlib的深度學(xué)習(xí)人臉識(shí)別技術(shù)實(shí)踐與應(yīng)用的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包