一、前言

本文主要使用yolo v2 训练自己的车牌图片数据,并能够框出测试图片中存在的车牌区域,也即车牌检测。本文参考了博文http://m.blog.csdn.net/qq_34484472/article/details/73135354和http://blog.csdn.net/zhuiqiuk/article/details/72722227

二、准备工作

首先需要下载正确配置好darknet, 使用./darknet detect cfg/yolo.cfg yolo.weights data/dog.jpg 命令可得检测结果。本文主要是为了检测车牌区域,在darknet下新建一文件夹plate_imgae,其中存放train和val、pic三个文件夹,train文件夹下为1296张训练图片,val文件夹下为196张验证图片,pic为236张待检测的图片,图片格式均为jpg格式,训练模型主要用到train和val这两个文件夹。

三、制作标签文件

yolo v2使用VOC格式的数据集,故这里首先需要对训练集及验证集的图片进行标注,每张图片均可得到相应的xml文件,然后再将xml文件转化为txt标签文件。参考这里http://blog.csdn.net/jesse_mx/article/details/53606897 安装标注工具LabelImg,安装完成后,./labelImg.py打开标注工具,先对train文件夹内的图片作标注,在plate_image文件夹下新建train_xml文件夹,用于存放生成的xml文件。所生成的xml文件如下所示:

同样的方法,也在在plate_image文件夹下新建val_xml文件夹,保存验证集的xml标注文件。这样就有VOC格式标记的XML文件,接下来需要将xml文件转换为txt文件,使用python转换,将train_xml中的xml文件,转换为txt保存于文件夹train_txt下;同理,将val_xml中的xml文件转换后保存于val_txt文件夹下

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join  xml_label_Dir = 'train_xml'        #需转换的xml路径
txt_label_Dir = 'train_txt/'          #转换得的txt文件保存路径def convert(size, box):        #归一化操作dw = 1./size[0]  dh = 1./size[1]  x = (box[0] + box[1])/2.0  y = (box[2] + box[3])/2.0  w = box[1] - box[0]  h = box[3] - box[2]  x = x*dw  w = w*dw  y = y*dh  h = h*dh  return (x,y,w,h)  if not os.path.exists(txt_label_Dir):   os.makedirs(txt_label_Dir)
for rootDir,dirs,files in os.walk(xml_label_Dir):  for file in files:  file_name = file.split('.')[0]  out_file = open(txt_label_Dir+'%s.txt'%(file_name),'w')  in_file = open("%s/%s"%(rootDir,file))  tree = ET.parse(in_file)  root = tree.getroot()  size = root.find('size')  w = int(size.find('width').text)  h = int(size.find('height').text)  for obj in root.iter('object'):  xmlbox = obj.find('bndbox')  b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text))  bb = convert((w,h), b)  out_file.write("0" + " " + " ".join([str(a) for a in bb]) + '\n')      #only one class,index 0out_file.close()    

接着还需要获得训练集图片的绝对路径train_imgae_path.txt和验证集的绝对路径val_image_path.txt,同样使用以下python代码

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import joinTrainDir = '/home/jyang/darknet/plate_image/train'out_file = open('train_image_path.txt','w')
for root,dirs,files in os.walk(TrainDir):for file in files:out_file.write('%s/%s\n'%(root,file))
out_file.close()

YOLO是直接通过替换原图片绝对路径的后缀名来找到对应标记文件的。比如原图片的绝对路径为/home/ubuntu/data/train/1.jpg。则YOLO将会直接认为其对应的标记文件路径为/home/ubuntu/data/train/1.txt。所以,我们将之前生成的txt文件都放到相应的图片路径下,即将train_txt下txt文件放到train文件夹下,将val_txt下txt文件放到val文件夹下

看看plate_image下都有啥。

四、修改配置文件

(1)创建names文件

在YOLO主目录的data文件夹下,创建一个.names文件,文件名任意,我的是myClass.names,在该文件中写入所有类别的名称,每一类占一行,我只检测车牌,故只在第一行写licence.

(2)修改data文件

修改darknet主目录下的 cfg/voc.data文件,修改如下:

classes= 1                      #只有一个类别
train  = /home/jyang/darknet/plate_image/train_image_path.txt        #训练集的绝对路径
valid  = /home/jyang/darknet/plate_image/val_image_path.txt           #验证集的绝对路径
names = data/myClass.names
backup = /home/jyang/darknet/plate_image/backup                     #训练得的模型保存路径

(3)修改cfg文件

修改darknet主目录下的cfg/yolo-voc.cfg。

1.[region]层中classes改为1

2.[region]层上方的[convolution]层中,filters的数量改成(classes+coords+1)*NUM。我这里改成了(1+4+1)*5=30.

五、 修改src/yolo.c文件

1.第13行改成 char *voc_names[] = {"licence"}; //如果你是一类的话,就改成这样,如果你有多类,自己根据需求改。

2.第322行draw_detections函数中,最后一个参数由20改成你的类别数,我这里是1

3.第354行demo函数中,倒数第三个参数由20改成你的类别数,我这里是1

4.第17行改成 char *train_images = "<你的路径>/train_imgae_path";

5.第18行改成 char *backup_directory = "你的路径/backup/";

6.第121行改成 char *base = "results/comp4_det_test_"

7.第123行改成 list *plist = get_paths("<你的路径>/val_image_path.txt");

8.第209行改成 char *base = "results/comp4_det_test_"

9.第210行改成 list *plist = get_paths("<你的路径>/val_image_path.txt");

10.将src/yolo_kernels.cu文件中,第62行draw_detections函数最后一个参数由20改成你的类别数,我这里是1.

11.scripts/voc_label.py 文件中 ,位置第9行改成:classes=[“licence”],因为我只有一类

12.将src/detector.c文件中,第372行改成 list *plist = get_paths("<你的路径>/val_image_path.txt");,第542行option_find_int函数的最后一个参数由20改成1.

六、重新编译darknet yolo

进入darknet主目录,make clean后 make -j8

七、下载预训练文件cfg/darknet19_448.conv.23

为了加快训练速度,下载官方提供的预训练模型,保存至cfg下。下载地址为

http://pjreddie.com/media/files/darknet19_448.conv.23

八、训练

在darknet文件夹路径下运行命令:

./darknet detector train cfg/voc.data cfg/yolo-voc.cfg cfg/darknet19_448.conv.23
        系统默认会迭代45000次batch,如果需要修改训练次数,进入cfg/yolo_voc.cfg修改max_batches的值。

九、训练过程输出log

参考自这篇文章http://blog.csdn.net/renhanchi/article/details/71077830?locationNum=13&fps=1,以下摘自这篇文章

Region Avg IOU: 这个是预测出的bbox和实际标注的bbox的交集 除以 他们的并集。显然,这个数值越大,说明预测的结果越好

Avg Recall: 这个表示平均召回率, 意思是 检测出物体的个数 除以 标注的所有物体个数。

count: 标注的所有物体的个数。 如果 count = 6, recall = 0.66667, 就是表示一共有6个物体(可能包含不同类别,这个不管类别),然后我预测出来了4个,所以Recall 就是 4 除以 6 = 0.66667

有一行跟上面不一样的,最开始的是iteration次数,然后是train loss,然后是avg train loss, 然后是学习率, 然后是一batch的处理时间, 然后是已经一共处理了多少张图片。 重点关注 train loss 和avg train loss,这两个值应该是随着iteration增加而逐渐降低的。如果loss增大到几百那就是训练发散了,如果loss在一段时间不变,就需要降低learning rate或者改变batch来加强学习效果。当然也可能是训练已经充分。这个需要自己判断

十、评估训练得的模型

训练了3天,得到了迭代30000次的权值,在plate_image/backup/下生成了yolo-voc_30000.weights,当然还有其他迭代次数的权值,使用以下语句可以测试单张图片

./darknet detector test cfg/voc.data cfg/yolo-voc.cfg plate_image/backup/yolo-voc_30000.weights plate_image/pic/099999.jpg

显示的检测结果为

训练的时候只是用到了训练集,评估检测性能才会使用到验证集。使用以下指令评估

root@computer:/home/jyang/darknet# ./darknet detector recall cfg/voc.data cfg/yolo-voc.cfg plate_image/backup/yolo-voc_30000.weights

根据参考的第2篇博文,使用该指令的时候,会调用src/detector.c里的validate_detector_recall函数,将其中的阈值从0.001修改为0.25,防止过多框被识别出,将432行代码修改为如下:

fprintf(stderr, "Id:%5d Correct:%5d Total%5d\tRPs/Img: %.2f\tIOU: %.2f\tRecall:%.2f%%\tPrecision:%.2f%%\n", i, correct, total, (float)proposals/(i+1), avg_iou*100/total, 100.*correct/total ,100.*correct/proposals);

重新make之后,运行结果为:

可见196张图片,准确率有97%以上。

结语

本文只是使用了yolo v2 检测了车牌,后续对框下来的车牌图片作识别,请看《yolo v2之车牌检测后续识别字符(一)》

yolo v2 之车牌检测相关推荐

  1. 重温目标检测--YOLO v2 -- YOLO9000

    YOLO9000:Better, Faster, Stronger CVPR 2017, Best Paper Honorable Mention https://pjreddie.com/darkn ...

  2. 深度学习目标检测之 YOLO v2

    论文名:<YOLO9000: Better, Faster, Stronger> 原文:https://arxiv.org/pdf/1612.08242v1.pdf 代码:http://p ...

  3. 目标检测之YOLO V2 V3

    YOLO V2 YOLO V2是在YOLO的基础上,融合了其他一些网络结构的特性(比如:Faster R-CNN的Anchor,GooLeNet的\(1\times1\)卷积核等),进行的升级.其目的 ...

  4. 目标检测:YOLO V1、YOLO V2、YOLO V3 算法

    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) yoloV3模型 目标检测:YOLO V1.YOLO V2.Y ...

  5. # 经典目标检测识别方法概述RCNN/FAST/FASTER RCNN/MASK RCNN/SSD/DSSD/YOLO V1/YOLO V2等

    经典目标检测识别方法概述@陈子逸 经典目标检测识别方法概述 由于水硕期间自学了一些目标探测的方法,这里做一个概述,肯定有不完美的地方,还请指正一起进步. 综述 1.分别简单描述一下RCNN系列: 在我 ...

  6. 基于 YOLO 的车牌检测与识别

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 导读 本文将重点介绍 ALPR 的端到端实现.它将侧重于两个过程: ...

  7. YOLO v2实现图像目标检测

    作者介绍 熊文博,男,西安工程大学电子信息学院,2020级硕士研究生,张宏伟人工智能课题组. 研究方向:机器视觉与人工智能 电子邮件:996270714@qq.com 师兄的CSDN主页: 欢迎关注和 ...

  8. YOLO v2目标检测详解一box生成与转换

    yolo v2会将图片切割成若干个大小为32*32 的小格子,因此,将图片传入时,图片的长和宽都必须是32的倍数,如下所示: 后面的内容中,如果没有说明,都是指的小格子.yolo v2中的box中的数 ...

  9. 使用深度学习进行自动车牌检测和识别

    作者 | 小白 来源 | 小白学视觉 介绍 在现代世界的不同方面,信息技术的大规模集成导致了将车辆视为信息系统中的概念资源.由于没有任何数据,自主信息系统就没有任何意义,因此需要在现实和信息系统之间改 ...

最新文章

  1. Web 开发在 2015 年及未来的发展趋势
  2. OpenGL blending 混合的实例
  3. bzoj3140: [Hnoi2013]消毒(二分图)
  4. POJ 1041 John's trip(欧拉回路)
  5. 使用阿基米德螺线进行数据可视化
  6. Java多线程(十):BlockingQueue实现生产者消费者模型
  7. Downie 4搭配Permute 3,一个完整的视频下载处理流
  8. 税务计算机类考试题型,2020年税务师考试题型、计算器使用规定及考试难度
  9. 深入浅出WPF 总结
  10. 他25岁进贝尔实验室,32岁提信息论,40岁办达特茅斯会议,晚年患上阿兹海默 | 人物志
  11. pytorch/tensorflow使用anaconda安装scipy库
  12. cidaemon.exe
  13. 【SpringBoot】十八、拦截器 interceptor
  14. 《Python数据可视化之Matplotlib与Pyecharts》之K线图
  15. 创意视频标题文字模板 Big Titles 2.0 | Premiere Pro
  16. 冰刃-删除顽固文件的利器!
  17. 使用python制作epub
  18. Alpine-Linux:仅5MB的Linux
  19. 【Python语言基础】——Python 命令行输入
  20. System.Windows.Markup.XamlParseException:““在“System.Windows.StaticResourceExtension”上提供值时引发了异常

热门文章

  1. 校园三维可视化建模与仿真
  2. 机器学习读书笔记:强化学习
  3. python利用setsockopt获得端口重用
  4. 使用记事本编写Java示例
  5. C语言-冒泡排序函数
  6. html 复制粘贴禁止,互联网常识:html怎么禁止复制粘贴
  7. goaccess分析日志
  8. 自强创新之路 打造真正上网不花钱8500WN已面世
  9. python中如何拷贝一个对象_python题目-----Python里面如何拷贝一个对象?
  10. python怎么输出数组全部数据_Python打印输出数组中全部元素