前言
人臉識(shí)別,是基于人的臉部特征信息進(jìn)行身份識(shí)別的一種生物識(shí)別技術(shù)。用攝像機(jī)或攝像頭采集含有人臉的圖像或視頻流,并自動(dòng)在圖像中檢測(cè)和跟蹤人臉,進(jìn)而對(duì)檢測(cè)到的人臉進(jìn)行臉部識(shí)別的一系列相關(guān)技術(shù),通常也叫做人像識(shí)別、面部識(shí)別。
人臉識(shí)別是機(jī)器學(xué)習(xí)熱門領(lǐng)域之一,在 github 上有很多項(xiàng)目實(shí)現(xiàn)了各種人臉識(shí)別功能,以下面6個(gè)測(cè)試軟件使用
- https://github.com/ageitgey/face_recognition
- https://github.com/PaddlePaddle/PaddleDetection
- https://github.com/serengil/deepface
- https://github.com/deepinsight/insightface
- https://github.com/seetaface/SeetaFaceEngine
- https://github.com/TadasBaltrusaitis/OpenFace
一、face_recognition
face_recognition 是世界上最簡(jiǎn)潔的人臉識(shí)別庫(kù),可以使用 Python 和命令行工具提取、識(shí)別、操作人臉。
face_recognition 項(xiàng)目的人臉識(shí)別是基于業(yè)內(nèi)領(lǐng)先的C++開源庫(kù) dlib中的深度學(xué)習(xí)模型,用Labeled Faces in the Wild人臉數(shù)據(jù)集進(jìn)行測(cè)試,有高達(dá)99.38%的準(zhǔn)確率。但對(duì)小孩和亞洲人臉的識(shí)別準(zhǔn)確率尚待提升。
Labeled Faces in the Wild是美國(guó)麻省大學(xué)安姆斯特分校(University of Massachusetts Amherst)制作的人臉數(shù)據(jù)集,該數(shù)據(jù)集包含了從網(wǎng)絡(luò)收集的13,000多張面部圖像。
1.1 安裝
pip install face_recognition
1.2 檢測(cè)人臉位置
可以使用命令行命令 face_detection
來(lái)識(shí)別人臉,下面以胡歌照片為例,來(lái)演示具體使用
face_detection faces/huge.jpg
# 輸出:faces/huge.jpg,101,221,173,149
使用命令行只顯示了位置的具體坐標(biāo),不能準(zhǔn)確的用肉眼查看,可以使用 python 來(lái)標(biāo)記
import face_recognition
from PIL import Image, ImageDraw
image = face_recognition.load_image_file("huge.jpg")
face_locations = face_recognition.face_locations(image)
pil_image = Image.fromarray(image)
draw = ImageDraw.Draw(pil_image)
for (top, right, bottom, left) in face_locations:
draw.rectangle(((left, top), (right, bottom)), outline=(0, 0, 255))
del draw
pil_image.save("huge_face.jpg")
多張人臉檢測(cè)
原始照片
標(biāo)記人臉位置照片
1.3 識(shí)別人臉
face_recognition 不僅支持識(shí)別人臉?biāo)谡掌恢?,更能識(shí)別人臉?biāo)淼娜?/p>
將 [‘劉詩(shī)詩(shī).jpg’, ‘唐嫣.jpg’, ‘楊冪.jpg’, ‘胡歌.jpg’, ‘霍建華.jpg’, ‘黃志瑋.jpg’] 照片放在一個(gè)文件夾下,例如我的是 known 文件夾下,再將仙劍三海報(bào) all.jpg 放在和腳本同一目錄下,開始識(shí)別人臉
測(cè)試的6張照片都是從網(wǎng)上找的,鏈接如下
- 劉詩(shī)詩(shī)
- 唐嫣
- 楊冪
- 胡歌
- 霍建華
- 黃志瑋
import face_recognition
import os
from PIL import Image, ImageDraw, ImageFont
import numpy as np
font = ImageFont.truetype("C:\\Windows\\Fonts\\simsun.ttc", 40, encoding="utf-8")
known_path = "../known"
known_face_names = []
known_face_encodings = []
images = os.listdir(known_path)
print(images)
for image in images:
if image.endswith('jpg'):
known_face_names.append(os.path.basename(image).split(".")[0])
image_data = face_recognition.load_image_file(os.path.join(known_path, image))
known_face_encodings.append(face_recognition.face_encodings(image_data)[0])
all_face_path = "all.jpg"
all_image = face_recognition.load_image_file(all_face_path)
all_face_locations = face_recognition.face_locations(all_image)
all_face_encodings = face_recognition.face_encodings(all_image, all_face_locations)
pil_image = Image.fromarray(all_image)
draw = ImageDraw.Draw(pil_image)
for (top, right, bottom, left), face_encoding in zip(all_face_locations, all_face_encodings):
matches = face_recognition.compare_faces(known_face_encodings, face_encoding, tolerance=0.5)
name = "未知"
face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
best_match_index = np.argmin(face_distances)
if matches[best_match_index]:
name = known_face_names[best_match_index]
draw.rectangle(((left, top), (right, bottom)), outline=(0, 0, 255))
text_width, text_height = draw.textsize(name, font=font)
draw.text((left + 6, bottom - text_height - 5), name, fill=(255, 255, 255, 255), font=font)
del draw
pil_image.save("all_faces.jpg")
二、PaddleDetection
PaddleDetection為基于飛槳 PaddlePaddle 的端到端目標(biāo)檢測(cè)套件,內(nèi)置30+模型算法及250+預(yù)訓(xùn)練模型,覆蓋目標(biāo)檢測(cè)、實(shí)例分割、跟蹤、關(guān)鍵點(diǎn)檢測(cè)等方向,其中包括服務(wù)器端和移動(dòng)端高精度、輕量級(jí)產(chǎn)業(yè)級(jí)SOTA模型、冠軍方案和學(xué)術(shù)前沿算法,并提供配置化的網(wǎng)絡(luò)模塊組件、十余種數(shù)據(jù)增強(qiáng)策略和損失函數(shù)等高階優(yōu)化支持和多種部署方案,在打通數(shù)據(jù)處理、模型開發(fā)、訓(xùn)練、壓縮、部署全流程的基礎(chǔ)上,提供豐富的案例及教程,加速算法產(chǎn)業(yè)落地應(yīng)用。
2.1 安裝
下載源碼,根據(jù)readme安裝,注意下載源碼版本需要根 paddlepaddle 版本對(duì)應(yīng)。
安裝過(guò)程中,安裝cython bbox 失敗,解決方法:windows下安裝cython-bbox失敗。下載資源:cython+bbox-0.1.3
2.2 運(yùn)行
PaddleDetection 內(nèi)置一個(gè)高效、高速的人臉檢測(cè)解決方案,包括最先進(jìn)的模型和經(jīng)典模型
python tools/infer.py -c configs/face_detection/blazeface_1000e.yml -o weights=https://paddledet.bj.bcebos.com/models/blazeface_1000e.pdparams --infer_img=C:\Users\supre\Desktop\faces\all.jpg --output_dir=infer_output/ --draw_threshold=0.6
三、DeepFace
Deepface 是一個(gè)輕量級(jí)的人臉面部識(shí)別和面部屬性分析(年齡、性別、情感和種族)框架。它是一個(gè)混合的人臉識(shí)別框架,包裝了最先進(jìn)的模型:VGG-Face
, Google FaceNet
, OpenFace
, Facebook DeepFace
, DeepID
, ArcFace
, Dlib
and SFace
.
實(shí)驗(yàn)表明,人類在面部識(shí)別任務(wù)上的準(zhǔn)確率為97.53%,而這些模型已經(jīng)達(dá)到并通過(guò)了這個(gè)準(zhǔn)確率水平。
3.1 安裝
pip install deepface
3.2 檢測(cè)人臉位置
from deepface import DeepFace
from deepface.detectors import FaceDetector
import cv2
img_path = "C:\\Users\\supre\\Desktop\\faces\\all.jpg"
detector_name = "opencv"
img = cv2.imread(img_path)
detector = FaceDetector.build_model(detector_name) #set opencv, ssd, dlib, mtcnn or retinaface
obj = FaceDetector.detect_faces(detector, detector_name, img)
faces = []
regions = []
for o in obj:
face, region = o
faces.append(face)
regions.append(region)
for (x, y, w, h) in regions:
cv2.rectangle(img, (x, y), (x+w, y + h), (0, 0, 255), 2)
cv2.imwrite("all_deep_face.jpg", img)
cv2.imshow('faces', img)
cv2.waitKey(0)
print("there are ",len(obj)," faces")
3.3 人臉屬性分析
運(yùn)行下面代碼會(huì)從 github 下載訓(xùn)練好的模型文件,如果下載太慢可手動(dòng)下載:https://github.com/serengil/deepface_models/releases/
from deepface import DeepFace
obj = DeepFace.analyze(img_path = "faces/huge.jpg",
actions = ['age', 'gender', 'race', 'emotion']
)
print(obj)
輸出:
{'age': 31, 'region': {'x': 141, 'y': 90, 'w': 92, 'h': 92}, 'gender': 'Man', 'race': {'asian': 86.62416855240873, 'indian': 0.2717677898641103, 'black': 0.025535856615095234, 'white': 11.001530200334203, 'middle eastern': 0.36970814565319693, 'latino hispanic': 1.707288910883004}, 'dominant_race': 'asian', 'emotion': {'angry': 4.005255788877951, 'disgust': 1.1836746688898558e-05, 'fear': 91.75890038960578, 'happy': 1.023393651002267, 'sad': 0.9277909615809299, 'surprise': 2.081933555420253, 'neutral': 0.20271948350039026}, 'dominant_emotion': 'fear'}
四、insightface
insightface 是一個(gè)開源的二維和三維深度面部分析工具箱,主要基于 PyTorch 和 MXNet。實(shí)現(xiàn)了很多人臉識(shí)別、人臉檢測(cè)和人臉對(duì)齊算法,為訓(xùn)練和部署進(jìn)行了優(yōu)化。
4.1 安裝
pip install insightface
4.2 運(yùn)行
運(yùn)行出現(xiàn)報(bào)錯(cuò):TypeError: __init__() got an unexpected keyword argument 'provider_options'
查找資料Error “got an unexpected keyword argument ‘provider_options’” when running quick example of insightface得知:是由于onnxruntime 版本過(guò)低導(dǎo)致,更新版本
pip install onnxruntime==1.6.0
import cv2
import numpy as np
import insightface
from insightface.app import FaceAnalysis
from insightface.data import get_image as ins_get_image
app = FaceAnalysis(providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])
app.prepare(ctx_id=0, det_size=(640, 640))
img = ins_get_image('C:\\Users\\supre\\Desktop\\faces\\all')
faces = app.get(img)
rimg = app.draw_on(img, faces)
cv2.imwrite("./all_output.jpg", rimg)
五、SeetaFaceEngine
? SeetaFaceEngine 是一個(gè)開源的C++人臉識(shí)別引擎,由中科院計(jì)算所山世光研究員帶領(lǐng)的人臉識(shí)別研究組研發(fā)。代碼基于C++實(shí)現(xiàn),且不依賴于任何第三方的庫(kù)函數(shù),開源協(xié)議為BSD-2,可供學(xué)術(shù)界和工業(yè)界免費(fèi)使用它可以運(yùn)行在CPU上。它包含人臉檢測(cè)、人臉對(duì)準(zhǔn)和人臉識(shí)別三個(gè)關(guān)鍵部分,是構(gòu)建真實(shí)人臉識(shí)別應(yīng)用系統(tǒng)的必要和充分條件
5.1 編譯
SeetaFaceEngine 包含三部分,所以需要使用 cmake 編譯三次,編譯方法見(jiàn) readme
5.2 人臉檢測(cè)
#include <cstdint>
#include <fstream>
#include <iostream>
#include <string>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "face_detection.h"
using namespace std;
int main(int argc, char** argv) {
const char* img_path = "C:\\Users\\supre\\Desktop\\faces\\all.jpg";
seeta::FaceDetection detector("E:\\tmp\\SeetaFaceEngine-master\\FaceDetection\\model\\seeta_fd_frontal_v1.0.bin");
detector.SetMinFaceSize(40);
detector.SetScoreThresh(2.f);
detector.SetImagePyramidScaleFactor(0.8f);
detector.SetWindowStep(4, 4);
cv::Mat img = cv::imread(img_path, cv::IMREAD_UNCHANGED);
cv::Mat img_gray;
if (img.channels() != 1)
cv::cvtColor(img, img_gray, cv::COLOR_BGR2GRAY);
else
img_gray = img;
seeta::ImageData img_data;
img_data.data = img_gray.data;
img_data.width = img_gray.cols;
img_data.height = img_gray.rows;
img_data.num_channels = 1;
long t0 = cv::getTickCount();
std::vector<seeta::FaceInfo> faces = detector.Detect(img_data);
long t1 = cv::getTickCount();
double secs = (t1 - t0)/cv::getTickFrequency();
cout << "Detections takes " << secs << " seconds " << endl;
cout << "Image size (wxh): " << img_data.width << "x"
<< img_data.height << endl;
cv::Rect face_rect;
int32_t num_face = static_cast<int32_t>(faces.size());
for (int32_t i = 0; i < num_face; i++) {
face_rect.x = faces[i].bbox.x;
face_rect.y = faces[i].bbox.y;
face_rect.width = faces[i].bbox.width;
face_rect.height = faces[i].bbox.height;
cv::rectangle(img, face_rect, CV_RGB(0, 0, 255), 4, 8, 0);
}
cv::namedWindow("Test", cv::WINDOW_AUTOSIZE);
cv::imwrite("all_1.jpg", img);
cv::imshow("Test", img);
cv::waitKey(0);
cv::destroyAllWindows();
}
5.3 face alignment
face alignment 指 通過(guò)一定量的訓(xùn)練集(人臉圖像和每個(gè)圖像上相對(duì)應(yīng)的多個(gè)landmarks),來(lái)得到一個(gè)model,使得該model再輸入了一張任意姿態(tài)下的人臉照片后,能夠?qū)υ撜掌械年P(guān)鍵點(diǎn)進(jìn)行標(biāo)記.
#include <cstdint>
#include <fstream>
#include <iostream>
#include <string>
#include "cv.h"
#include "highgui.h"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "face_detection.h"
#include "face_alignment.h"
int main(int argc, char** argv)
{
// Initialize face detection model
std::string MODEL_DIR = "E:\\tmp\\SeetaFaceEngine-master\\FaceAlignment\\model\\";
std::string DATA_DIR = "E:\\tmp\\SeetaFaceEngine-master\\FaceAlignment\\data\\";
std::string IMG_PATH = DATA_DIR + "all.jpg";
int pts_num = 5;
seeta::FaceDetection detector("E:\\tmp\\SeetaFaceEngine-master\\FaceDetection\\model\\seeta_fd_frontal_v1.0.bin");
detector.SetMinFaceSize(40);
detector.SetScoreThresh(2.f);
detector.SetImagePyramidScaleFactor(0.8f);
detector.SetWindowStep(4, 4);
// Initialize face alignment model
seeta::FaceAlignment point_detector((MODEL_DIR + "seeta_fa_v1.1.bin").c_str());
//load image
cv::Mat img = cv::imread(IMG_PATH, cv::IMREAD_UNCHANGED);
cv::Mat img_gray;
if (img.channels() != 1)
cv::cvtColor(img, img_gray, cv::COLOR_BGR2GRAY);
else
img_gray = img;
seeta::ImageData img_data;
img_data.data = img_gray.data;
img_data.width = img_gray.cols;
img_data.height = img_gray.rows;
img_data.num_channels = 1;
std::vector<seeta::FaceInfo> faces = detector.Detect(img_data);
int32_t face_num = static_cast<int32_t>(faces.size());
std::cout<<"face_num:"<<face_num;
if (face_num == 0)
{
return 0;
}
cv::Rect face_rect;
for (int32_t i = 0; i < face_num; i++) {
face_rect.x = faces[i].bbox.x;
face_rect.y = faces[i].bbox.y;
face_rect.width = faces[i].bbox.width;
face_rect.height = faces[i].bbox.height;
cv::rectangle(img, face_rect, CV_RGB(0, 0, 255), 4, 8, 0);
// Detect 5 facial landmarks
seeta::FacialLandmark points[5];
point_detector.PointDetectLandmarks(img_data, faces[i], points);
for (int i = 0; i< pts_num; i++)
{
cv::circle(img, cvPoint(points[i].x, points[i].y), 2, CV_RGB(0, 255, 0), CV_FILLED);
}
}
cv::namedWindow("Test", cv::WINDOW_AUTOSIZE);
cv::imwrite("test.jpg", img);
cv::imshow("Test", img);
cv::waitKey(0);
cv::destroyAllWindows();
return 0;
}
5.4 人臉檢測(cè)相似率
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "face_identification.h"
#include "recognizer.h"
#include "face_detection.h"
#include "face_alignment.h"
#include "math_functions.h"
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
using namespace seeta;
using namespace std;
std::string DATA_DIR = "E:\\tmp\\SeetaFaceEngine-master\\FaceIdentification\\data\\";
std::string MODEL_DIR = "E:\\tmp\\SeetaFaceEngine-master\\FaceIdentification\\model\\";
int main(int argc, char* argv[]) {
// Initialize face detection model
seeta::FaceDetection detector("E:\\tmp\\SeetaFaceEngine-master\\FaceDetection\\model\\seeta_fd_frontal_v1.0.bin");
detector.SetMinFaceSize(40);
detector.SetScoreThresh(2.f);
detector.SetImagePyramidScaleFactor(0.8f);
detector.SetWindowStep(4, 4);
// Initialize face alignment model
seeta::FaceAlignment point_detector("E:\\tmp\\SeetaFaceEngine-master\\FaceAlignment\\model\\seeta_fa_v1.1.bin");
// Initialize face Identification model
FaceIdentification face_recognizer((MODEL_DIR + "seeta_fr_v1.0.bin").c_str());
std::string test_dir = DATA_DIR + "test_face_recognizer/";
//load image
cv::Mat gallery_img_color = cv::imread(test_dir + "images/liushishi_1.jpg", 1);
cv::Mat gallery_img_gray;
cv::cvtColor(gallery_img_color, gallery_img_gray, CV_BGR2GRAY);
cv::Mat probe_img_color = cv::imread(test_dir + "images/liushishi_2.jpg", 1);
cv::Mat probe_img_gray;
cv::cvtColor(probe_img_color, probe_img_gray, CV_BGR2GRAY);
ImageData gallery_img_data_color(gallery_img_color.cols, gallery_img_color.rows, gallery_img_color.channels());
gallery_img_data_color.data = gallery_img_color.data;
ImageData gallery_img_data_gray(gallery_img_gray.cols, gallery_img_gray.rows, gallery_img_gray.channels());
gallery_img_data_gray.data = gallery_img_gray.data;
ImageData probe_img_data_color(probe_img_color.cols, probe_img_color.rows, probe_img_color.channels());
probe_img_data_color.data = probe_img_color.data;
ImageData probe_img_data_gray(probe_img_gray.cols, probe_img_gray.rows, probe_img_gray.channels());
probe_img_data_gray.data = probe_img_gray.data;
// Detect faces
std::vector<seeta::FaceInfo> gallery_faces = detector.Detect(gallery_img_data_gray);
int32_t gallery_face_num = static_cast<int32_t>(gallery_faces.size());
std::vector<seeta::FaceInfo> probe_faces = detector.Detect(probe_img_data_gray);
int32_t probe_face_num = static_cast<int32_t>(probe_faces.size());
if (gallery_face_num == 0 || probe_face_num==0)
{
std::cout << "Faces are not detected.";
return 0;
}
// Detect 5 facial landmarks
seeta::FacialLandmark gallery_points[5];
point_detector.PointDetectLandmarks(gallery_img_data_gray, gallery_faces[0], gallery_points);
seeta::FacialLandmark probe_points[5];
point_detector.PointDetectLandmarks(probe_img_data_gray, probe_faces[0], probe_points);
for (int i = 0; i<5; i++)
{
cv::circle(gallery_img_color, cv::Point(gallery_points[i].x, gallery_points[i].y), 2,
CV_RGB(0, 255, 0));
cv::circle(probe_img_color, cv::Point(probe_points[i].x, probe_points[i].y), 2,
CV_RGB(0, 255, 0));
}
cv::imwrite("gallery_point_result.jpg", gallery_img_color);
cv::imwrite("probe_point_result.jpg", probe_img_color);
// Extract face identity feature
float gallery_fea[2048];
float probe_fea[2048];
face_recognizer.ExtractFeatureWithCrop(gallery_img_data_color, gallery_points, gallery_fea);
face_recognizer.ExtractFeatureWithCrop(probe_img_data_color, probe_points, probe_fea);
// Caculate similarity of two faces
float sim = face_recognizer.CalcSimilarity(gallery_fea, probe_fea);
std::cout << "相似率:"<<sim <<endl;
return 0;
}
使用兩張劉詩(shī)詩(shī)照片對(duì)比:相似率為 0.679915
六、OpenFace
OpenFace, 一個(gè)旨在為計(jì)算機(jī)視覺(jué)和機(jī)器學(xué)習(xí)研究人員、情感計(jì)算社區(qū)和有興趣構(gòu)建基于面部行為分析的交互式應(yīng)用程序的人使用的工具。OpenFace是第一個(gè)能夠進(jìn)行面部地標(biāo)檢測(cè)、頭部姿態(tài)估計(jì)、面部動(dòng)作單元識(shí)別和眼睛-注視估計(jì)的工具包,它具有可用的源代碼,可用于運(yùn)行和訓(xùn)練模型。代表 OpenFace 核心的計(jì)算機(jī)視覺(jué)算法在上述所有任務(wù)中都展示了最先進(jìn)的結(jié)果。此外,我們的工具能夠?qū)崟r(shí)性能,并能夠運(yùn)行在非專業(yè)的硬件上, 例如一個(gè)簡(jiǎn)單的網(wǎng)絡(luò)攝像頭。
6.1 安裝
- window
- 32位:https://github.com/TadasBaltrusaitis/OpenFace/releases/download/OpenFace_2.2.0/OpenFace_2.2.0_win_x86.zip
- 64位:https://github.com/TadasBaltrusaitis/OpenFace/releases/download/OpenFace_2.2.0/OpenFace_2.2.0_win_x64.zip
- Linux:https://github.com/TadasBaltrusaitis/OpenFace/wiki/Unix-Installation
- Mac:https://github.com/TadasBaltrusaitis/OpenFace/wiki/Mac-Installation
6.2 運(yùn)行
OpenFace windows 版安裝完成后還需要下載模型數(shù)據(jù):https://github.com/TadasBaltrusaitis/OpenFace/wiki/Model-download,放在安裝目錄\model\patch_experts下面。
OpenFace 還提供了一些工具用于在命令行實(shí)現(xiàn)人臉識(shí)別
-
FaceLandmarkImg 從照片中識(shí)別人臉,還是以仙劍3海報(bào)做例子放在samples下面,再新建輸出文件夾out_dir,開始識(shí)別人臉
FaceLandmarkImg.exe -f "samples/all.jpg" -out_dir "out_dir"
輸出結(jié)果為:
-
FaceLandmarkVid 從視頻中識(shí)別人臉
-
FaceLandmarkVidMulti 從多個(gè)視頻中識(shí)別人臉文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-443316.html
-
FeatureExtraction 用于包含單個(gè)人臉的分析文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-443316.html
參考
- windows下安裝cython-bbox失敗
到了這里,關(guān)于6款人臉識(shí)別開源軟件的簡(jiǎn)單使用的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!