跳转到内容

人脸识别算法执行指南

1. 人脸识别概述

人脸识别是一种基于人脸特征信息进行身份确认的生物识别技术。它通过摄像头或摄像头模块获取包含人脸的图像或视频流,自动检测并跟踪图像中的人脸,然后对检测到的人脸进行识别。该技术通常也称为人员识别或人脸认证。

人脸识别系统主要由人脸图像采集与检测、人脸图像预处理、人脸特征提取、比对与识别四个部分组成。本示例也包含这些处理流程。

本人脸识别算法在数据集上的性能如下。

人脸识别算法performance
LFW99.80%
IJB-C(E4)97.12%

face recognition ijb roc curve

图 1-1

CSUN RV1126B 开发板上的执行效率如下。

算法类型执行效率
face_detect24ms
face_recognition12.4ms

2. 快速开始

2.1 开发环境准备

首次阅读本文档时,请参考《入门指南/开发编译环境准备与更新》,并按照相关步骤部署编译环境。在 PC 侧 Ubuntu 系统中执行 run 脚本,进入 Docker 开发环境。

Terminal window
cd ~/linuxshare/work/rv1126b/jp/embedded/images/develop_environment
./run.sh 2204

docker development environment startup

图 2-1

2.2 源代码下载

在 Docker 开发环境中,创建用于保存源代码仓库的管理目录,并使用 git 工具克隆远程仓库。请下载完整仓库。

Terminal window
cd /opt/linuxshare/work/rv1126b/jp/AI/demo/ai-algorithm
git clone https://github.com/csunltd/rv1126b-ai-toolkit.git

2.3 模型部署

人脸识别示例同时使用人脸检测算法模型和人脸识别算法模型。下载后,请将模型文件复制到 Release/ 目录。

face recognition model release files

图 2-2

2.4 示例构建

进入示例所在目录并执行构建。由于依赖库位于开发板侧,交叉编译过程中需要保持 /mnt 挂载。

Terminal window
cd rv1126b-ai-toolkit/Demos/algorithm-face_recognition
./build.sh cpres
Terminal window
sudo mount -t nfs -o vers=3,proto=tcp,mountproto=tcp,nolock,retrans=5,timeo=5 192.168.10.85:/ /mnt

face recognition build terminal output

图 2-3

2.5 示例执行与结果

示例以两张人脸图像作为输入,并输出 similarity。similarity 大于 0.4 时判断为同一人,值越大可能性越高。similarity 的取值范围为 -1 到 1。

Terminal window
cp Release/* /mnt/userdata/Demo/algorithm-face_recognition/
cd /userdata/Demo/algorithm-face_recognition/
./test-face-recognition 1.jpg 2.jpg

face recognition board run output

图 2-4

3. 人脸检测 API 说明

3.1 引用方法

如果需要在本地项目中直接调用 EASY EAI API 库,请添加以下头文件目录、库文件目录和链接参数。

项目说明
头文件目录easyeai-api/algorithm/face_detect
库文件目录easyeai-api/algorithm/face_detect
库链接参数-lface_detect

3.2 人脸检测初始化函数

函数原型如下。

int face_detect_init(rknn_context *ctx, const char *path);
项目说明
函数名face_detect_init()
头文件face_detect.h
输入参数ctx: rknn_context handle
输入参数path: algorithm model path
返回值成功时返回值:0 / 失败时返回值:-1
说明

3.3 人脸检测执行函数

函数原型如下。

int face_detect_run(rknn_context ctx, cv::Mat &input_image, std::vector<det> &result);
项目说明
函数名face_detect_run()
头文件face_detect.h
输入参数ctx: rknn_context handle
输入参数input_image: cv::Mat input image
输出参数result: face detection result
返回值成功时返回值:0 / 失败时返回值:-1
说明

3.4 人脸检测释放函数

函数原型如下。

int face_detect_release(rknn_context ctx);
项目说明
函数名face_detect_release()
头文件face_detect.h
输入参数ctx: rknn_context handle
返回值成功时返回值:0 / 失败时返回值:-1
说明

4. 人脸标准化 API 说明

4.1 引用方法

如果需要在本地项目中直接调用 EASY EAI API 库,请添加以下头文件目录、库文件目录和链接参数。

项目说明
头文件目录easyeai-api/algorithm/face_recognition
库文件目录easyeai-api/algorithm/face_recognition
库链接参数-lface_recognition

4.2 人脸标准化函数

函数原型如下。

cv::Mat face_alignment(cv::Mat img, cv::Point2f *points);
项目说明
函数名face_alignment()
头文件face_alignment.h
输入参数img: OpenCV input image
输入参数points: face landmark coordinates
说明接收输入图像和人脸关键点坐标,并输出标准化后的人脸图像。

5. 人脸识别 API 说明

5.1 引用方法

如果需要在本地项目中直接调用 EASY EAI API 库,请添加以下头文件目录、库文件目录和链接参数。

项目说明
头文件目录easyeai-api/algorithm/face_recognition
库文件目录easyeai-api/algorithm/face_recognition
库链接参数-lface_recognition

5.2 人脸识别初始化函数

函数原型如下。

int face_recognition_init(rknn_context *ctx, const char *path);
项目说明
函数名face_recognition_init()
头文件face_recognition.h
输入参数ctx: rknn_context handle
输入参数path: algorithm model path
返回值成功时返回值:0 / 失败时返回值:-1
说明

5.3 人脸识别执行函数

函数原型如下。

int face_recognition_run(rknn_context ctx, cv::Mat *face_image, float (*feature)[512]);
项目说明
函数名face_recognition_run()
头文件face_recognition.h
输入参数ctx: rknn_context handle
输入参数face_image: cv::Mat input image
输出参数feature: 512-dimensional face feature vector
返回值成功时返回值:0 / 失败时返回值:-1
说明

5.4 人脸识别特征比对函数

函数原型如下。

float face_recognition_comparison(float *feature_1, float *feature_2, int output_len);
项目说明
函数名face_recognition_comparison()
头文件face_recognition.h
输入参数feature_1: face feature vector 1
输入参数feature_2: face feature vector 2
输入参数output_len: feature length
说明通常,相似度大于 0.4 时可以判断为同一人。

5.5 人脸识别释放函数

函数原型如下。

int face_recognition_release(rknn_context ctx);
项目说明
函数名face_recognition_release()
头文件face_recognition.h
输入参数ctx: rknn_context handle
返回值成功时返回值:0 / 失败时返回值:-1
说明

6. 人脸识别算法示例

示例目录为 Demos/algorithm-face_recognition/test-face-recognition.cpp。操作流程如下。

face recognition sample flow

图 6-1

参考示例如下。

#include <opencv2/opencv.hpp>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include "face_detect.h"
#include "face_alignment.h"
#include "face_recognition.h"
using namespace cv;
int main(int argc, char **argv)
{
rknn_context detect_ctx, recognition_ctx;
std::vector<det> result1, result2;
int ret;
struct timeval start;
struct timeval end;
float time_use=0;
if( argc != 3)
{
printf("./face_recognition_demo xxx.jpg xxx.jpg\n");
return -1;
}
cv::Mat src_1, src_2;
src_1 = cv::imread(argv[1], 1);
src_2 = cv::imread(argv[2], 1);
/* 顔検出を初期化します */
printf("face detect init!\n");
ret = face_detect_init(&detect_ctx, "./face_detect.model");
if( ret < 0)
{
printf("face_detect_init fail! ret=%d\n", ret);
return -1;
}
/* 顔認識を初期化します */
printf("face recognition init!\n");
ret = face_recognition_init(&recognition_ctx, "./face_recognition.model");
if( ret < 0)
{
printf("face_recognition fail! ret=%d\n", ret);
return -1;
}
/* 顔検出を実行します */
face_detect_run(detect_ctx, src_1, result1);
face_detect_run(detect_ctx, src_2, result2);
Point2f points1[5], points2[5];
for (int j = 0; j < (int)result1[0].landmarks.size(); ++j)
{
points1[j].x = (int)result1[0].landmarks[j].x;
points1[j].y = (int)result1[0].landmarks[j].y;
}
for (int j = 0; j < (int)result2[0].landmarks.size(); ++j)
{
points2[j].x = (int)result2[0].landmarks[j].x;
points2[j].y = (int)result2[0].landmarks[j].y;
}
Mat face_algin_1, face_algin_2;
face_algin_1 = face_alignment(src_1, points1);
face_algin_2 = face_alignment(src_2, points2);
/* 顔認識を実行します */
float feature_1[512], feature_2[512];
gettimeofday(&start,NULL);
face_recognition_run(recognition_ctx, &face_algin_1, &feature_1);
gettimeofday(&end,NULL);
time_use=(end.tv_sec-start.tv_sec)*1000000+(end.tv_usec-start.tv_usec);//マイクロ秒
printf("time_use is %f\n",time_use/1000);
face_recognition_run(recognition_ctx, &face_algin_2, &feature_2);
float similarity;
similarity = face_recognition_comparison(feature_1, feature_2, 512);
printf("similarity:%f\n", similarity);
/* 顔検出を解放します */
face_detect_release(detect_ctx);
/* 顔認識を解放します */
face_recognition_release(recognition_ctx);
return 0;
}