yolo_v3代码解析以及相关注意事项(代码片段)

koushihao koushihao     2022-11-11     489

关键词:

[TOC]

1. 项目介绍

$~~~~~~~$本次YOLO_v3的项目来源于机器之心翻译的项目---从零开始PyTorch项目:YOLO v3目标检测实现以及从零开始 PyTorch 项目:YOLO v3 目标检测实现(下)两部分组成,原版的博客在此Series: YOLO object detector in PyTorch,原始博客的GitHub地址为:ayooshkathuria/pytorch-yolo-v3,最后附上论文的地址:YOLOv3: An Incremental Improvement

2. 项目需求及相关文件解释

$~~~~~~~$YOLO_v3官方原始的代码是由C语言所写,真是佩服作者手撸代码能力啊,但是由于源码并没有相关的任何注释,阅读起来特别费事,所以参考了网上关于YOLO_v3迁移到$Tensorflow$和$Pytorch$的代码进行阅读,以便对代码有更深的认识和理解。

$~~~~~~~$关于此YOLO_v3的$Pytorch$的代码,其$Pytorch$作者的GitHub提到相应的需求如下:

  • Python3.5
  • OpenCV
  • Pytorch 0.4(其中作者提了一句:$Using$ $PyTorch$ $0.3$ $will$ $break$ $the$ $detector.$)

$~~~~~~~$在准备好相应的东西之后将相应的项目$Clone$ $or$ $downoad$下来,除此之外你首先需要下载$weights$ $file$(权重文件),地址如下:a weightsfile only for COCO,大小有237M,下载下来的权重文件只需放在下载好的$project$根目录下即可,权重文件名为:yolov3.weights

$~~~~~~~$一切准备就绪就可以进行图片检测了,如果想要检测图片,可以在$Pycharm$的底部栏找到$Terminal$,也就是$CMD$,将地址$cd$到你下载的项目所在的地址,如:D:\软件安装\pycharm\PyCharm Community Edition 2017.3.3\workplace\yolo_tensorflow-master>,然后在$Terminal$中输入:python detect.py --images imgs --det det命令即可,其中 --images代表定义图片存储或加载的文件夹,而--det代表检测完图片之后将检测图片保存起来的文件夹,当然,如果需要查看其它标记含义(例如:--bs),可以通过在命令行输入:python detect.py -h 或者直接代开$project$中detect.py文件查看arg_parse()函数下定义的参量进行查看。甚至直接运行detect.py文件也可以进行图片检测。

$~~~~~~~$如果你想检测视频,可以运行video.py进行检测,要在视频或网络摄像头上运行这个检测器,代码基本可以保持不变,只是我们不会在 batch 上迭代,而是在视频的帧上迭代。

$~~~~~~~$在视频上运行该检测器的代码可以在我们的 GitHub 中的 video.py 文件中找到。这个代码非常类似 detect.py 的代码,只有几处不太一样。这里需要注意的是,如果想要对视频进行检测需要将视频文件放入$projiect$的根目录中,而且在video.py文件中对视频定义的默认参数为:default = "video.avi",所以,你需要更改你视频文件的名称或者更改参数的默认设定。

3. 源码详细解析

$~~~~~~~$PASS

4. 源码中的问题

$~~~~~~~$在项目下载下来之后发现了源码有一些比较坑的地方,以至于部分代码无法运行,这里举出暂时所遇到的坑以及解决办法。

4.1 视频检测中遇到的问题:

$~~~~~~~$此处非项目:YOLO_v3_tutorial_from_scratch-master中视频检测遇到的问题,而是项目yolo_tensorflow-master中视频检测遇到的问题,只是在此将所有和YOLO代码相关的问题都列举出来,在项目yolo_tensorflow-mastertest.py中,第201-203行代码为摄像头检测的代码:detect from camera
代码中:cap = cv2.VideoCapture(0),原始的GitHub:hizhangp/yolo_tensorflow代码中为:cap = cv2.VideoCapture(-1),运行时造成摄像头开启后显示的图像为满屏幕的雪花噪点,无法检测到任何东西,需要将括号中的参数-1改为0方可正常开始摄像头进行检测。此项目yolo_tensorflow-master的解读参照知乎相关专栏:YOLO源码解析 作者:狗头山人七

4.2 图片检测中遇到的问题:

$~~~~~$此处遇到的问题非常的多和杂,将代码修改正确以正常运行耗费了我很多精力,在此一一列举,以备以后遇到类似情况。
$
~~~~~$技术分享图片

4.2.1 绝对路径与相对路径的问题

$~~~~~~~$刚开始运行图片检测代码(项目:YOLO_v3_tutorial_from_scratch-master)的时候直接报错,报的错误为:

$~~~~~$AttributeError: ‘NoneType‘ object has no attribute ‘shape‘
$
~~~$!!完全不知道错误的那种错!!
$
~~~~~$技术分享图片

$~~~~~~~$后来一堆百度,Google查证之后发现是报了一个空的对象没有shape这个属性的错误,可能是因为路径设置不对,所以返回的类型是None。后来通过bug排除发现是代码第126行:imlist = [osp.join(osp.realpath(‘.‘), images, img) for img in os.listdir(images)],这一行代码主要是用于生成图片所在的绝对地址:

D:\软件安装\pycharm\PyCharm Community Edition 2017.3.3\workplace\pytorch-yolo-v3-master\imgs\dog.jpg
D:\软件安装\pycharm\PyCharm Community Edition 2017.3.3\workplace\pytorch-yolo-v3-master\imgs\eagle.jpg
D:\软件安装\pycharm\PyCharm Community Edition 2017.3.3\workplace\pytorch-yolo-v3-master\imgs\giraffe.jpg
D:\软件安装\pycharm\PyCharm Community Edition 2017.3.3\workplace\pytorch-yolo-v3-master\imgs\herd_of_horses.jpg
D:\软件安装\pycharm\PyCharm Community Edition 2017.3.3\workplace\pytorch-yolo-v3-master\imgs\img1.jpg
D:\软件安装\pycharm\PyCharm Community Edition 2017.3.3\workplace\pytorch-yolo-v3-master\imgs\img2.jpg
D:\软件安装\pycharm\PyCharm Community Edition 2017.3.3\workplace\pytorch-yolo-v3-master\imgs\img3.jpg
D:\软件安装\pycharm\PyCharm Community Edition 2017.3.3\workplace\pytorch-yolo-v3-master\imgs\img4.jpg
D:\软件安装\pycharm\PyCharm Community Edition 2017.3.3\workplace\pytorch-yolo-v3-master\imgs\lisa.jpg
$~~~~~~~$技术分享图片

$~~~~~$这里我意识到可能此处的错误并非作者源代码的错误,而是作者在用这一句osp.join(osp.realpath(‘.‘)的时候获取的是绝对路径,而我的绝对路径包含了中文!!!!
$
~~~~~$技术分享图片

$~~~~~~~$所以为了解决这个问题,我需要将绝对路径修改为相对路径,以避免出现中文这个脑壳疼的问题(话说好多与bug有关的问题是出现路径有中文上!),修改方法就是上面的代码修改为:osp.join(osp.relpath(‘.‘),其中rel指的就是relative


4.2.2 斜杠‘/‘与反斜杠‘\‘的问题

$~~~~~~~$在上面的问题解决以后运行代码发现代码运行正常,但是最后保存检测图片的文件夹--det并没有任何图片存放其中,后来定位到存放图片的代码:

det_names = pd.Series(imlist).apply(lambda x: "/det_".format(args.det,x.split("/")[-1]))
list(map(cv2.imwrite, det_names, orig_ims))

$~~~~~~~$每张图像都以「det_」加上图像名称的方式保存。我们创建了一个地址列表,这是我们保存我们的检测结果图像的位置。最后,将带有检测结果的图像写入到 det_names 中的地址。

$~~~~~~~$其中det_name打印出来结果如下:

0 det/det_.\imgs\dog.jpg
1 det/det_.\imgs\eagle.jpg
2 det/det_.\imgs\giraffe.jpg
3 det/det_.\imgs\herd_of_horses.jpg
4 det/det_.\imgs\img1.jpg
5 det/det_.\imgs\img2.jpg
6 det/det_.\imgs\img3.jpg
7 det/det_.\imgs\img4.jpg
8 det/det_.\imgs\lisa.jpg
9 det/det_.\imgs\messi.jpg
10 det/det_.\imgs\person.jpg
11 det/det_.\imgs\scream.jpg
12 det/det_.\imgs\vagaa.jpg

$~~~~~~~$而imlist打印出来的结果为:

[‘.\imgs\dog.jpg‘,‘.\imgs\eagle.jpg‘, ‘.\imgs\giraffe.jpg‘,‘.\imgs\herd_of_horses.jpg‘, ‘.\imgs\img1.jpg‘,‘.\imgs\img2.jpg‘, ‘.\imgs\img3.jpg‘,

$~~~~~~~$下一句代码:list(map(cv2.imwrite, det_names, orig_ims))中:

$~~~~~$1.cv2.imwrite()函数:保存图片的函数,共两个参数,第一个为保存文件名,第二个为读入图片。
$
~~~$2. orig_ims:为list所包裹这的array矩阵,类型为无符号8位dtype=uint8,所以为图片的编码矩阵。
$
~~~~~$3.map()函数:会根据提供的函数对指定序列做映射。第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。语法为:map(function, iterable, ...),其中function -- 函数,有两个参数;iterable -- 一个或多个序列,例如:map(square, [1,2,3,4,5]),打印:[1, 4, 9, 16, 25],其中square(x)为一个函数,return x$^2$

$~~~~~~~$所以从上可以看出map函数将cv2.imwrite, det_names, orig_ims之间建立映射,其中det_names, orig_ims作为cv2.imwrite()的参数,其中一个作为保存文件名,一个作为读入的图片。

$~~~~~~~$运行此代码,显示:

[False, False, False, False, False, False, False, False, False, False, False, False, False]

$~~~~~~~$说明映射失败,图片存储不成功。而由det_name所打印的显示表明失败是由于文件名中存在反斜杠‘‘,反斜杠在python中有实际转义含义的,所以需要将反斜杠换为斜杠,不然运行的时候代码会将反斜杠一起运行。

$~~~~~~~$修改方法如下:

    for i in range(len(imlist)):
    imlist[i] = imlist[i].replace('\\', '/')
    

$~~~~~~~$此处还需要注意的就是imlist[i].replace(‘\‘, ‘/‘)会生成一个列表存放修改后的值,而不是在原本的列表imlist[]上进行修改。

$~~~~~~~$修改后的det_name为:

0 det/det_dog.jpg
1 det/det_eagle.jpg
2 det/det_giraffe.jpg
3 det/det_herd_of_horses.jpg
4 det/det_img1.jpg
5 det/det_img2.jpg
6 det/det_img3.jpg
7 det/det_img4.jpg
8 det/det_lisa.jpg
9 det/det_messi.jpg
10 det/det_person.jpg
11 det/det_scream.jpg
12 det/det_vagaa.jpg

$~~~~~~~$此时,反斜杠已经改为了斜杠,代码运行正常,且det文件夹也正常存放了检测后的图片,如下:
技术分享图片

5. 关于YOLO_v3作者

$~~~~~~~$在知乎中有一个问题是关于如何评价最新的YOLOv3?,非常有意思,列举如下一些有趣的点:

$~~~~~~~$1. 首先,YOLO_v3的论文根本就不算论文,更多的算是一片技术报告,读起来相当的欢乐。作者首先就诚实的表明自己去年没做什么研究,而是主要花在完Twitter上和玩了下GAN。
技术分享图片
技术分享图片


$~~~~~~~$2. 其次,yolo的作者编码能力真的强,darknet几乎不用啥依赖库,全部手撸,编译起来也是快到没朋友。而且,作业可能是个小马宝莉的迷吧,哈哈哈,蛮有意思,感觉像个小萌妹。看看他的resume、个人主页、git的commit message感受一下萌萌哒。
技术分享图片
技术分享图片
技术分享图片

$~~~~~~~$而他本人长这样:
技术分享图片


$~~~~~~~$3. 直接diss一众算法,例如他论文中出现的:
技术分享图片

这张图把自己放在第二象限,赤裸裸的表达你们这些都是辣鸡。。。。
这图应该作者从其他论文裁剪过来,再强行画上的;
实力嘲讽啊,取了Retina里面的图,然后diss一波


$~~~~~$4. 论文结尾亮点满满,挺佩服能把自己论文写的这么随意的,羡慕大佬:
技术分享图片
$
~~~~~$效果好到论文可以随意写,反正我效果摆在这里,论文写的再随意,你们还是要引用的。


$~~~~~$5. 而且有细心网友发现,模型一作在arXiv上发布研究论文时,脑回路清奇地将自己这篇论文自引自用了一下。
技术分享图片
$
~~~~~$而在小哥自引自用后没多久,arXiv官方账号宣布服务器由于不明原因挂掉了……
技术分享图片

6. 补完计划

$~~~~~~~$文章的第三部分代码详细解析,有空了会继续补完,待续。。。

mybatis的相关api以及配置解析(代码片段)

文章目录MyBatis的相关api1.1Resources1.2构建器SqlSessionFactoryBuilder1.3工厂对象SqlSessionFactory1.4SqlSession会话对象1.5相关api应用示例MyBatis映射配置文件2.1映射配置文件介绍2.2查询功能2.3新增功能2.4修改功能2.5删除功能Mybatis核心配置文件介... 查看详情

vue过滤器常用相关指令自定义指令函数式和对象式以及它们的注意事项(代码片段)

文章目录1.收集表单数据的各个注意事项2.Vue的过滤器3.Vue相关指令3.1已经学过的指令3.2v-text指令3.3v-html指令3.3.1cookie工作原理3.3.2v-html安全性(类似XSS攻击)3.4v-clock指令3.5v-once指令3.6v-pre指令4.自定义指令4.1判断一个元素... 查看详情

c++内存四大区域(代码片段)

...全局常量)栈区解析1普通局部变量2const修饰局部变量3栈区注意事项堆区解析new的用法1开辟单个堆区元素2开辟数组前言c++在执行程序(.exe程序)时候会对内存进行划分区域,主要目的就是方便更加高效以及灵活编程.那么,在此... 查看详情

基于流式输入输出使用java借助gson库实现对大型asc文件的读入解析并输出为json文件(代码片段)

...相关3示例3.1环境3.2测试数据3.3测试代码-Java3.4测试结果3.5注意事项致谢DOSKEY_jason参考文章奇伢-使用流的方式读写J 查看详情

基于yolo_v5训练识别人物(代码片段)

文章目录基于yolo_v5训练识别人物一、文章前言二、工具&环境准备2.1安装必要环境工具2.2获取yolov5源码三、模型训练基于yolo_v5训练识别人物一、文章前言文章分享yolo模型训练和部署二、工具&环境准备2.1安装必要环境工具ID... 查看详情

基于yolo_v5训练识别人物(代码片段)

文章目录基于yolo_v5训练识别人物一、文章前言二、工具&环境准备2.1安装必要环境工具2.2获取yolov5源码三、模型训练基于yolo_v5训练识别人物一、文章前言文章分享yolo模型训练和部署二、工具&环境准备2.1安装必要环境工具ID... 查看详情

12.6.3解析json文档相关的类介绍(代码片段)

12.6.3解析JSON文档相关的类介绍 QT提供的QJsonDocument类可以用来读取和写入JSON格式的文档。QJsonDocument类包含了完整的JSON文档操作方法,既可以读取基于UTF-8编码的文本,又可以读取和写入Qt自己的二进制格式数据。利用isNull()... 查看详情

基于流式输入输出使用java借助gson库实现对大型asc文件的读入解析并输出为json文件(代码片段)

...相关3示例3.1环境3.2测试数据3.3测试代码-Java3.4测试结果3.5注意事项致谢DOSKEY_jason参考文章奇伢-使用流的方式读写JSON(GSON)1为什么要使用流式输入输出(使用情景)解决在进行非流式输入输出时,当需处理的文件过大时... 查看详情

nlptransformer架构解析(代码片段)

【NLP】Transformer架构解析(二)【NLP】Transformer架构解析(一)3.编码器部分实现3.1掩码张量3.2注意力机制3.3多头注意力机制3.4前馈全连接层3.5规范化层3.6子层连接结构3.7编码器层3.8编码器【NLP】Transformer架构解析&#... 查看详情

nlptransformer架构解析(代码片段)

【NLP】Transformer架构解析(二)【NLP】Transformer架构解析(一)3.编码器部分实现3.1掩码张量3.2注意力机制3.3多头注意力机制3.4前馈全连接层3.5规范化层3.6子层连接结构3.7编码器层3.8编码器【NLP】Transformer架构解析&#... 查看详情

java上传excel以及解析(代码片段)

一、前言在写管理后台的需求的时候,经常会用到上传excel的功能,需要我们解析Excel的内容,导入数据等。二、上传上传到文件服务器,文件服务有相关的上传接口,需要我们调用API上传。@PostMapping("/v100/uploadFile")@ResponseBodypubli... 查看详情

mapperscannerconfigurer源码解析(代码片段)

声明:源码基于mybatis-spring1.3.2前文首先在阅读本文前需要明白整合后的使用方式以及熟悉MyBatis本身的工作原理,再者如果对于本文相关知识点不熟悉的可以参考下述文章。MyBatis与Spring整合SqlSessionTemplate源码解析Spring包扫描机制... 查看详情

aqs(abstractqueuedsynchronizer)源码深度解析—aqs的设计与总体结构(代码片段)

详细介绍了AQS的设计思想,以及总体设计结构。AQS相关文章:AQS(AbstractQueuedSynchronizer)源码深度解析(1)—AQS的设计与总体结构AQS(AbstractQueuedSynchronizer)源码深度解析(2)—Lock接口以及自定义锁的实现AQS(AbstractQueuedSynchronizer)源... 查看详情

linux内核中kcsan数据竞争检测(代码片段)

...2、内核提供的测试用例3、检测输出4、检测解析三、锁的注意事项1、通过debugfs查看2、加锁注意事项3、LocalLocks四、锁的错误使用1、不正确的自旋锁用法 2、阻塞和无法获取引用3、长时间的延迟(数据处理)3.1阿里的一... 查看详情

linux内核中kcsan数据竞争检测(代码片段)

...2、内核提供的测试用例3、检测输出4、检测解析三、锁的注意事项1、通过debugfs查看2、加锁注意事项3、LocalLocks四、锁的错误使用1、不正确的自旋锁用法 2、阻塞和无法获取引用3、长时间的延迟(数据处理)3.1阿里的一... 查看详情

数据结构java数据结构栈和队列以及leetcode相关面试题(代码片段)

...队列5.LeetCode题目第一题:有效的括号解题思路:画图解析:代码实现:第二题:用队列实现栈解题思路:画图解析:代码实现:第三题:用栈实现队列解题思路:画图解析:代码实现:第四题:最小栈解题思路:画图解析:代码实现:第五题:设计循环... 查看详情

aqs(abstractqueuedsynchronizer)源码深度解析—同步队列以及独占式获取锁释放锁的原理一万字(代码片段)

详细介绍了AQS中的同步队列以及同步状态的独占式获取、释放的原理。AQS相关文章:AQS(AbstractQueuedSynchronizer)源码深度解析(1)—AQS的设计与总体结构AQS(AbstractQueuedSynchronizer)源码深度解析(2)—Lock接口以及自定义锁的实现AQS(Abstra... 查看详情

12306购票解析车站信息以及车辆信息(代码片段)

解析车站信息以及车辆信息1.解析城市/车站编码2.获取车辆信息3.解析车辆信息4.获取后续请求所需的参数了解解析车站信息了解解析车辆信息1.解析城市/车站编码城市/车站编码js文件有版本号#12306.funk12306.get_stations_dictimportreimport... 查看详情