人脸识别组件

简介

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)

PIX_FMT_BGR888

BGR 24位真彩色

230400 字节

PIX_FMT_YUV422_YUYV_PACKED

YUYV422 交织格式

153600 字节

PIX_FMT_RGB565

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;

配置选项

基本配置

配置项

说明

默认值

CONFIG_ACOMP

启用ACOMP组件

n

CONFIG_ACOMP_FD

启用ACOMP组件的人脸识别组件

n

资源配置

配置项

说明

默认值

CONFIG_ACOMP_FD_RES_FACE_DETECT_ADDRESS

人脸检测模型地址(Flash)

0x30100000

CONFIG_ACOMP_FD_RES_FACE_DETECT_LENGTH

人脸检测模型长度

450936

CONFIG_ACOMP_FD_RES_FACE_ALIGN_ADDRESS

人脸对齐模型地址(Flash)

0x30170000

CONFIG_ACOMP_FD_RES_FACE_ALIGN_LENGTH

人脸对齐模型长度

1588664

CONFIG_ACOMP_FD_RES_FACE_LIVE_ADDRESS

活体检测模型地址(Flash)

0x30300000

CONFIG_ACOMP_FD_RES_FACE_LIVE_LENGTH

活体检测模型长度

1095288

CONFIG_ACOMP_FD_FACE_VERIFY_ADDRESS

特征提取模型地址(Flash)

0x30410000

CONFIG_ACOMP_FD_FACE_VERIFY_LENGTH

特征提取模型长度

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

注意事项

  1. 初始化顺序:必须先调用 acomp_init() 初始化 ACOMP 框架,再调用 acomp_fd_init()

  2. 生命周期管理:启动前必须调用 acomp_fd_prepare(),停止后应调用 acomp_fd_cleanup() 释放资源

  3. 状态检查:所有 API 都会进行状态检查,确保在正确的状态下调用相应的函数

  4. 事件回调:回调函数在组件内部线程中执行,应避免长时间阻塞操作

  5. 内存管理:组件使用动态内存分配,确保系统有足够的堆内存

  6. 资源配置:确保配置的模型地址和长度与实际烧录的模型匹配

  7. 图像格式:支持 YUYV422、RGB565、BGR888 等格式,推荐使用 YUYV422或RGB565 以节省内存

  8. 活体检测阈值:根据实际应用场景调整活体检测阈值,平衡误识率和拒识率

  9. 特征管理:最多支持 10 个注册人脸特征,每个特征为 384 维浮点数

  10. 跨核通信:图像流基于 IPC 机制,注意跨核数据传输的延迟和同步问题

  11. 双核协作:本组件运行在 CP 核,需要 AP 核提供算法支持,确保 AP 核固件正确烧录

常见问题

Q: 人脸识别组件初始化失败怎么办?

A: 检查以下几点:

  • 确保 ACOMP 框架已正确初始化

  • 检查系统是否有足够的堆内存

  • 确认 AP 核固件和算法模型已正确烧录到 Flash

Q: 为什么没有检测到人脸?

A: 可能的原因:

  • 图像质量不佳(光线不足、模糊等)

  • 人脸角度过大或遮挡严重

  • 图像格式或尺寸不正确

  • 检查回调函数是否正确注册

Q: 活体检测总是失败怎么办?

A: 建议:

  • 调整活体检测阈值 score_threshold[1] (降低阈值更容易通过)

  • 确保图像质量良好,光线充足

  • 检查人脸是否正对摄像头,角度不要过大

Q: 特征比对得分很低怎么办?

A: 建议:

  • 确保注册和识别时的图像质量一致

  • 检查人脸角度和光线条件

  • 特征比对阈值通常设置为 0.7-0.9,根据实际情况调整

Q: 如何提高识别准确率?

A: 建议:

  • 使用高质量的图像输入(清晰、光线充足)

  • 确保人脸正对摄像头,角度不要过大

  • 注册多个角度的人脸特征

  • 调整活体检测和特征比对阈值