# 人脸识别库的移植 ### 简介 本文介绍如何在`Openharmony` 标准系统上移植开源项目--人脸识别(`SeetaFace2`),`SeetaFace2` 是中科视拓开源的第二代人脸识别库。包括了搭建一套全自动人脸识别系统所需的三个核心模块,即:人脸检测模块 `FaceDetector`、面部关键点定位模块 `FaceLandmarker` 以及人脸特征提取与比对模块 `FaceRecognizer`。 `SeetaFace2` 采用标准 C++ 开发,全部模块均不依赖任何第三方库,支持 x86 架构(`Windows、Linux`)和 ARM 架构(`Android`)。`SeetaFace2`支持的上层应用包括但不限于人脸门禁、无感考勤、人脸比对等。 ### 人脸识别库的移植 #### 获取源码 ##### 人脸识别库源码 人脸识别库github源码地址:https://github.com/seetafaceengine/SeetaFace2 gitee地址:https://gitee.com/mirrors/SeetaFace2/tree/master 建议使用gitee地址下载,执行如下指令(关于git的配置及使用请参照gitee官网文档,这里不在做过多的讲解): ``` cd ~/ git clone git@gitee.com:mirrors/SeetaFace2.git ``` ##### Openharmony源码 本次移植时在openharmony3.1beta版本上运行的,所以我们需要准备openharmony3.1beta的源码。 ``` mkdir ~/openharmony_3.1.0 cd ~/openharmony_3.1.0 repo init -u git@gitee.com:openharmony/manifest.git -b refs/tags/OpenHarmony-v3.1-Beta --no-repo-verify repo sync -c repo forall -c 'git lfs pull' ``` 获取源码的具体步骤参照文档:[openharmony源码获取](https://gitee.com/openharmony/docs/blob/OpenHarmony-3.1-Beta/zh-cn/device-dev/quick-start/quickstart-lite-sourcecode-acquire.md)。 #### 配置源码 下载完openharmony源码后,将SeetaFace2的源码拷贝到openhamony的third_party目录下: ``` cp -raf ~/SeetaFace2 ~/openharmony_3.1.0/third_party ``` #### SeetaFace2编译gn化 人脸识别引擎包括了搭建一套全自动人脸识别系统所需的三个核心模块,即:人脸检测模块 `FaceDetector`、面部关键点定位模块 `FaceLandmarker` 以及人脸特征提取与比对模块 `FaceRecognizer`。 已经两个辅助模块 `FaceTracker` 和 `QualityAssessor` 用于人脸跟踪和质量评估。因此我们在SeetaFace2顶层目录中编写的gn文件,只需要依赖以上模块即可。 ``` import("//build/ohos.gni") group("SeetaFace2") { deps = [ "FaceDetector", "FaceLandmarker", "FaceRecognizer", "FaceTracker", "QualityAssessor", ] } ``` 写完顶层目录的gn后,我们只需要在每个模块添加对应的gn即可,如人脸检测模块 FaceDetector的gn: ``` import("//build/ohos.gni") config("lib_config") { cflags_cc = [ "-frtti", "-fexceptions", "-DCVAPI_EXPORTS", "-DOPENCV_ALLOCATOR_STATS_COUNTER_TYPE=int", "-D_USE_MATH_DEFINES", "-D__OPENCV_BUILD=1", "-D__STDC_CONSTANT_MACROS", "-D__STDC_FORMAT_MACROS", "-D__STDC_LIMIT_MACROS", "-O2", "-Wno-error=header-hygiene", ] } ohos_shared_library("FaceDetector"){ sources = [ "src/seeta/FaceDetector.cpp", "seeta/common_alignment.cpp", "seeta/FaceDetectorPrivate.cpp", "seeta/graphics2d.cpp", "seeta/ImageProcess.cpp", ] include_dirs = [ "./", "./seeta", "./include", "include/seeta", "../SeetaNet/include/" ] deps = [ "../SeetaNet" ] configs = [ ":lib_config" ] part_name = "SeetafaceApi" } ``` - ohos_shared_library即为最终生成的模块名,这里代表此模块为最终生成ibFaceDetector.so - sources该模块需要编译的源码文件 - include_dirs该模块编译依赖的头文件路径 - deps 该模块编译依赖其他模块 - configs该模块编译配置的环境变量 特别说明,configs中的配置如若是填写在ohos_shared_library中的化,最终会被系统配置替换掉,因为需要将configs的内容写在ohos_shared_library之外。 - part_name 该模块编译依赖的编译子系统组件名。该配置项是为了模块最终生成的so文件能在系统编译完后自动拷贝到系统目录中。如果没有配置该项,系统编译完后是不会自动将生成的so文件拷贝到系统目录。 以上gn内容根据每个模块内容自行编写即可。 #### 编译 在对应依赖SeetaFace2的项目中添加以下依赖 ``` deps += [ "//third_party/SeetaFace2:SeetaFace2" ] ``` 根据项目的编译规则进行编译即可,此处以编译rk3568开发板为例,即对应的demo添加以上依赖后直接执行 ``` ./build.sh --product-name rk3568 --ccache ``` 最终在out目录的lib下可以看到生成的so文件: ![so文件](media/so.png) #### 测试 ##### 选择测试用例编译 本文用了库中自带的测试用例的crop_face用例来测试库的对应功能,本用例主要测试人脸检测功能。 ##### 测试用例gn化 ``` import("//build/ohos.gni") config("lib_config") { cflags_cc = [ "-frtti", "-fexceptions", "-DCVAPI_EXPORTS", "-DOPENCV_ALLOCATOR_STATS_COUNTER_TYPE=int", "-D_USE_MATH_DEFINES", "-D__OPENCV_BUILD=1", "-D__STDC_CONSTANT_MACROS", "-D__STDC_FORMAT_MACROS", "-D__STDC_LIMIT_MACROS", "-O2", "-Wno-error=header-hygiene", ] } ohos_executable("crop_face"){ sources = [ "example.cpp" ] include_dirs = [ "./", "./seeta", "../../SeetaNet/include/", "../../FaceDetector/include", "../../FaceLandmarker/include", "../../FaceRecognizer/include", "//third_party/opencv/include", "//third_party/opencv/common", "//third_party/opencv/modules/core/include", "//third_party/opencv/modules/highgui/include", "//third_party/opencv/modules/imgcodecs/include", "//third_party/opencv/modules/imgproc/include", ] deps = [ "../../FaceDetector", "../../FaceLandmarker", "../../FaceRecognizer", "../../SeetaNet", "//third_party/opencv:opencv", ] configs = [ ":lib_config" ] part_name = "SeetafaceApi" } ``` ohos_executable 代表需要该模块生成的是可执行程序。 其他和库模块中的意义一致。 特别声明,因为测试用例中使用了opencv开源库,该库已经完全移植到openharmony中,下载地址:[opencv下载](https://gitee.com/huangminzhong/opencv)。 ##### 代码修改及编译 - 顶层gn加上测试用例的依赖 ``` "example/crop_face", ``` - 由于已移植的opencv不支持png,固需要将测试用例中的png改为jpg。 - 修改完后直接运行编译指令,最终将在对应的out路径下生成可执行文件。 ![bin文件](media/bin.png) ##### 运行结果 将so文件通过hdc工具上传到系统的/system/lib下,然后将crop_face以及modle模型文件,1.jpg的测试图片上传到系统根目录下,通过串口工具运行程序,如图:  ![run app](media/run.png) 最终生成crop_face.jpg。该图效果是从一个全身像中识别到人脸部分并将其截取保存。如图所示,上图为原图,下图为识别后的图。  1.jpg  ![crop_face.jpg](media/crop_face.jpg) ### 参考文件 [人脸识别SeetaFace2开源地址](https://gitee.com/mirrors/SeetaFace2/tree/master) [人脸识别SeetaFace2原理与代码详解](https://blog.csdn.net/weixin_45915902/article/details/103205423) [openharmony源码获取](https://gitee.com/openharmony/docs/blob/OpenHarmony-3.1-Beta/zh-cn/device-dev/quick-start/quickstart-lite-sourcecode-acquire.md)