带你玩转OpenHarmony AI:基于Seetaface2的人脸识别

简介

随着时代的进步,全民刷脸已经成为一种新型的生活方式,这也是全球科技进步的又一阶梯,人脸识别技术已经成为一种大趋势,无论在智慧出行、智能家居、智慧办公等场景均有较广泛的应用场景,本文介绍了基于SeetaFace2人脸识别引擎在OpenAtom OpenHarmony(以下简称"OpenHarmony")上实现人脸识别的AI能力。

什么是SeetaFace2

SeetaFace2是由中科视拓(北京)科技有限公司开发并使用BSD开源协议开源出来的一款人脸识别引擎库,其搭建了一套全自动人脸识别系统所需的三个核心模块,即:人脸检测模块FaceDetector、面部关键点定位模块 FaceLandmarker 以及人脸特征提取与比对模块FaceRecognizer。除了三个核心模块外,它还提供了两个辅助模块FaceTracker和QualityAssessor用于人脸跟踪和质量评估。下图是SeetaFace2人脸识别算法组件:

SeetaFace2能做什么

SeetaFace2采用标准C++开发,全部模块均不依赖任何第三方库,支持x86架构(Windows、Linux)和ARM架构,可以轻松地移植到OpenHarmony上。SeetaFace2支持的上层应用包括但不限于人脸门禁、无感考勤、人脸比对等。如下图展示了SeetaFace2支持的应用矩阵:

SeetaFace2人脸识别原理

SeetaFace2人脸识别引擎搭建了一套全自动人脸识别系统所需的三个核心模块:

  1. 人脸检测(FaceDetector)

在图像中首先定位出人脸的位置,然后裁剪(crop)出包含人脸位置的矩形框,一般还会进行填充、缩放到指定尺寸,还可能会对人脸图像进行标准化normalize;

  1. 面部关键点定位(FaceLandmarker)

提取人脸关键点坐标,然后使用放射变化或相似变换等进行人脸对齐变换。面部关键点定位的目标就是把所有的人脸图片统一到一个固定的正脸姿态大小,从而提高模型对人脸姿态变化的鲁棒性。

  1. 人脸特征提取与比对模块(FaceRecognizer)

主要使用深度学习等方法提取人脸的特征,然后通过特征对比,计算人脸的相似度。

SeetaFace2人脸识别的具体过程如下图所示:

两步带你实现人脸识别

关于SeetaFace2的如何移植到OpenHarmony移植请参照文档:SeetaFace2移植开发文档(请参考文章末尾相关文档链接),这里我们主要分析通过SeetaFace2如何实现人脸识别。

从上面人脸识别的流程图可以知道人脸识别主要包含2个大块:人脸注册和人脸识别。

  1. 人脸注册

人脸注册首先需要对传入的图片进行人脸检测,当检测到人脸后会提取对应的人脸信息,并将信息保存用于对比。

人脸信息检测实现:

复制代码
std::vector<SeetaFaceInfo> DetectFace(const SeetaImageData &image)
{
  auto faces = FD.detect(image);
  return std::vector<SeetaFaceInfo>(faces.data, faces.data + faces.size);
}

其中FD是三大模块中的人脸检测模块(FaceDetector),其加载了人脸检测模型:

复制代码
seeta::ModeStting FD_model("fd_2_00.dat", seeta::ModeStting::CPU, 0);

而返回SeetaFaceInfo数据则是检测到的人脸信息,其中包含了人脸个数,人脸区域坐标以及人脸置信度得分数据。然后通过人脸信息检测返回的数据进行面部关键点定位。

面部关键点定位实现:

复制代码
std::vector<SeetaPointF> DetectPoints(const SeetaImageData &image, const SeetaRect &face)
{
  std::vector<SeetaPointF> points(PD.number());
  PD.mark(image, face, points.data());
  return std::move(points);
}

其中的PD是三大模块中的关键点定位模块(FaceLandmarker),关键点定位需要根据面部特征模型进行对比分析的,SeetaFace2提供2种面部特征模型。分别是通过5点定位和通过81点定位,此实例中我们使用的是81点定位模型:

复制代码
seeta::ModeStting PD_model("pd_2_00_pts81.dat", seeta::ModeStting::CPU, 0);

获取完面部特征数据后,SeetaFace2提供了一个人脸数据库进行保存对应的人脸信息数据,以此来完成人脸信息的注册:

复制代码
int64_t Register(const SeetaImageData &image)
{
  auto faces =  DetectFace(image);
  auto points =  DetectPoints(image, faces.pos);
 
  return FDB.Register(image, points.data());
}   

其中FDB是SeetaFace2实现的FaceDatabase数据库管理。该数据库也为人脸识别提供面部特征数据的对比结果,面部特征对比也需要一个人脸数据模型:

复制代码
seeta::ModeStting FDB_model("fr_2_00.dat", seeta::ModeStting::CPU, 0);

通过以上步骤,我们就已经完成了人脸的注册。

  1. 人脸识别

人脸识别和人脸注册步骤类似,都需要先检测人脸信息及提取面部特征数据。唯一的区别在于提取面部特征时需要进行人脸质量评估,最后根据质量评估结果进行识别,具体实现如下:

复制代码
int64_t RecogizePoint(const SeetaImageData &image)
{
    int64_t result = 0;
  seeta::ModeStting FD_model("fd_2_00.dat", seeta::ModeStting::CPU, 0);        // 此3步创建3个模型
  seeta::ModeStting PD_model("pd_2_00_pts81.dat", seeta::ModeStting::CPU, 0);
  seeta::ModeStting FDB_model("fr_2_00.dat", seeta::ModeStting::CPU, 0);
   
  seeta::FaceDetector FD(FD_model);    // 创建人脸检测模块
  seeta::FaceLandmarker PD(PD_model);   // 创建面部关键点定位模块
  seeta::FaceDatabase FDB(FDB_model);    // 创建人脸特征信息数据库模块
   
  auto faces = FD.detect(image);        // 获取人脸特征信息
    for (SeetaFaceInfo &face : faces) {    // 对比每个人脸信息
        int64_t index = -1;
        float similarity = 0;
        std::vector<SeetaPointF> points(PD.number());
      PD.mark(image, face, points.data());            // 获取人脸框信息
        auto score = QA.evaluate(image, face.pos, points.data());   // 获取人脸质量评分
        if (score == 0) {
            HILOGI("no ignored\r\n");
        } else {
            auto queried = FDB.QueryTop(image, points.data(), 1, &index, &similarity);    // 从注册的人脸数据库中对比相似度
            if (queried < 1) {
                continue;
            }
            if (similarity > threshold) {
                HILOGI("get recognized face!! \r\n");
                result++;
            }
        }
    }
     
    return result;
}

为了帮助到大家能够更有效的学习OpenHarmony 开发的内容,下面特别准备了一些相关的参考学习资料:

OpenHarmony 开发环境搭建:https://qr18.cn/CgxrRy

《OpenHarmony源码解析》:https://qr18.cn/CgxrRy

  • 搭建开发环境
  • Windows 开发环境的搭建
  • Ubuntu 开发环境搭建
  • Linux 与 Windows 之间的文件共享
  • ......

系统架构分析:https://qr18.cn/CgxrRy

  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ......

OpenHarmony 设备开发学习手册:https://qr18.cn/CgxrRy

OpenHarmony面试题(内含参考答案):https://qr18.cn/CgxrRy

相关推荐
ai安歌3 小时前
鸿蒙PC:鸿蒙electron跨端框架PC归档流水线实战:把散落文件整理成可追踪的桌面归档流程
华为·electron·harmonyos
lqj_本人4 小时前
鸿蒙electron跨端框架PC课业板实战:课程、截止时间、提交物和风险都放到桌面上
服务器·electron·harmonyos
小雨青年7 小时前
鸿蒙 HarmonyOS 6 | Pura X Max 鸿蒙原生适配 10:横屏下页面从上下结构改为左右结构
华为·harmonyos
lqj_本人7 小时前
鸿蒙electron跨端框架PC灵光速记实战:让突然冒出来的想法先有地方落脚
harmonyos
Swift社区7 小时前
HarmonyOS 鸿蒙PC三方库移植:vcpkg方式的 Port 脚本编写简明教程
华为·harmonyos
lqj_本人7 小时前
鸿蒙electron跨端框架PC剪贴台实战:把高频短文本整理成一键可取的桌面片段库
华为·electron·harmonyos
桑榆肖物8 小时前
nanoFramework 正式支持 Raspberry Pi Pico RP2040
驱动开发·嵌入式硬件·iot
ai安歌8 小时前
鸿蒙PC:鸿蒙electron跨端框架PC素材情绪板实战:把灵感、配色和参考资料收进桌面创作面板
华为·electron·harmonyos
梦想不只是梦与想8 小时前
鸿蒙 Live View Kit:实况窗服务(一)
harmonyos·鸿蒙·实况窗
nashane9 小时前
HarmonyOS 6学习:Web组件内嵌H5视频全屏“复活”指南
前端·学习·harmonyos