#YOLO_v3代码解析以及相关注意事项

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. 补完计划

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

---恢复内容结束---

## 你好

原文地址:https://www.cnblogs.com/koushihao/p/9013408.html

时间: 2024-08-30 17:13:30

#YOLO_v3代码解析以及相关注意事项的相关文章

个人小程序实现自然语言对话工程查询--快递,身份证,词典,天气等功能完整代码解析

这个小程序旨在通过自然语言对话查询快递.身份证.天气.诗歌.词典等等的功能. 自然语言对话,即使用中文语言直接对程序下命令,比如:‘查一下天气’,“帮我查一下123456这个运单号吧”,“我想听李白的静夜思”等等. 如果还是不明白,请阅读博客 https://i.cnblogs.com/EditPosts.aspx?postid=7203097&update=1 的前言部分. 1. 小程序功能介绍 如果希望直接体验小程序,请直接扫描下面的二维码,这样更直观. 但是发布的小程序里没有身份证查询,因

OpenStack之虚机热迁移代码解析

OpenStack之虚机热迁移代码解析 话说虚机迁移分为冷迁移以及热迁移,所谓热迁移用度娘的话说即是:热迁移(Live Migration,又叫动态迁移.实时迁移),即虚机保存/恢复(Save/Restore):将整个虚拟机的运行状态完整保存下来,同时可以快速的恢复到原有硬件平台甚至是不同硬件平台上.恢复以后,虚机仍旧平滑运行,用户不会察觉到任何差异.OpenStack的虚机迁移是基于Libvirt实现的,下面来看看Openstack虚机热迁移的具体代码实现. 首先,由API入口进入到nova/

MYSQL常见出错mysql_errno()代码解析

如题,今天遇到怎么一个问题, 在理论上代码是不会有问题的,但是还是报了如上的错误,把sql打印出來放到DB中却可以正常执行.真是郁闷,在百度里面 渡 了很久没有相关的解释,到时找到几个没有人回复的 "网站出现Query was empty 报错" 帖子,后来我查阅了 MYSQL常见出错代码解析大全mysql_errno()才知道是 1065:无效的SQL语句,SQL语句为空 导致的错误. 所以我们应该把重点放在sql语句上,最后发现是我的SQL语句的变量用了大写,而执行的时候该变量用了

Nginx防盗链 Nginx访问控制 Nginx解析php相关配置 Nginx代理

12.13 Nginx防盗链cd /usr/local/nginx/conf/vhostvi test.com.conf将以上内容复制到下图位置测试,成功前提data/wwwroot/test.com目录下要有1.gif12.14 Nginx访问控制cd /usr/local/nginx/conf/vhostvi test.com.confFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=" alt="Nginx

Redis相关注意事项

本文介绍了五个使用Redis使用时的注意事项.如果你在使用或者考虑使用Redis,你可以学习一下下面的一些建议,避免遇到以下提到的问题. 一.配置相关注意事项 1.涉及到内存的单位注意添加 b 1k => 1000 bytes 1kb => 1024 bytes 2.daemonize为 yes 后台运行时,记得配置 pidfile daemonize yes pidfie /var/run/redis.pid 3.配置了最大内存 maxmemory 之后记得配置过期删除策略 maxmemor

ffmpeg代码解析

void avdevice_register_all(void){    static int initialized;    if (initialized)        return;    initialized = 1;    /* devices */    REGISTER_INOUTDEV(ALSA,             alsa);    REGISTER_INDEV   (AVFOUNDATION,     avfoundation);    REGISTER_INDEV

[nRF51822] 10、基础实验代码解析大全 · 实验15 - RTC

一.实验内容: 配置NRF51822 的RTC0 的TICK 频率为8Hz,COMPARE0 匹配事件触发周期为3 秒,并使能了TICK 和COMPARE0 中断. TICK 中断中驱动指示灯D1 翻转状态, 即指示灯D1 以8Hz 的速率翻转状态 COMPARE0 中断中点亮指示灯D2 二.nRF51822的内部RTC结构: NRF51822 有两个RTC 时钟:RTC0,RTC1.两个RTC 均为24 位,使用LFCLK 低频时钟,并带有12 位分频器,可产生TICK.compare 和溢出

(转)Java二进制指令代码解析

转自http://www.blogjava.net/DLevin/archive/2011/09/13/358497.html Java二进制指令代码解析 Java源码在运行之前都要编译成为字节码格式(如.class文件),然后由ClassLoader将字节码载入运行.在字节码文件中,指令代码只是其中的一部分,里面还记录了字节码文件的编译版本.常量池.访问权限.所有成员变量和成员方法等信息(详见Java字节码格式详解).本文主要简单介绍不同Java指令的功能以及在代码中如何解析二进制指令. Ja

Storm中的LocalState 代码解析

官方的解释这个类为: /** * A simple, durable, atomic K/V database. *Very inefficient*, should only be * used for occasional reads/writes. Every read/write hits disk. */ 简单来理解就是这个类每次读写都会将一个Map<Object, Object>的对象序列化存储到磁盘中,读的时候将其反序列化. 构造函数指定的参数就是你在磁盘中存储的目录,同时也作为