恩智浦NXP RT1062F 本地神经网络人脸识别接口 - [详解]

恩智浦NXP RT1062F 本地神经网络人脸识别接口使用详解

一、芯片介绍

NXP MCU级别的人脸识别解决方案利用i.MX RT106F来实现,使开发者轻松便捷地将人脸识别功能添加到他们基于MCU的IoT产品中,这个超小尺寸,集成软件算法和硬件的方案,可以方便开发者进行快速的评估和概念验证开发。SLN-VIZN-IOT开发套件可以离线创建自己的面部模型,而无需进行云连接,从而降低了总体成本和设计复杂性。

这个解决方案最大程度上缩短了上市时间,降低了风险并减少了开发工作,可以使众多OEM厂家更方便地添加人脸识别功能,为智能家居,智能家电,智能玩具和智能工业提供高级用户界面和访问控制功能,而无需Wi- Fi和云连接,解决了许多消费者的隐私问题。

i.MX RT106F是i.MX RT1060系列的成员,于2020年4月份正式量产,主要针对低成本人脸识别应用,基于Arm Coretx-M7内核,主频高达600MHz的高性能实时处理器,除了人脸识别功能外,i.MX RT106F 还有大量可用外设,可以作为多种应用的主芯片。i.MX RT106F已经获得许可,可以运行NXP OASIS 运行库进行人脸识别,其中包括:

摄像头驱动、图像捕获和预处理、人脸检测、人脸跟踪、人脸对比、人脸识别、防欺骗、人脸配置、置信度、人脸识别认证结果、情绪识别、内置安全bootloader,应用程序验证、连接性:MQTT;1W1p,TLS搜索与注册;所有驱动(包含wifi和蓝牙)、RTOS OTW客户端:OTW签名脚本,OTW rollback,图像冗余。

二、摄像头图片获取

在本人实际项目中使用的摄像头获取的格式为YUV422格式,后面使用接口转换为需要的对应接口
通过NXP中的CSI接口获取摄像头的图片,CSI(CMOS Sensor Interface)是专用的图像传感器接口,RT1062的CSI接口支持8位、10位、16位并行接口。CSI模块内嵌DMA因此不需要占用MCU的DMA外设。

CSI中断源码

void CSI_IRQHandler(void)
{
    uint32_t csisr = CSI->CSISR;

    /* Clear the error flags. */
    CSI->CSISR = csisr;

    if((csisr & CSI_CSISR_DMA_TSF_DONE_FB1_MASK) != 0)
    {
        gImageDone = 1;
        //gCameraActiveBufferIndex = 1;
        gCameraActiveBufferIndexA = 1;
        Camera_TransferStop();
        //PRINTF("1\n");
    }
    else if((csisr & CSI_CSISR_DMA_TSF_DONE_FB2_MASK) != 0)
    {
        gImageDone = 1;
        gCameraActiveBufferIndexB = 2;
        Camera_TransferStop();
        //PRINTF("2\n");
    }
    //CSI_DriverIRQHandler();
    __DSB();
}

通过FLEXIO调取图片信息

  • 以下是NXP提供的图片转换接口,第一个参数为摄像头获取的参数,第二个参数为转后图片输出。
void APP_SetPxp_RGB565toRGB888_Rotate(uint32_t srcBuf, uint32_t dstBuf);
void APP_SetPxp_Y8toRGB565_Rotate(uint32_t srcBuf, uint32_t dstBuf);
void APP_SetPxp_Mirror(uint32_t srcBuf, uint32_t dstBuf,uint8_t _MirrorType);
void APP_SetPxp_YUV422toRGB888_Rotate(uint32_t srcBuf, uint32_t dstBuf);
void APP_SetPxp_YUV422toRGB565_Rotate(uint32_t srcBuf, uint32_t dstBuf);
void APP_SetPxp_YUV422toY8_Rotate(uint32_t srcBuf, uint32_t dstBuf);
void APP_SetPxp_YUV422toY8_320_Rotate(uint32_t srcBuf, uint32_t dstBuf);
void APP_SetPxp_YUV422toY8_320_PALM_Rotate(uint32_t srcBuf, uint32_t dstBuf);
void APP_SetPxp_RGB565_640to320_scale(uint32_t srcBuf, uint32_t dstBuf);
  • 在实际项目中使用到的是RGB图片和红外IR图片,
//用来存储图片的数组,像素为640*480
__attribute__((aligned(64)))  __attribute__((section("SdramSection")))  uint8_t gTempLcddisp[2][640 * 480 * 3];

三、识别接口调用

人脸识别接口初始化结构体,识别模式设置

static OASISLTInitPara_t
init_para =
{
    .height = 640,
    .width = 480,															//图片像素大小
    .imgType = OASIS_IMG_TYPE_IR_SINGLE,									//人脸识别通道模式选择
    .minFace = 100,															//人脸存储容量
    .memPool = NULL,														//内存池
    .size = 0,																//内存池大小
    .cbs = {
        OASISLT_EvtHandler,//evtcb											//事件响应跳转函数
        GetRegisteredFacesHandler,//getface									//获取注册人脸
        AddNewFaceHandler,//add face										//将新注册的人脸加入到链表中
        NULL,
			  NULL,
        AdjustBrightnessHandler,											//光线处理函数
			  NULL,
			  NULL,
        oasislite_print
    },
    .enableFlags = OASIS_ENABLE_LIVENESS,// | OASIS_ENABLE_MULTI_VIEW,
    .falseAcceptRate = OASIS_FAR_1_1000000,
    .modClass = OASISLT_MODEL_CLASS_LIGHT,
	.fastMemBuf = NULL,
	.fastMemSize = 0,
};
  • 根据不同的识别方式,我们需要对初始化函数中的设置进行更改
typedef enum
{
    OASIS_IMG_TYPE_RGB_SINGLE,       // input only RGB frame
    OASIS_IMG_TYPE_IR_SINGLE,        // input only IR frame
    OASIS_IMG_TYPE_IR_RGB_DUAL,      // IR and RGB frames, do face recognition on IR frame
    OASIS_IMG_TYPE_RGB_IR_DUAL,      // IR and RGB frames, do face recognition on RGB frame
    OASIS_IMG_TYPE_IR_RGB_3D_TRIPLE, // IR, RGB and 3D frames, do face recognition on IR frame
    OASIS_IMG_TYPE_RGB_IR_3D_TRIPLE, // IR, RGB and 3D frames, do face recognition on RGB frame
    OASIS_IMG_TYPE_NUM,
    OASIS_IMG_TYPE_INVALID = 0xFF
} OASISLTImageType_t;

识别接口调用

接口函数使用:
param:rgb888Buf,RGB人脸识别时传入的图像
IRBuf,红外人脸识别时的红外人像图片
剩下的是人脸识别的用户信息结构体

int OASIS_recognition(char* rgb888Buf, char* IRBuf, sFaceRecInfo* _FaceRecInfo, sUserIdNormalInfo* _UserIdNormalInfo)
{
    ImageFrame_t RGBFrame = {init_para.height, init_para.width, 0, (unsigned char*)rgb888Buf};
    ImageFrame_t IRFrame = {init_para.height, init_para.width, 0, (unsigned char*)IRBuf};
    ImageFrame_t* frames[OASISLT_INT_FRAME_IDX_LAST] = {&RGBFrame, &IRFrame, NULL};
    int ret = 0;
    memset(&gFaceRecInfo, 0xFF, sizeof(sFaceRecInfo));
    gFaceRecInfo.faces_count = gParaTable.wRegFaceNum;
    gFaceRecInfo.similarity = 0;

    gFaceRunMode = FACE_SEARCH_FEATURE;

    ret = OASISLT_run_extend(frames, OASIS_DET_REC, init_para.minFace, _UserIdNormalInfo);

    memcpy(_FaceRecInfo, &gFaceRecInfo, sizeof(sFaceRecInfo));
    //check ret
    if(ret != 0)
    {
        OASISLT_LOGE(">>[oasis]OASISLT_run failed, Expect:0 output:%d\r\n", ret);
    }
    else
    {
        OASISLT_LOGI(">>[oasis]OASISLT_run success, Expect:0 output:%d\r\n", ret);
        //todo
    }

    return ret;
}
  • 传入参数设置列表
typedef enum
{
    OASIS_IMG_FORMAT_RGB888, // 3 channels
    OASIS_IMG_FORMAT_BGR888, // 3 channels

    /* theses formats are used internal only */
    OASIS_IMG_FORMAT_GREY888, // 3 channels
    OASIS_IMG_FORMAT_GREY8,   // 1 channel
    OASIS_IMG_FORMAT_NUM,
    OASIS_IMG_FORMAT_INVALID = 0xFF
} OASISLTImageFormat_t;

识别结果

  • 识别结果会传入初始化时设置的回调函数中,在以下函数的 OASISLTCbPara_t* para 参数中
static void OASISLT_EvtHandler(ImageFrame_t** frames,
                               OASISLTEvt_t evt,
                               OASISLTCbPara_t* para,
                               void* user_data)
typedef struct
{
    FaceBox_t *faceBoxIR;                            // face rect and landmark on IR image
    FaceBox_t *faceBoxRGB;                           // face rect and landmark on RGB image
    uint16_t faceID;                            // only valid when a face recognized or registered
    OASISLTRegisterRes_t regResult;             // only valid for registration
    OASISLTFaceOrientation_t faceOrientation;    //valid for face registration in progress event
    OASISLTDeregisterRes_t deregResult;         // only valid for deregistration
    OASISLTRecognizeRes_t recResult;            // only valid for face recognition
    OASISLTFaceQualityRes_t qualityResult;      // only valid for face quality check event.
    //OASISLTFaceMaskCheckRes_t maskResult;       // only valid for face mask check event.
    OASISLTFaceGlassesCheckRes_t glassesResult; // only valid for face glasses check event.
#define OASISLT_CB_PARA_RESERVED_INT 32
    int reserved[OASISLT_CB_PARA_RESERVED_INT]; // this field is reserved for debugging purpose
} OASISLTCbPara_t;

图片质量返回值含义

para->qualityResult;

Byte[0]: Recognition State                      //识别状态
Byte[1]: Face Count in database                 //数据库已注册人脸数
Byte[2]: Recognition Quality Check Result:      //识别人脸图像质量检测结果
typedef enum {
    OASIS_QUALITY_RESULT_FACE_OK ,                  //0.人脸图像质量合格
    OASIS_QUALITY_RESULT_FACE_TOO_SMALL,            // 1.人脸太小
    OASIS_QUALITY_RESULT_FACE_SIDE_FACE,            // 2:人脸图像不正
    OASIS_QUALITY_RESULT_FACE_BLUR,                 // 3:人脸图像模糊
    OASIS_QUALITY_RESULT_FAIL_LIVENESS_IR,          // 4:人脸IR活体失败
    OASIS_QUALITY_RESULT_FAIL_LIVENESS_RGB,         // 5:人脸RGB活体失败
    OASIS_QUALITY_RESULT_FAIL_BRIGHTNESS_DARK,      // 6:人脸亮度过黑
    OASIS_QUALITY_RESULT_FAIL_BRIGHTNESS_OVEREXPOSURE, // 7:人脸亮度过度曝光
    OASIS_QUALITY_RESULT_INVALID = 0xFF                // 8:人脸图像质量检测无效
} OASISLTFaceQualityRes_t;

Byte[3]: Recognition Result                            //识别结果

typedef enum {
    OASIS_REC_RESULT_KNOWN_FACE,                   // 0: 识别为已注册人脸
    OASIS_REC_RESULT_UNKNOWN_FACE,                 // 1: 识别为未注册人脸
    OASIS_REC_RESULT_INVALID = 0xFF                // 2: 识别无效
} OASISLTRecognizeRes_t;

Byte[4]: Recognition Face ID                        // 识别已注册人脸ID
Byte[5-8]: Recognition  Face Similarity (float type) //识别人脸相似度参数

人脸注册

识别成功后,调用人脸注册函数 FcStoreCharByChar,将用户信息写入指定的Flash中

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值