人脸识别组件
简介
ACOMP FD (Face Detection) 是 ARCS SDK 的人脸识别组件,提供基于图像流的人脸检测、对齐、活体检测和特征提取功能。该组件支持多种图像格式输入,提供灵活的参数配置和事件回调机制。
主要特性
完整人脸识别流程:支持人脸检测、对齐、活体检测、特征提取和特征比对
多格式图像输入:支持 YUYV422、RGB565、BGR888 等多种图像格式,最大支持640*480分辨率
活体检测:支持活体检测功能,可配置活体检测阈值
人脸特征管理:支持人脸特征导入和比对,最多支持 10 个注册人脸
事件回调机制:支持人脸识别结果、错误事件等多种事件通知
图像流管理:提供完整的图像流通道管理和缓冲区操作接口
状态管理:支持初始化、就绪、启动、停止等完整的生命周期管理
跨核通信:基于 IPC 机制实现图像流的跨核传输
人脸识别基本流程
人脸识别基本流程如下图所示,实际根据业务需求,流程可能会有所不同:
组件架构
ACOMP FD 组件采用双核异构架构,CP 核(应用核)通过 ACOMP IPC 框架与 AP 核(算法核)进行通信,实现人脸识别功能。
┌─────────────────────────────────────────────────────────────────────┐
│ CP 核 (Application Core) │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ 用户应用层 │ │
│ │ ┌────────────────────────────────────────────────────────┐ │ │
│ │ │ • 人脸识别事件回调处理 (检测结果/特征/活体) │ │ │
│ │ │ • 图像数据采集 (摄像头/图像文件) │ │ │
│ │ │ • 人脸特征管理 (注册/比对) │ │ │
│ │ └────────────────────┬───────────────────────────────────┘ │ │
│ └───────────────────────┼──────────────────────────────────────┘ │
│ │ │
│ ┌───────────────────────▼──────────────────────────────────────┐ │
│ │ ACOMP FD 组件 (CP 侧) │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ 生命周期管理 │ │ 事件回调管理 │ │ 参数配置接口 │ │ │
│ │ │ init/prepare │ │ add_callback │ │ params_set/ │ │ │
│ │ │ start/stop │ │ remove_cb │ │ live_detect │ │ │
│ │ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ │
│ │ │ │ │ │ │
│ │ ┌──────▼─────────────────▼─────────────────▼───────┐ │ │
│ │ │ 图像流管理 (Stream API) │ │ │
│ │ │ • M2R 流: 图像输入 (camera → 算法) │ │ │
│ │ │ • tx_alloc/submit │ │ │
│ │ └──────────────────────┬───────────────────────────┘ │ │
│ └─────────────────────────┼──────────────────────────────────┘ │
│ │ │
│ ┌─────────────────────────▼─────────────────────────────────────┐ │
│ │ ACOMP IPC 层 (CP 侧) │ │
│ │ • IPC 消息封装 (NEW/FREE/CONTROL/NOTIFY) │ │
│ │ • 设备查询和管理 │ │
│ │ • 同步/异步命令处理 │ │
│ └─────────────────────────┬─────────────────────────────────────┘ │
└────────────────────────────┼────────────────────────────────────────┘
│
│ IC Message (IPC 消息通道)
│
┌────────────────────────────▼────────────────────────────────────────┐
│ AP 核 (Algorithm Core) │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ ACOMP Framework (AP 侧) │ │
│ │ │ │
│ │ • 接收 CP 核的 IPC 命令 (prepare/start/stop/control) │ │
│ │ • 处理图像流数据 (M2R 接收) │ │
│ │ • 执行人脸识别算法引擎 │ │
│ │ • 推送识别结果到 CP 核 (检测框/特征/活体) │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 人脸识别算法引擎 (FD Engine) │ │
│ │ │ │
│ │ • 人脸检测 (Face Detection) │ │
│ │ • 人脸对齐 (Face Alignment) - 68个关键点 │ │
│ │ • 活体检测 (Liveness Detection) │ │
│ │ • 特征提取 (Feature Extraction) - 384维特征 │ │
│ │ • 特征比对 (Feature Comparison) │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────┐
│ 共享内存 (Shared Mem) │
│ ┌────────────────────┐ │
│ │ VirtQueue 环形缓冲 │ │
│ │ (Stream IPC 数据) │ │
│ └────────────────────┘ │
└─────────────────────────┘
架构说明
1. CP 核 (应用核) - 开放接口层
用户应用层: 处理人脸识别事件,采集图像数据,管理人脸特征
ACOMP FD 组件: 提供生命周期管理、事件回调、参数配置等 API
图像流管理: 管理 M2R(Master to Remote) 图像数据流
ACOMP IPC 层: 封装 IPC 消息,与 AP 核通信
2. AP 核 (算法核) - 算法实现层
ACOMP Framework: 接收 IPC 命令,管理算法生命周期,处理图像流数据
人脸识别算法引擎: 执行人脸检测、对齐、活体检测、特征提取和比对
Note
AP 核的具体实现为闭源算法库,开发者只需关注 CP 核的 API 使用即可。
3. 通信机制
控制通道: 通过 IC Message 传递控制命令 (prepare/start/stop/control)
数据通道: 通过 VirtQueue 共享内存实现零拷贝图像流传输
事件通知: AP 核通过 NOTIFY 消息主动推送识别结果到 CP 核
4. 数据流向
M2R 流: CP 核采集的图像数据 (摄像头/文件) → AP 核算法引擎
事件流: AP 核识别结果(检测框/特征/活体) → CP 核回调函数
图像数据结构
输入图像数据结构
typedef struct{
acomp_fd_pixel_format format; /* 像素格式 */
uint32_t index; /* 帧索引号 */
uint16_t width; /* 图像宽度(像素) */
uint16_t height; /* 图像高度(像素) */
uint32_t length; /* 图像数据长度(字节) */
uint32_t resv[4]; /* 保留字段 */
uint8_t data[0]; /* 图像数据 */
} acomp_fd_input_frame_t;
支持的图像格式
格式 |
说明 |
数据大小 (320x240) |
|---|---|---|
|
BGR 24位真彩色 |
230400 字节 |
|
YUYV422 交织格式 |
153600 字节 |
|
RGB 16位高彩色 |
153600 字节 |
人脸识别结果结构
typedef struct {
acomp_fd_rect_t face_rect; /* 人脸检测矩形框 */
float face_score; /* 人脸检测得分 */
acomp_fd_align_point_t align_points[68]; /* 68个人脸关键点 */
int n_align_point; /* 关键点个数 */
acomp_fd_head_pose_t pose; /* 头部姿态角度 */
acomp_fd_live_detect_result_t live_result; /* 活体检测结果 */
int face_id; /* 人脸ID */
float features[384]; /* 384维人脸特征 */
int feature_cnt; /* 特征维度 */
float compare_scores[10]; /* 与注册人脸的比对得分 */
int compare_cnt; /* 已注册人脸数量 */
} acomp_fd_result_t;
配置选项
基本配置
配置项 |
说明 |
默认值 |
|---|---|---|
|
启用ACOMP组件 |
n |
|
启用ACOMP组件的人脸识别组件 |
n |
资源配置
配置项 |
说明 |
默认值 |
|---|---|---|
|
人脸检测模型地址(Flash) |
0x30100000 |
|
人脸检测模型长度 |
450936 |
|
人脸对齐模型地址(Flash) |
0x30170000 |
|
人脸对齐模型长度 |
1588664 |
|
活体检测模型地址(Flash) |
0x30300000 |
|
活体检测模型长度 |
1095288 |
|
特征提取模型地址(Flash) |
0x30410000 |
|
特征提取模型长度 |
2953752 |
快速开始
1. 启用组件
在项目的 prj.conf 文件中添加:
# 启用 ACOMP 组件
CONFIG_ACOMP=y
# 启用ACOMP组件的FD组件
CONFIG_ACOMP_FD=y
# 配置人脸识别组件所需资源在flash的位置和大小
CONFIG_ACOMP_FD_RES_FACE_DETECT_ADDRESS=0x30100000
CONFIG_ACOMP_FD_RES_FACE_DETECT_LENGTH=450936
CONFIG_ACOMP_FD_RES_FACE_ALIGN_ADDRESS=0x30170000
CONFIG_ACOMP_FD_RES_FACE_ALIGN_LENGTH=1588664
CONFIG_ACOMP_FD_RES_FACE_LIVE_ADDRESS=0x30300000
CONFIG_ACOMP_FD_RES_FACE_LIVE_LENGTH=1095288
CONFIG_ACOMP_FD_FACE_VERIFY_ADDRESS=0x30410000
CONFIG_ACOMP_FD_FACE_VERIFY_LENGTH=2953752
2. 初始化人脸识别组件
在应用程序中初始化人脸识别组件:
#include "acomp.h"
#include "fd/acomp_fd.h"
int main(int argc, char **argv)
{
// 初始化 ACOMP 框架
acomp_init();
// 初始化人脸识别组件
int ret = acomp_fd_init();
if (ret != ACOMP_ERR_OK) {
printf("FD init failed: %d\n", ret);
return -1;
}
// 你的应用代码
return 0;
}
3. 注册事件回调
使用事件回调函数接收人脸识别结果:
#include "fd/acomp_fd.h"
void fd_event_handler(uint32_t event, void *event_data,
uint32_t event_data_len, void *priv)
{
if (event & FD_CB_EVENT_ENGINE_RLT) {
// 人脸识别结果
acomp_fd_result_info_t *info = (acomp_fd_result_info_t *)event_data;
if (info->results_cnt > 0) {
uint32_t max_idx = info->max_area_results_index;
acomp_fd_result_t *result = &info->results[max_idx];
printf("Face detected: [%d,%d,%d,%d], score: %.2f\n",
result->face_rect.x, result->face_rect.y,
result->face_rect.w, result->face_rect.h,
result->face_score);
printf("Head pose: yaw=%.1f, pitch=%.1f, roll=%.1f\n",
result->pose.yaw, result->pose.pitch, result->pose.roll);
printf("Live detect: status=%d, score=%.2f\n",
result->live_result.status,
result->live_result.scores[1]);
} else {
printf("No face detected\n");
}
} else if (event & FD_CB_EVENT_ENGINE_WR_ERR) {
// 写入错误
printf("FD write error\n");
}
}
// 注册回调
int ret = acomp_fd_add_callback(
FD_CB_EVENT_ENGINE_RLT | FD_CB_EVENT_ENGINE_WR_ERR,
fd_event_handler,
NULL
);
4. 启动人脸识别服务
完整的启动流程:
#include "fd/acomp_fd.h"
void start_fd_service(void)
{
int ret;
// 1. 就绪组件(分配资源)
ret = acomp_fd_prepare();
if (ret != ACOMP_ERR_OK) {
printf("FD prepare failed: %d\n", ret);
return;
}
// 2. 启动人脸识别
ret = acomp_fd_start();
if (ret != ACOMP_ERR_OK) {
printf("FD start failed: %d\n", ret);
return;
}
printf("FD service started\n");
}
void stop_fd_service(void)
{
int ret;
// 1. 停止人脸识别
ret = acomp_fd_stop();
if (ret != ACOMP_ERR_OK) {
printf("FD stop failed: %d\n", ret);
return;
}
// 2. 清理资源
ret = acomp_fd_cleanup();
if (ret != ACOMP_ERR_OK) {
printf("FD cleanup failed: %d\n", ret);
return;
}
printf("FD service stopped\n");
}
5. 配置活体检测参数
设置活体检测模式和阈值:
#include "fd/acomp_fd.h"
void configure_live_detect(void)
{
// 配置活体检测
acomp_fd_live_detect_mode_t mode = {
.enable = true, // 启用活体检测
.score_threshold = {
0.51, // 假人阈值(未使用)
0.1, // 真人阈值(活体得分 >= 0.1 才进行特征提取)
},
};
int ret = acomp_fd_live_detect_mode_set(&mode);
if (ret != ACOMP_ERR_OK) {
printf("Set live detect mode failed: %d\n", ret);
}
}
6. 创建图像输入流并发送图像数据
使能 M2R (Master to Remote) 流通道,用于将图像数据发送给 AP 核:
#include "fd/acomp_fd.h"
#define TX_STREAM_CH_INDEX 0
#define TX_STREAM_CH_NAME "stream.fd_image"
void setup_tx_stream(void)
{
// 1. 创建 M2R 流通道描述符
acomp_stream_chn_create_desc_t desc = {
.cname = TX_STREAM_CH_NAME,
.direction = ACOMP_STREAM_DIRECTION_M2R, // Master to Remote
.index = TX_STREAM_CH_INDEX,
.buffer_size = 320 * 240 * 2 + sizeof(acomp_fd_input_frame_t),
.num_descs = 4, // 缓冲区描述符数量
.kick_policy = 1, // 自动触发
};
// 2. 使能流通道
int ret = acomp_fd_stream_ch_enable(TX_STREAM_CH_INDEX, &desc);
if (ret != ACOMP_ERR_OK) {
printf("Failed to enable tx stream: %d\n", ret);
}
}
void send_image_to_fd(uint8_t *image_data, int width, int height,
acomp_fd_pixel_format format)
{
uint8_t *buffer;
uint32_t buf_size;
uint16_t desc_idx;
// 1. 分配发送缓冲区
buffer = acomp_fd_stream_tx_buffer_alloc(TX_STREAM_CH_INDEX,
&buf_size, &desc_idx);
if (buffer && buf_size > 0) {
// 2. 填充图像帧数据
acomp_fd_input_frame_t *frame = (acomp_fd_input_frame_t *)buffer;
frame->format = format;
frame->index = 0;
frame->width = width;
frame->height = height;
frame->length = width * height * 2; // YUYV422
memcpy(frame->data, image_data, frame->length);
// 3. 提交缓冲区发送
acomp_fd_stream_tx_buffer_submit(TX_STREAM_CH_INDEX,
buffer, buf_size, desc_idx);
}
}
7. 人脸特征管理
导入人脸特征用于识别:
#include "fd/acomp_fd.h"
void load_face_features(void)
{
// 准备人脸特征数据(特征可从人脸识别组件识别结果或文件或数据库读取)
acomp_fd_feature_result_t features[3]; // 最多10个
// 假设已经从某处获取了特征数据(特征可从人脸识别组件识别结果或文件或数据库读取)
// load_features_from_storage(features, 3);
// 导入特征到人脸识别组件
int ret = acomp_fd_features_load(features, 3);
if (ret != ACOMP_ERR_OK) {
printf("Load features failed: %d\n", ret);
} else {
printf("Loaded 3 face features\n");
}
}
API 参考
生命周期管理
acomp_fd_init
int acomp_fd_init(void);
功能:初始化人脸识别组件
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_NO_MEM:内存不足ACOMP_ERR_INVALID_STATE:无效状态ACOMP_ERR_NOT_FOUND:设备未找到
acomp_fd_prepare
int acomp_fd_prepare(void);
功能:就绪人脸识别组件,初始化内存块及算法资源
说明:在调用 acomp_fd_start() 之前必须调用此函数
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_NO_MEM:内存不足ACOMP_ERR_INVALID_STATE:无效状态
acomp_fd_cleanup
int acomp_fd_cleanup(void);
功能:复位人脸识别组件,释放内存块及算法资源
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_INVALID_STATE:无效状态
acomp_fd_start
int acomp_fd_start(void);
功能:启动人脸识别组件,开始处理图像流
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_NO_MEM:内存不足ACOMP_ERR_INVALID_STATE:无效状态
acomp_fd_stop
int acomp_fd_stop(void);
功能:停止人脸识别组件,停止处理图像流
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_INVALID_STATE:无效状态
参数配置
acomp_fd_params_set
int acomp_fd_params_set(const acomp_fd_param_t *params, uint32_t params_cnt);
功能:设置组件参数
参数:
params:参数数组指针params_cnt:参数个数
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_INVALID_ARG:参数错误ACOMP_ERR_INVALID_STATE:无效状态
acomp_fd_live_detect_mode_set
int acomp_fd_live_detect_mode_set(const acomp_fd_live_detect_mode_t *mode);
功能:设置活体检测模式
参数:
mode:活体检测配置enable:是否启用活体检测score_threshold[1]:真人得分阈值(活体得分 >= 此值才进行特征提取)
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_INVALID_ARG:参数错误ACOMP_ERR_INVALID_STATE:无效状态
acomp_fd_align_threshold_set
int acomp_fd_align_threshold_set(const acomp_fd_head_pose_t *threshold);
功能:设置人脸对齐的头部姿态阈值
说明:如果头部姿态角度超过阈值,将不进行活体检测和特征提取
参数:
threshold:头部姿态阈值yaw:偏航角阈值pitch:俯仰角阈值roll:翻滚角阈值
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_INVALID_ARG:参数错误ACOMP_ERR_INVALID_STATE:无效状态
acomp_fd_features_load
int acomp_fd_features_load(const acomp_fd_feature_result_t *features, uint32_t count);
功能:从外部导入人脸特征到注册库
参数:
features:人脸特征数组指针count:特征个数(最多10个)
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_NO_MEM:内存不足ACOMP_ERR_INVALID_ARG:参数错误ACOMP_ERR_INVALID_STATE:无效状态
事件回调
acomp_fd_add_callback
int acomp_fd_add_callback(uint32_t events, fd_event_cb_t cb, void *priv);
功能:添加事件回调函数
参数:
events:事件位掩码,可同时注册多个事件FD_CB_EVENT_ENGINE_RLT:人脸识别结果返回FD_CB_EVENT_ENGINE_WR_ERR:算法引擎写入错误
cb:回调函数指针priv:回调函数的私有数据指针
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_NO_MEM:内存不足ACOMP_ERR_INVALID_ARG:参数错误ACOMP_ERR_INVALID_STATE:无效状态
acomp_fd_remove_callback
int acomp_fd_remove_callback(fd_event_cb_t cb);
功能:移除回调函数
参数:
cb:待移除的回调函数
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_INVALID_ARG:参数错误ACOMP_ERR_INVALID_STATE:无效状态ACOMP_ERR_NOT_SUPPORTED:不支持的操作
图像流管理
acomp_fd_stream_ch_enable
int acomp_fd_stream_ch_enable(int chn, acomp_stream_chn_create_desc_t *desc);
功能:使能图像流通道
参数:
chn:通道索引desc:通道描述符指针
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_INVALID_STATE:无效状态ACOMP_ERR_INVALID_ARG:参数错误ACOMP_ERR_CREATE_STREAM_FAILED:创建流失败
acomp_fd_stream_ch_disable
int acomp_fd_stream_ch_disable(int chn);
功能:禁用图像流通道
参数:
chn:通道索引
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_INVALID_STATE:无效状态ACOMP_ERR_INVALID_ARG:参数错误
acomp_fd_stream_tx_buffer_alloc
void* acomp_fd_stream_tx_buffer_alloc(int chn, uint32_t* len, uint16_t* desc_idx);
功能:分配 TX 流缓冲区用于向 AP 核发送图像数据
参数:
chn:通道索引len:可用缓冲区长度指针(输出)desc_idx:描述符索引指针(输出)
返回值:缓冲区指针,失败返回 NULL
acomp_fd_stream_tx_buffer_submit
int acomp_fd_stream_tx_buffer_submit(int chn, void* buffer,
uint32_t len, uint16_t desc_idx);
功能:提交 TX 流缓冲区发送图像数据到 AP 核
参数:
chn:通道索引buffer:缓冲区指针len:数据长度desc_idx:描述符索引
返回值:
ACOMP_ERR_OK:成功ACOMP_ERR_INVALID_STATE:无效状态ACOMP_ERR_INVALID_ARG:参数错误
使用示例
完整示例
#include "acomp.h"
#include "fd/acomp_fd.h"
#include "lisa_log.h"
#define TAG "fd_demo"
// 事件回调函数
void fd_event_handler(uint32_t event, void *event_data,
uint32_t event_data_len, void *priv)
{
if (event & FD_CB_EVENT_ENGINE_RLT) {
acomp_fd_result_info_t *info = (acomp_fd_result_info_t *)event_data;
LISA_LOGI(TAG, "FD result: count=%d", info->results_cnt);
if (info->results_cnt > 0) {
uint32_t idx = info->max_area_results_index;
acomp_fd_result_t *result = &info->results[idx];
LISA_LOGI(TAG, "Face rect: [%d,%d,%d,%d], score: %.2f",
result->face_rect.x, result->face_rect.y,
result->face_rect.w, result->face_rect.h,
result->face_score);
LISA_LOGI(TAG, "Head pose: yaw=%.1f, pitch=%.1f, roll=%.1f",
result->pose.yaw, result->pose.pitch, result->pose.roll);
LISA_LOGI(TAG, "Live: status=%d, score=%.2f",
result->live_result.status,
result->live_result.scores[1]);
if (result->compare_cnt > 0) {
LISA_LOGI(TAG, "Compare scores: [%.2f, %.2f]",
result->compare_scores[0],
result->compare_scores[1]);
}
}
} else if (event & FD_CB_EVENT_ENGINE_WR_ERR) {
LISA_LOGE(TAG, "FD write error");
}
}
void fd_demo(void)
{
int ret;
// 1. 初始化 ACOMP 框架
acomp_init();
// 2. 初始化人脸识别组件
ret = acomp_fd_init();
if (ret != ACOMP_ERR_OK) {
LISA_LOGE(TAG, "FD init failed: %d", ret);
return;
}
// 3. 注册事件回调
ret = acomp_fd_add_callback(
FD_CB_EVENT_ENGINE_RLT | FD_CB_EVENT_ENGINE_WR_ERR,
fd_event_handler,
NULL
);
if (ret != ACOMP_ERR_OK) {
LISA_LOGE(TAG, "Add callback failed: %d", ret);
return;
}
// 4. 就绪组件
ret = acomp_fd_prepare();
if (ret != ACOMP_ERR_OK) {
LISA_LOGE(TAG, "FD prepare failed: %d", ret);
return;
}
LISA_LOGI(TAG, "FD prepared");
// 5. 启动人脸识别
ret = acomp_fd_start();
if (ret != ACOMP_ERR_OK) {
LISA_LOGE(TAG, "FD start failed: %d", ret);
return;
}
LISA_LOGI(TAG, "FD started");
// 6. 配置活体检测
acomp_fd_live_detect_mode_t mode = {
.enable = true,
.score_threshold = {0.51, 0.1},
};
acomp_fd_live_detect_mode_set(&mode);
// 7. 创建图像输入流
acomp_stream_chn_create_desc_t desc = {
.cname = "stream.fd_image",
.direction = ACOMP_STREAM_DIRECTION_M2R,
.index = 0,
.buffer_size = 320 * 240 * 2 + sizeof(acomp_fd_input_frame_t),
.num_descs = 4,
.kick_policy = 1,
};
acomp_fd_stream_ch_enable(0, &desc);
// 8. 发送图像数据(示例)
// send_image_to_fd(...);
// 9. 运行一段时间
vTaskDelay(pdMS_TO_TICKS(10000));
// 10. 停止人脸识别
ret = acomp_fd_stop();
if (ret != ACOMP_ERR_OK) {
LISA_LOGE(TAG, "FD stop failed: %d", ret);
}
LISA_LOGI(TAG, "FD stopped");
// 11. 清理资源
ret = acomp_fd_cleanup();
if (ret != ACOMP_ERR_OK) {
LISA_LOGE(TAG, "FD cleanup failed: %d", ret);
}
LISA_LOGI(TAG, "FD cleaned up");
}
图像流处理示例
#include "fd/acomp_fd.h"
void image_stream_tx_example(uint8_t *image_data, int width, int height)
{
int chn = 0;
uint32_t len;
uint16_t desc_idx;
void *buffer;
// 分配发送缓冲区
buffer = acomp_fd_stream_tx_buffer_alloc(chn, &len, &desc_idx);
if (buffer) {
// 填充图像帧数据
acomp_fd_input_frame_t *frame = (acomp_fd_input_frame_t *)buffer;
frame->format = PIX_FMT_YUV422_YUYV_PACKED;
frame->index = 0;
frame->width = width;
frame->height = height;
frame->length = width * height * 2;
memcpy(frame->data, image_data, frame->length);
// 提交发送
acomp_fd_stream_tx_buffer_submit(chn, buffer, len, desc_idx);
}
}
注意事项
初始化顺序:必须先调用
acomp_init()初始化 ACOMP 框架,再调用acomp_fd_init()生命周期管理:启动前必须调用
acomp_fd_prepare(),停止后应调用acomp_fd_cleanup()释放资源状态检查:所有 API 都会进行状态检查,确保在正确的状态下调用相应的函数
事件回调:回调函数在组件内部线程中执行,应避免长时间阻塞操作
内存管理:组件使用动态内存分配,确保系统有足够的堆内存
资源配置:确保配置的模型地址和长度与实际烧录的模型匹配
图像格式:支持 YUYV422、RGB565、BGR888 等格式,推荐使用 YUYV422或RGB565 以节省内存
活体检测阈值:根据实际应用场景调整活体检测阈值,平衡误识率和拒识率
特征管理:最多支持 10 个注册人脸特征,每个特征为 384 维浮点数
跨核通信:图像流基于 IPC 机制,注意跨核数据传输的延迟和同步问题
双核协作:本组件运行在 CP 核,需要 AP 核提供算法支持,确保 AP 核固件正确烧录
常见问题
Q: 人脸识别组件初始化失败怎么办?
A: 检查以下几点:
确保 ACOMP 框架已正确初始化
检查系统是否有足够的堆内存
确认 AP 核固件和算法模型已正确烧录到 Flash
Q: 为什么没有检测到人脸?
A: 可能的原因:
图像质量不佳(光线不足、模糊等)
人脸角度过大或遮挡严重
图像格式或尺寸不正确
检查回调函数是否正确注册
Q: 活体检测总是失败怎么办?
A: 建议:
调整活体检测阈值
score_threshold[1](降低阈值更容易通过)确保图像质量良好,光线充足
检查人脸是否正对摄像头,角度不要过大
Q: 特征比对得分很低怎么办?
A: 建议:
确保注册和识别时的图像质量一致
检查人脸角度和光线条件
特征比对阈值通常设置为 0.7-0.9,根据实际情况调整
Q: 如何提高识别准确率?
A: 建议:
使用高质量的图像输入(清晰、光线充足)
确保人脸正对摄像头,角度不要过大
注册多个角度的人脸特征
调整活体检测和特征比对阈值