最近想试一下使用Yolov4做目标检测的效果,想要用最快的速度做出效果来,尝试了使用pytorch,
但是由于需要转换为C++,把训练好的pth文件转换为pt文件应用的过程中出现了各种各样的问题,暂时不想花费大量的时间在这件事情上,所以转而选择了直接使用darknet。
以下全程使用windows,各项配置不发生变化。
测试过程中有一个小发现:我自己训练用的图像是三通道的图像,训练出来的模型用在单通道图像上也是可行的,至少没有出错。
使用Darknet对已在coco数据集上训练好的模型做目标检测
darknet版本:2021.4.7的ID为e83d6526的提交
环境:
Win10
RTX 2060 6G
cuda 11.1
cuDNN 8.0.5 for cuda11.1
opencv 3.4.2
vs2019
darknet e83d6526
部署步骤参考下面的链接,有几条注意事项写在下面了,配合教程食用更加:
WIN10+YOLOv4,windows上完美执行YOLOv4目标检测
注意:
- 通过查看
darknet.vcxproj
文件,发现此版本下依赖cuda11.1,上面的参考步骤中使用了cuda10.2,需要注意。 - 安装了多个版本的cuda的情况下要注意有坑,简单粗暴的方法是把其他版本的cuda卸载掉。由于对cuDNN的版本有要求,千万不要偷懒,因为以前有安装过其他版本的cuDNN,就没有下载对应的版本,版本不对是一个很大的坑。
- opencv的版本建议一定要按照上面那个教程中的来,用其他版本有可能会有问题;配置的opencv库目录用的是vc14,这里可以改成vc15,亲测没有问题,有高版本的我还是倾向于选择高版本的。
- nvidia的账号建议注册一个,不麻烦,下东西会方便很多。
- 教程中让配置的各种环境变量,都配置一下,可以避免之后遇到的很多问题,如果遇到环境变量Path过长的问题,可以先将一些较长的路径设置设置为名称较短的系统变量,然后添加到Path中。
- 全都配置好之后打开项目编译,按照上面的步骤应该会编译通过,如果没有通过不要慌,看错误,缺什么文件补什么文件,可能出现缺少某些opencv相关的dll或者lib文件,简单粗暴的方法是缺什么就把什么放到程序目录下;我还遇到过编译结果只提示有一个错误,但是错误列表中什么都没有的情况,排查后发现是cuda版本的问题。
- 官方给出的windows上darknet编译,让使用cmake来,没有这个必要,反而对于不熟悉cmake的人来说,会出问题,直接编译darknet.sln下面的项目就好了。包括其他几个项目,如果不熟悉cmake,也直接编译对应的项目就好了。
使用Darknet训练自己的模型
全程参考了darknet在GitHub上的README,其中对于训练过程做了详细的说明,除了是用英文写的,这份说明非常的完整。
指路:How to train (to detect your custom objects)
注意:
- 图片的标记使用了说明中的Yolo_mark来标记,需要下载下来自己编译,一般不会遇到太大的问题,opencv的目录该配置的还是配置一下。标记的时候有一些快捷键还挺好用的,不用鼠标去点标签和图片了,可以提高效率,具体输入
h
可以看帮助,我常用的是←
、→
和数字键。 - 训练过程中出现了显存不够的问题,有一些官方提供的解决方案:What does the error message "CUDA Error: out of memory" mean during training?。
我自己改了图片大小,还把subdivisions
改成了128,似乎有点夸张了。 - 在知道自己显卡不太够用刚好能够跑起来的情况下,不要作死在训练的过程中运行其他很占用显存的程序,会导致训练断掉,特别是weights文件一个都还没有保存的情况下。
- 训练的那行命令不要完全按照说明中写的来,路径要按照实际路径来,怕有问题索性就写完整路径,如果出现加载图片失败的情况,基本上就可以确定就是路径出问题了,包括train.txt中的图片路径。
- 训练完后可以用训练的模型按照上面的方法看一下检测效果。
Windows上C++使用Yolo官方提供的办法调用自己训练好的模型
指路官方:How to use Yolo as DLL and SO libraries
简要概括:
- 第一步是要编译出yolo_cpp_dll.dll和.lib文件,直接编译yolo_cpp_dll.sln那个解决方案中的项目,编译过程中可能出错,
建议直接按照编译darknet时候的配置,可以减少很多出错的可能性,但是还是有可能出错,
我遇到了一个cuda相关的错误,需要把下图这个地方配置一下,去掉一些内容。
- 调用代码参考:C++调用YOLOV4模型进行目标检测-使用YOLOV4官方接口,这篇文章唯一的问题就是他是在Linux上调用的,而我要在Windows上调用。
- 自己的项目中要把yolo_cpp_dll.lib文件放进来,添加进链接器的附加依赖项中,
yolo_v2_class.hpp
这个文件也记得放进来,其他的一些项目配置,参考darknet,该放进来的都放进来,编译过程中遇到链接之类的错误,一般就是附加依赖项中少配置了什么东西,总体上跑不出这些文件。 - 直接搬上面的文章中的代码有点小问题,因为它是Linux系统中运行的,用了一些Linux系统自由的和时间相关的库,相关内容去掉或者改成合适的就好了,当然,梳理一下代码,自己写出适合自己的就更合适了。