ZYNQ(ARM)部署人脸检测模型libfacedetection

        历经无数坑坑洼洼,终于让我坚持更新了【猛男落泪】。ZYNQ成功部署libfacedetection,输入640*480 单帧平均耗时约为25ms,也算看到一丝丝希望了,但是离目标还差一点,后期还有备用优化方案,继续坚持吧!

一、前言

        在上一篇博文中,在Ubuntu中搭建人脸检测模型libfacedetection,由于该模型是针对嵌入式设备设计的轻量级人脸检测模型,为纯C++编写,之前大多数都是部署基于python的模型,突然有点不知所措了~ 在Ubuntu实验中熟悉了cmake编译,包括shell脚本语法、CMakeList脚本语法等等,本博客主要在开发板ZYNQ7035的ARM端部署人脸检测模型,因为Ubuntu系统和开发板的ARM系统架构不一样,这里就设计到交叉编译了~

二、实验过程

1. 准备条件

1.1. 首先要明确目标系统的架构

        之前在Ubuntu16.04上进行模型部署,是不能直接搬过去开发板使用的,因为Ubuntu架构是ARM 64位,而zynq开发板的架构是ARM 32位,这一步很关键,决定了所有依赖换源的版本型号都要和系统架构匹配。因为编译环境是在Ubuntu上进行,跨系统架构编译则需要进行交叉编译。

Ubuntu 系统架构

ZYNQ ARM 系统架构

1.2. 提前准备好编译环境

        主要得先下载libfacedetection源码(参考链接)、Opencv源码(这里采用3.4.1版本)、交叉编译工具链(这里采用了vivado库下的arm-linux-gnueabihf-g++,本来是想安装Xilinx SDK 2017.4,奈何Ubuntu不能直接安装SDK,则通过Vivado间接安装,不过对后期需要引进FPGA设计还是有帮助的,或者其他自行下载)。其实主要需要准备的就这么多了,得益于这个模型它依赖三方库太少了,便于部署,赞!

2. 实验过程

2.1. 配置编译环境

        在编译Opencv之前需要先设置好编译环境,一些底层的依赖库、cmake、包括设置交叉编译工具链。

2.2. 交叉编译Opencv

        此步骤主要参考芯驿站电子科技的《ZYNQ 开发平台 Linux 应用教程》-第二章 OpenCV 应用,先下载好教程提供的opencv源码包,使用cmake进行编译安装确实有点麻烦,不像Ubuntu几行命令就可以搞定,camke编译就是为系统量身定做一套opencv环境,因为完整的opencv库非常庞大,部署到嵌入式系统占用较大资源,于是可以根据特定需要进行编译安装,其所有功能库保存于src_pkg文件夹下。但是,其中opencv的版本是3.1.0,踩过小坑,在libface模型中用到的个别库需要opencv3.4.1以上版本才能兼容,所以自行下载opencv3.4.1源码替换掉该文件夹下的opencv源码,接着就可以开启编译工程之路啦~

        主要是通过shell脚本设置编译环境,里边采用了Xilinx SDK的交叉编译工具,如果有自己的编译工具可以替换掉,还有Opencv的版本需要更改,再就是根据预设功能通过修改cmake参数选择开关对应的功能,虽说heijin教程有点粗糙,但至少可以用,就是比较费劲,看懂脚本文件后就可以举一反三啦。当编译通过后,会在当前文件目录生成一个zynq_opencv_lib文件夹,里边包含了Opencv动态库,然后可以运行make_img.sh文件结合opencv_env_set.sh生成镜像文件(我的理解就是,将多个子文件合并在设定的内存空间中,最后生成img镜像文件,可以通过挂载来访问所有的子文件),最后得到一个好东西:zynq_cv_lib.img。

2.3. 交叉编译libface

        在编译libface源码之前一定要先安装好opencv,没有妈就没有孩子。经历了opencv编译后相信这一步就轻松一点了,建议详细阅读libface模型github上的说明,正常来说通过以下命令就可以正常编译安装了,但似乎少了点啥,opencv库路径都不用指定了吗?看回CMakeLists.txt中find_package(OpenCV REQUIRED) 就可以自动寻找系统中的opencv库了6!但是啊!

   cd libfacedetection
   mkdir build
   cd build
   cmake .. -DCMAKE_INSTALL_PREFIX=install -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release -DDEMO=OFF
   cmake --build . --config Release
   cmake --build . --config Release --target install

我们是要将编译得到的动态库放到zyqn的ARM端进行调用,则需要在上面命令基础上加入交叉编译链!完全可以参考opencv编译过程,举一反三:(具体路径需要根据自己情况更改,已开启NEON)

SDK_PATH=/opt/SDK/install_path/SDK/2017.4
if [ ! -d $SDK_PATH ]; then
  echo "no dir ${SDK_PATH}"
  exit 1
fi

source ${SDK_PATH}/settings64.sh 
export PKG_CONFIG_LIBDIR=${SDK_PATH}/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/lib
export CROSS_COMPILE=arm-linux-gnueabihf  
mkdir build
cd build
echo "set( CMAKE_SYSTEM_NAME Linux )" > toolchain.make
echo "set( CMAKE_SYSTEM_PROCESSOR arm )" >> toolchain.make
echo "set( CMAKE_C_COMPILER ${CROSS_COMPILE}-gcc )" >> toolchain.make
echo "set( CMAKE_CXX_COMPILER ${CROSS_COMPILE}-g++ )" >> toolchain.make
echo "set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )" >> toolchain.make
echo "set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )" >> toolchain.make
echo "set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )" >> toolchain.make

cmake .. -DCMAKE_INSTALL_PREFIX=install -DBUILD_SHARED_LIBS=ON -DDEMO=OFF -DUSE_OPENMP=ON -DCMAKE_TOOLCHAIN_FILE=toolchain.make -DENABLE_NEON=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS:STRING="-march=armv7-a -mfloat-abi=hard -mfpu=neon -mtune=cortex-a9 -Wno-psabi" -DCMAKE_C_FLAGS:STRING="-march=armv7-a -mfloat-abi=hard -mfpu=neon -mtune=cortex-a9 -Wno-psabi" -DCMAKE_ASM_FLAGS:STRING="-march=armv7-a -mfloat-abi=hard -mfpu=neon -mtune=cortex-a9 -g"
make

此处有个细节就是开启了OPENMP编译优化和NEON指令加速(cmake参数中),因为涉及实时性,肯定要发挥出硬件最大的性能,libface模型支持NEON指令实现并行加速,则需要确定自己的系统是否支持该指令:

若模型库编译开启了NEON,则需要修改模型文件:(实测开启了NEON确实会小幅度提升速度)

2.4. 交叉编译测试历程

        以上两个步骤都是为最后测试程序做准备的,同样,因为程序要放到zynq运行就需要进行交叉编译,编译脚本同样借用libface源码编译的脚本,但是当时编译遇到个错误,要指定Opencv库路径,纳闷了呀哥们儿?为何libface源码不需要呢?是Ubuntu本地已经有一个opencv了,导致冲突,具体可看问题汇总解决

这里编译通过后会在build文件夹下生成image 和 camera例程的执行文件。DNA动了啊:C++编译打印Hello work!

2.5. petalinux 搭建Linux系统

       到此,动态库和例程都准备好啦,该放到哪里执行呢?zynq arm开发主要有两种方式:裸机开发和基于Linux开发,显然,本实验需要通过磁盘挂载配置实验环境,则需要操作系统来实现(鄙人的见解,若有其他看法请指正哈)。

        petalinux可以自定义Linux系统,刷新了认知,但这个入门有点难,得从底层去理解Linux系统,包括内核、根文件系统、设备树、驱动、boot、FSBL等,但是,要开发zynq中的arm联合FPGA,这个是逃不过的,其中FPGA部分属于硬件设计,可在vivado上完成设计并导出硬件描述文件,再通过petalinux设计整合到系统中。但在此实验中偷懒一下:芯驿站电子《ZYNQ 开发平台基础教程》第二十九章,直接就可以启动系统了~

2.6. 运行测试例程

        首先通过nfs将本地目录挂载到系统板的/mnt,这样方便文件传输和挂载。然后,在开发板/tmp上新建一个文件用于挂载opencv镜像库,挂载成功后会在指定目录下生成所有动态库和配置环境文件,运行该文件即可将opencv库设置为系统环境变量。同样的操作设置libface模型的环境。(指令并非完全适用,需根据自己情况做修改)

mount -t nfs -o nolock 192.168.xx.xx:/home/alinx/work /mnt 
#设置opencv环境变量
cd /mnt
mkdir /tmp/opencv
mount zynq_cv_lib.img /tmp/opencv
cd /tmp/opencv
source ./opencv_env_set.sh
#设置libface环境变量
cd /mnt
mkdir /tmp/libface
mount libface.img /tmp/libface
cd /tmp/libface
source ./libface_env_set.sh

        通过设置好依赖库环境变量后即可还是运行程序,通过nfs将实验例程共享至开发板,并在开发板插入usb摄像头,运行程序即可输出结果,由于开发板系统问题,在运行程序时,显示没有包含GTK可视化窗口的库,尝试多种方法无果,最后,妥协通过命令行输出结果,并将摄像头读取结果进行保存成视频文件进行可视化输出。

        

三、总结

        整个过程的探索算是跌宕起伏啊,主要是基于ZYNQ的ARM开发参考比较少,还得自己慢慢摸路。感觉到这个libface模型真的很强大,发现影响它速度的竟然直接根输入图片尺寸有关,而对人脸个数多少影响不大,再则对侧脸和低分辨率适配得很好,使得在嵌入式低性能设备有更多的发挥空间,但这个速度还需要再优化一下,接着先去了解整个模型然后再从算法上进行优化~

        整个实验过程也耗费不少时间,主要是在 做实验过程中,感觉总把自己埋进去,就会搞晕头脑,没那捏住主次,导致周期长了点,过程中的一些问题和踩过的坑也汇总到问题集,大家可以一起学习,本实验过程大多为个人实践之谈,存在不合理的地方还请指正,也欢迎有兴趣的大佬带我学习哈哈哈!

基于ARM的ZYNQ部署人脸检测模型问题汇总-CSDN博客

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值