人脸识别算法执行指南
1. 人脸识别概述
人脸识别是一种基于人脸特征信息进行身份确认的生物识别技术。它通过摄像头或摄像头模块获取包含人脸的图像或视频流,自动检测并跟踪图像中的人脸,然后对检测到的人脸进行识别。该技术通常也称为人员识别或人脸认证。
人脸识别系统主要由人脸图像采集与检测、人脸图像预处理、人脸特征提取、比对与识别四个部分组成。本示例也包含这些处理流程。
本人脸识别算法在数据集上的性能如下。
| 人脸识别算法 | performance |
|---|---|
| LFW | 99.80% |
| IJB-C(E4) | 97.12% |

图 1-1
CSUN RV1126B 开发板上的执行效率如下。
| 算法类型 | 执行效率 |
|---|---|
| face_detect | 24ms |
| face_recognition | 12.4ms |
2. 快速开始
2.1 开发环境准备
首次阅读本文档时,请参考《入门指南/开发编译环境准备与更新》,并按照相关步骤部署编译环境。在 PC 侧 Ubuntu 系统中执行 run 脚本,进入 Docker 开发环境。
cd ~/linuxshare/work/rv1126b/jp/embedded/images/develop_environment./run.sh 2204
图 2-1
2.2 源代码下载
在 Docker 开发环境中,创建用于保存源代码仓库的管理目录,并使用 git 工具克隆远程仓库。请下载完整仓库。
cd /opt/linuxshare/work/rv1126b/jp/AI/demo/ai-algorithmgit clone https://github.com/csunltd/rv1126b-ai-toolkit.git2.3 模型部署
人脸识别示例同时使用人脸检测算法模型和人脸识别算法模型。下载后,请将模型文件复制到 Release/ 目录。
- https://dl.dragonwake.com/download/rv1126b/AI/demo/01_face-detect.zip
- https://dl.dragonwake.com/download/rv1126b/AI/demo/02_face_recognition.zip

图 2-2
2.4 示例构建
进入示例所在目录并执行构建。由于依赖库位于开发板侧,交叉编译过程中需要保持 /mnt 挂载。
cd rv1126b-ai-toolkit/Demos/algorithm-face_recognition./build.sh cpressudo mount -t nfs -o vers=3,proto=tcp,mountproto=tcp,nolock,retrans=5,timeo=5 192.168.10.85:/ /mnt
图 2-3
2.5 示例执行与结果
示例以两张人脸图像作为输入,并输出 similarity。similarity 大于 0.4 时判断为同一人,值越大可能性越高。similarity 的取值范围为 -1 到 1。
cp Release/* /mnt/userdata/Demo/algorithm-face_recognition/cd /userdata/Demo/algorithm-face_recognition/./test-face-recognition 1.jpg 2.jpg
图 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。操作流程如下。

图 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;}