libfacedetection 框架阅读及扩展经验

2022 年您需要了解的 10 大计算机视觉框架 阅读详情

前段时间因为工作需要,对libfacedetection框架做了些扩展,在阅读源码过程中收获良多,做博客记录以加深理解。同时感谢深圳大学于老师团队开源该优秀代码。github地址

1. libfacedetection 框架简介

从名字可以看出来,这个项目是专门为人脸检测而生。其主要优势就是运行速度高,不依赖其他第三方库。运行效率结果对比在作者的github项目上都有介绍,这里就不再赘述了。虽然后来有其他框架号称可以与libfacedetection框架一较高下,甚至更快,但不得不说libfacedetection在当时的前向推理速度还是很值得让人对其代码探索一番的。
为什么可以这么快,作者主要使用了三个策略:1 . 地址分配得当,从而使得conv,pooling等含有大量运算的模块可以做到连续访存。2. arm上的neon加速指令和intel cpu上的avx2加速指令的使用,这两个指令集分别可以使得连续四地址或者连续八地址的内存进行并行计算。1,2策略的结合使得运算速度大大提高。3. 对计算量最大的conv模块进行了量化操作,开发了对应的int类型运算。
下面的内容会以代码和图例的形式详细介绍。当然,因为作者只针对该项目做了特定层的开发,为了不浪费这么好的开源框架和适配我们自己常用的模型,我们需要对该框架进行扩展,所以该篇博客会以两部分展开:源码解析 ,其他层的扩展。

2. 源码解析

libfacedetection的代码量不大,主要有三个文件,一个头文件,两个源文件。我们先看一下头文件里面做了什么。

  • facedetection.h
  • facedetectcnn.cpp
  • facedetectcnn-model.cpp

2.1 facedetectcnn.h

头文件中除了定义了一些结构体,最主要的是做了CDataBlob类定义, 这个类用来模拟caffe中的blobData, 用于层与层传输数据,保存运算结果。这里的CDataBlob是以 C, W, H 的顺序来存储数据的三维数组,并没有实现caffe中 blobData 的 N, C, H, W 里面的N维度,而是用一个 vector<CDataBlob *>类型的变量存储多个CDataBlob类来模拟N (貌似caffe中也是类似的实现方式,没太细看),总之这里想表达的是CDataBlob并不是地址连续的四维数组,层与层的传输数据是vector类型,而vector里面的每个成员是一个地址连续的三维数组,这里拿一张图片作为例子,格子里面的数字用来表示存储地址。可以看见libfacedetection中构造,存储数据的方式。
libfacedetection中层与层之间传递的blob存储顺序

当然,作者为了地址对齐(通道对齐),还做了额外操作。在创造维度是C,W,H大小的CDataBlob类型数据的时候,会对C维度大小进行补齐操作,使其扩展为4或者8的倍数(根据使用neon指令集还是avx2指令集策略有所不同),也就是说上面图例中地址存储顺序其实还不太准确,严格来说会变成以下图示,比如输入是三通道的数据会被多添加一层全是0的数据变成四通道,这样在后续neon指令集加速可以使得四个连续地址并行运算,提高效率。当然avx2指令可以8个连续地址并行运算,所以会补齐一定通道数使得总通道数是8的倍数,比如最开始的3通道的输入会被再补上5个都是0的通道变成8通道输入,方便后续计算。
扩展通道数,CWH顺序存储
整个.h文件基本上就是做了这么一件事情:定义CDataBlob类和其存储数据的格式。

2.2 facedetectcnn.cpp

这个源文件就是实现了我们一些常见的运算模块,比如convolution, pooling, relu等,这里不会过多介绍运算原理,太多数学和公式不是本篇博客的重点,举一个3x3卷积的例子来看下作者在层与层之间加速运算的实现和输出数据的存放格式。我们拿48x48x32的输入与64x32x3x3维度大小的权重做卷积运算举例。输入如左边所示,其中用黄色标出的是第一次做卷积时,3x3大小的滑动窗口在输入图像上的位置,右边如上所述用vector< CDataBlob *>类型变量存储64个卷积核,每个卷积核是32x3x3大小,都是按照CDataBlob地址要求存放权重。
在这里插入图片描述把向量展开,进行卷积运算,过程如下图所示。以vector[0]绿色卷积核和输入的前3x3大小的窗口(黄色)做卷积为例,9对向量点乘之和便是输出数据的第一个通道的地址0应该存放的数值。接着输入从地址0开始再和vector[1] 粉色的卷积核进行同样的点乘求和操作,得到的数据存放在输出blob的第二个通道地址为1的位置。重复64次,输出数据的最左上角的64个通道(对应地址为0-63)的数据就都得到了,接着按W,H方向遍历滑动输入的窗口,就可以得到输出blob的所有数值。作者在向量点乘函数dotProductFloatChGeneral中对四个连续地址做neon指令集加速,所以conv层加速主要在点乘函数中实现。其中注意9对向量做点乘运算时候,卷积核的9个向量地址一直都是连续的,而输入的9个向量,前三个地址连续,中间三个地址连续,后三个地址连续,所以是分三步调用了向量点乘函数。
在这里插入图片描述
其他层比如maxpooling,Prelu等层的实现思想和这个大同小异,就不多加介绍了。

2.3 facedetectcnn-model.cpp

这个源文件的作用完全类似于caffe中的prototxt的作用–定义网络结构。该源文件可以认为做了三件事情,1. 定义卷积核,偏置项,全连接层等(只要含有权重的)层的维度大小,也就是声明存储这些权重的数组维度大小。2. 将从.caffemodel文件读取的一系列权重值初始化到在第一步中声明的数组中,并构建CDataBlob类和<vector CDataBlob*>类型数据。3. 利用2.2中提到的源文件中定义的各种运算模块,来搭建网络结构。每一步放部分代码块大概看一下:

//1. 声明各参数,比如conv的 kernel_size,stride,padding,number,group大小
ConvInfo param_pConvInfo[NUM_CONV_LAYER] = {
   
   
    //conv1
    {
   
   1, 1, 1, 3, 3, 3, 32},
    //conv2
    {
   
   1, 1, 1, 3, 3, 32, 64},
    //conv3
    {
   
   
实时人脸五观检测:基于libfacedetection(CNN模型) 当前项目里,通过使用OpenCV库打开摄像头,调用"libfacedetection"库,实现实时人脸检测并将识别出的人脸面部和五官位置标注出来。 阅读详情

相关推荐

Unity 2D精灵点击交互实现:从BoxCollider 2D到Event Trigger的完整指南

本文提供了Unity 2D精灵点击交互的完整实现指南。通过详细拆解BoxCollider 2D与Event Trigger两大核心组件的协同工作原理,手把手教你为Sprite Renderer添加点击、悬停等事件响应。文章包含从基础配置到进阶优化、性能调试的实战步骤,帮助开发者高效实现游戏世界内的对象交互,是Unity 2D开发的实用教程。

ansible6ops的博客 295

Windows 下 Codex MCP 服务配置全攻略:从环境搭建到实战避坑

本文详细介绍了在Windows系统下配置Codex MCP服务的完整流程与实战避坑指南。内容涵盖从Node.js环境搭建、Codex CLI安装,到核心配置文件config.toml的编写与解析,并重点解决了Windows平台特有的环境变量设置、MCP服务启动命令适配等关键难点,帮助开发者顺利完成从环境准备到编辑器插件连接的整个配置过程。

weixin_28826545的博客 2055

URDF模型转换实战:解决SolidWorks到Gazebo的五大常见问题

本文详细解析了从SolidWorks导出URDF模型到Gazebo仿真过程中常见的五大问题及解决方案,包括插件安装、坐标系建立、Link与Joint配置等关键步骤。通过实战经验分享,帮助机器人仿真工程师高效完成模型转换,确保Gazebo仿真准确性。

weixin_29052717的博客 435

【Unity动画系统】详解Root Motion动画在Unity中的应用(一)

什么时候勾选Bake into pose,当不希望动画带动游戏对象旋转时。在旋转的动画中一般是不用勾选的,因为就需要用它来带动我们的角色对象旋转。但在比如前进、后退、待机等动画来说,我们就可以勾选这里,以避免因动画文件本身的瑕疵而给我们带来的旋转。loop match:代表了这个动画在角度上的吻合度。如果这个动画在播放中转角过大,那么就会显示红色,告诉我们如果勾选bake into pose,则会带来不好的效果。

weixin_60154963的博客 6798

Spring WebFlux响应式编程实战(三):优雅处理异常与高效调试技巧

本文深入探讨了Spring WebFlux响应式编程中的异常处理与调试技巧。文章通过电商订单流处理场景,详细解析了Reactor核心操作符onErrorReturn、onErrorResume和onErrorMap的实战应用,并介绍了如何构建@ControllerAdvice和WebExceptionHandler全局异常处理防线。同时,提供了使用.log()操作符、Hooks.onOperatorDebug()及BlockHound进行高效调试的方法,旨在帮助开发者构建健壮、可维护的响应式应用。

weixin_29252171的博客 57

七段数码管动态显示技术:分时复用与使能端优化

本文深入解析了七段数码管动态显示技术的核心原理,重点阐述了分时复用与使能端优化如何协同工作。通过利用人眼视觉暂留效应,分时复用技术以一套数据线驱动多个数码管,而合理的使能端控制则是消除鬼影、保证亮度均匀的关键。文章提供了从硬件基础到Verilog代码实战的完整指南,帮助开发者实现稳定高效的动态显示系统。

lilh34434的博客 205

AI+Xmind自动生成测试用例(思维导图格式)

最后:我是Walker,一个热爱分享编程知识的程序员,希望能够帮助到你!

Think_and_work的博客 2321

FPGA八股文(2)——笔试的FPGA问题汇总(持续更新)

常见FPGA笔试题的概念总结

居安士的博客 8883

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

下一篇: 基于华为Holosens Store的调研
Rick51
博客等级 码龄8年 7粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值