最近使用yolo作为目标检测的模型,此代码使用的是keras与python,在环境配置问题上会很方便。该文档主要是为了留给自己实验室的同学为了能快速使用深度学习的目标检测模型,主要讲究应用,而不是研究yolo的内部结构。
我个人认为keras框架的确简单方便,但是也有很多的不方便,比如在此yolov3工程中我们就很难实现训练一部分同时保存模型,而tensorflow就可以很好地解决。
1. 环境说明
所需环境:python3+keras2.1.5+opencv-python
这里省略环境的配置,需要看环境配置的请看我的第一篇博客安装anaconda。
已知可运行系统:Ubuntu,Windows10
该项目原来的地址:GitHub - qqwweee/keras-yolo3: A Keras implementation of YOLOv3 (Tensorflow backend)
我自己对此项目进行了修改,该博客将基于我的代码仓库进行解释说明,地址:GitHub - RuoyuChen10/Yolo
此次的演示主要基于Windows10,因为Windows10能运行的代码Ubuntu一定能运行!
2. 试运行
首先下载仓库的代码到本地,下载权重文件yolov3.weights,地址:https://pjreddie.com/media/files/yolov3.weights,放在文件夹中,如图所示:
接着,打开命令行,在这个Yolo文件夹的目录中,运行代码(注意,一定要注意在哪个路径运行):
python convert.py yolov3.cfg yolov3.weights model_data/yolo.h5
这个主要是生成h5文件,生成yolo的网络结构以及他的参数,你会在model_data这个文件夹下看到一个叫yolo.h的文件。
接着先用这个官方现成的文件检测一下图像吧,我直接从网上下载了一张图片放在了该目录文件夹下,命名为test.jpg,如下图所示:
测试的图像如图所示:
打开yolo.py,修改第23行如下,保存
"model_path": 'model_data/yolo.h5'
然后直接运行yolo.py即可
python yolo.py
如果运行成功,在你的命令行中会要求你输入图片,这时候,输入:
test.jpg
看,这样就检测到了图片中的小狗与猫,但是我们如果是应用于机器一定是需要知道此图像的相对坐标的,已经打印在了命令行中:
就是小狗和猫,让后是左上角的坐标和右下角的坐标,这里说说明下,图像的坐标原点是左上角,而不是我们习惯的左下角。
程序无限循环输入图,按ctrl+c结束程序。
3. 训练自己的数据集
这里需要一个标注的软件,叫labelimg,可以直接利用pip安装:
pip install labelimg
然后直接在命令行输入labelimg即可出现。
标注数据的方法我在之前的博客中提到过,这里不再细说,请到我的以前的博客阅读,或者百度一下labelimg标注数据。
参考地址:使用Google object_detection API与opencv实现简单的动态目标实时检测_Exploer_TRY的博客-CSDN博客
不过,我想提醒下,1、标注的标签用英文,别用中文!2、标注的标签不要有空格,可以用 ‘_’ 代替
为了方便,就创建一个和该程序训练的原始数据集一样的文件夹目录存放图片和标注的xml文件,在Yolo目录创建:VOCdevkit/VOC2007/,然后在VOC2007文件夹下创建Annotations(用于放标注的xml文件),ImageSets,JPEGImages(用于放需要训练的图片)三个文件夹。
然后在VOC2007文件夹下创建一个py文件:xml_convert.py:
import os
import random
trainval_percent = 0.2
train_percent = 0.8
xmlfilepath = 'Annotations'
txtsavepath = 'ImageSets\Main'
total_xml = os.listdir(xmlfilepath)
num = len(total_xml)
list = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list, tv)
train = random.sample(trainval, tr)
ftrainval = open('ImageSets/Main/trainval.txt', 'w')
ftest = open('ImageSets/Main/test.txt', 'w')
ftrain = open('ImageSets/Main/train.txt', 'w')
fval = open('ImageSets/Main/val.txt', 'w')
for i in list:
name = total_xml[i][:-4] + '\n'
if i in trainval:
ftrainval.write(name)
if i in train:
ftest.write(name)
else:
fval.write(name)
else:
ftrain.write(name)
ftrainval.close()
ftrain.close()
fval.close()
ftest.close()
运行该程序,将在ImageSets\Main里得到四个文本文件。
到这里,我说明一下我制作的数据集,包括basketball,arm,hand,hoop,head,Outer_edge六个类,因此我们需要修改Yolo目录下的文件voc_annotation.py
在voc_annotation.py中做出下面修改,如图:
然后运行voc_annotation.py
python voc_annotation.py
然后可以在Yolo文件夹下可以看到生成了3个txt文件:2007_test.txt,2007_train.txt,2007_val.txt。
还有就是需要修改参数文件yolo3.cfg,这个其实就是因为类别变了,我们需要为此调整网络结构。
在这个文件中搜索yolo这个关键词,有三次出现如图:
画线部分是需要修改的,重复修改三次。
filters后的255修改为3*(5+你标注的类别数量),我这里是6类,所以是3*(5+6)=33。懂一点yolo v3网络结构的人知道,yolo v3有三个输出,每一个输出块中,5层代表位置信息,而后面就是类别信息,有多少类,故这个公式就是这样来的,不懂不要紧,按照我说的做就行,毕竟只是介绍应用,而不是讲解yolo算法。
classes是你标注的类别,我这有6类,所以改为6。
random主要是改小显存,需要改小的改为0。
把三个部位全部修改,然后保存。
在model_data下创建my_classes.txt,里面每一行写上自己的类别。
然后在train.py文件中,修改 第19行为:
classes_path = 'model_data/voc_classes.txt'
在Yolo文件夹下创建目录logs/000/
然后运行train.py
注意:如果遇到 AttributeError: module 'keras.backend' has no attribute 'control_flow_ops' 说明你的keras版本过新,如何调整可以自己百度,这里建议用旧版本keras,2.1.5。
安排上了,等训练完就好。
训练好后,就能在logs/000/文件夹下看到一个h5格式文件,就是我们训练完模型的文件。
4. 测试训练完的模型
这里我将生成的文件yolo_weights.h5放在model_data文件夹下,看看自己训练的数据效果。
修改yolo.py的23行与25行,定位到yolo_weight.h5和自己定义的my_classes.txt文件
测试图片如下:
运行yolo.py查看效果:
已经可以检测到了。
5. 关于如何导出其坐标与类别
关于类别问题和坐标,请见yolo.py文件的147行:
print(label, (left, top), (right, bottom))
没错,这个就是我们要找的关键信息了。
这里解释一下,label是一个字符串,是 “种类 概率”
因此判断可以用label.split(' ')[0]来确认类别(所以要求标注不要有空格)
left和right,top和bottom导出时,最好加上int,因为图片索引一定是整数。
这里我有导入到一个excel里面,参考如下方式,具体实行请见reload_xls.py文件,不再解释。
如果是提取数据在这导入到excel里,如果是移植到机器人上,在这里写串口通信。
如果是做视频实时检测,请加入opencv的调用摄像头文件或者读取视频方法,在网上有很多例子,需要理解请努力学习。