YOLOv5-Face | 原理超精细讲解、训练步骤还原、C++边缘部署(就要这么学!!!)(二)

简介: YOLOv5-Face | 原理超精细讲解、训练步骤还原、C++边缘部署(就要这么学!!!)(二)

4开启训练


4.1 下载源码

git clone https://github.com/deepcam-cn/yolov5-face

4.2 下载widerface数据集

下载网址:

https://drive.google.com/file/d/1tU_IjyOwGQfGNUvZGwWWM4SwxKp2PUQ8/view?usp=sharing

下载后,解压缩位置放到yolov5-face-master项目里data文件夹下的widerface文件夹下。

4.3 运行train2yolo.py和val2yolo.py

把数据集转成yolo训练用的格式。完成后文件夹显示如下:

4.4 运行train.py

过程显示如下:


5OpenCV-C++部署


5.1 参数配置

该部分主要是输入输出尺寸、Anchor以及Strides设置等

const float anchors[3][6] = { {4,5,  8,10,  13,16}, 
                               {23,29,  43,55,  73,105},
                               {146,217,  231,300,  335,433} };
 const float stride[3] = { 8.0, 16.0, 32.0 };
 const int inpWidth = 640;
 const int inpHeight = 640;
 float confThreshold;
 float nmsThreshold;
 float objThreshold;

5.2 模型加载以及Sigmoid的定义

该部分主要设ONNX模型的加载。

YOLO::YOLO(Net_config config)
{
 cout << "Net use " << config.netname << endl;
 this->confThreshold = config.confThreshold;
 this->nmsThreshold = config.nmsThreshold;
 this->objThreshold = config.objThreshold;
 strcpy_s(this->netname, config.netname.c_str());
 string modelFile = this->netname;
 modelFile += "-face.onnx";
 this->net = readNet(modelFile);
}
void YOLO::sigmoid(Mat* out, int length)
{
 float* pdata = (float*)(out->data);
 int i = 0; 
 for (i = 0; i < length; i++)
 {
  pdata[i] = 1.0 / (1 + expf(-pdata[i]));
 }
}

5.3 后处理部分

这里对于坐标的处理和YOLOV5保持一致,但是由于多出来Landmark,所以也多出了这一部分的处理:

if (box_score > this->objThreshold)
     {
      // 该部分与yolov5的保持一致
      float face_score = sigmoid_x(pdata[15]);
      float cx = (sigmoid_x(pdata[0]) * 2.f - 0.5f + j) * this->stride[n];  ///cx
      float cy = (sigmoid_x(pdata[1]) * 2.f - 0.5f + i) * this->stride[n];   ///cy
      float w = powf(sigmoid_x(pdata[2]) * 2.f, 2.f) * anchor_w;   ///w
      float h = powf(sigmoid_x(pdata[3]) * 2.f, 2.f) * anchor_h;  ///h
      int left = (cx - 0.5*w)*ratiow;
      int top = (cy - 0.5*h)*ratioh;   
      confidences.push_back(face_score);
      boxes.push_back(Rect(left, top, (int)(w*ratiow), (int)(h*ratioh)));
      // landmark的处理
      vector<int> landmark(10);
      for (k = 5; k < 15; k+=2)
      {
       const int ind = k - 5;
       landmark[ind] = (int)(pdata[k] * anchor_w + j * this->stride[n])*ratiow;
       landmark[ind + 1] = (int)(pdata[k + 1] * anchor_h + i * this->stride[n])*ratioh;
      }
      landmarks.push_back(landmark);
      //}
     }


6参考


[1].https://github.com/hpc203/yolov5-face-landmarks-opencv-v2

[2].https://github.com/deepcam-cn/yolov5-face

[3].YOLO5Face: Why Reinventing a Face Detector

[4].https://zhuanlan.zhihu.com/p/375966269

相关文章
|
1月前
|
C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(二)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
1月前
|
编译器 C++ 开发者
【C++】深入解析C/C++内存管理:new与delete的使用及原理(三)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
1月前
|
存储 C语言 C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(一)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
4月前
|
存储 C++ Cloud Native
云原生部署问题之C++ 中的 nullptr 和 NULL 区别如何解决
云原生部署问题之C++ 中的 nullptr 和 NULL 区别如何解决
58 0
|
1月前
|
C++
C++番外篇——虚拟继承解决数据冗余和二义性的原理
C++番外篇——虚拟继承解决数据冗余和二义性的原理
39 1
|
1月前
|
算法 Java C++
【贪心算法】算法训练 ALGO-1003 礼物(C/C++)
【贪心算法】算法训练 ALGO-1003 礼物(C/C++)
【贪心算法】算法训练 ALGO-1003 礼物(C/C++)
|
1月前
|
算法 C++
蓝桥 算法训练 共线(C++)
蓝桥 算法训练 共线(C++)
|
2月前
|
图形学 C++ C#
Unity插件开发全攻略:从零起步教你用C++扩展游戏功能,解锁Unity新玩法的详细步骤与实战技巧大公开
【8月更文挑战第31天】Unity 是一款功能强大的游戏开发引擎,支持多平台发布并拥有丰富的插件生态系统。本文介绍 Unity 插件开发基础,帮助读者从零开始编写自定义插件以扩展其功能。插件通常用 C++ 编写,通过 Mono C# 运行时调用,需在不同平台上编译。文中详细讲解了开发环境搭建、简单插件编写及在 Unity 中调用的方法,包括创建 C# 封装脚本和处理跨平台问题,助力开发者提升游戏开发效率。
222 0
|
4月前
|
程序员 编译器 C语言
云原生部署问题之C++中的nullptr相比C语言中的NULL优势如何解决
云原生部署问题之C++中的nullptr相比C语言中的NULL优势如何解决
55 10
|
5月前
|
大数据 C++ 索引
C++ STL标准库 《vector向量原理与实战分析》
C++ STL标准库 《vector向量原理与实战分析》
56 0
下一篇
无影云桌面