理论知识

干货

论文链接

论文解读

darknet安装

​ 在darknet安装之前,需要预先装好cuda、cudnn和opencv环境。也可以不用装GPU版本直接编译运行使用cpu版本,但是,为了体现更好的处理效率,推荐使用GPU。

​ 安装方法直接按照官网教程就可以,链接如下:

​ darknet安装

车型识别

车型识别目标: 要精确识别给定车辆图片的车型信息

零碎知识点

标注软件Colabeler

参考链接1

参考链接2

yolo可视化

darknet命令总结

召回率和准确率<https://www.zhihu.com/question/19645541/answer/91694636>

mAp、P、IOU

数据集准备与处理

车型数据集共有1500张车辆照片,主要为汽车、公共汽车、卡车三种类型,拍摄时尽可能从不同角度、不同场景、不同环境下采集图片,初次之外,每种类型车型的图片量尽可能相差不大。

  1. 数据标记

注意:标注图片时,要时常查看标注的数据是否已经保存,并且要非常注意要勾选标注图片的类型

  1. xml文件

    [外链图片转存失败(img-FuNiXWdz-1568511457921)(/home/gavin/NoteBook/学习汇报/DeepinScreenshot_select-area_20190516185547.png)]

    注意:一定要生成指定的XML格式文件,此次主要是根据pascal xml数据制作数据标签。

  2. 生成标签

    VOCdevkit
    └── VOC2018
    ├── Annotations #存放标记生成的XML文件
    ├── ImageSets #存放训练集和验证集的照片信息(照片的名称)
    ├── JPEGImages #存放车型数据集
    └── labels  # 每张样本的标签

    labels文件格式:

    0 0.5467489919354839 0.4299395161290323 0.8933971774193548 0.5191532258064516

    • object-class:是指对象的索引,从0开始,具体代表哪个对象去obj.names配置文件中按索引查,初次之外,每个txt文件可以有多个boundbox的信息,表示圈定的图片不是一个单一类。
    • x,y:是一个坐标,需要注意的是它可不是对象左上角的坐标,而对象中心的坐标
    • width,height:是指对象的宽高

    voc_label.py 解析

    import xml.etree.ElementTree as ET
    import pickle
    import os
    from os import listdir, getcwd
    from os.path import joinsets=[('2018', 'train'), ('2018', 'val')]classes = ["car", "bus", "truck"] #设置分类车型def convert(size, box): #此函数主要生成labels文件中归一化的值dw = 1./(size[0]) #用于归一化dh = 1./(size[1])x = (box[0] + box[1])/2.0 #找出对象的中心点坐标y = (box[2] + box[3])/2.0w = box[1] - box[0] # 得到真是的boundbox的长宽信息h = box[3] - box[2]x = x*dw #归一化w = w*dwy = y*dhh = h*dhreturn (x,y,w,h)def convert_annotation(year, image_id):#解析XMl文件in_file = open('VOCdevkit/VOC%s/Annotations/%s.xml'%(year, image_id))out_file = open('VOCdevkit/VOC%s/labels/%s.txt'%(year, image_id), 'w')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'):difficult = obj.find('difficult').textcls = obj.find('name').text #查找是不是我们自己的类if cls not in classes or int(difficult)==1:#跳过continuecls_id = classes.index(cls)#得到类别标签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(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')wd = getcwd()#获取当前路径#1.创建labels文件夹
    for year, image_set in sets: #此处第一个循环训练集 第二个循环验证集if not os.path.exists('VOCdevkit/VOC%s/labels/'%(year)):os.makedirs('VOCdevkit/VOC%s/labels/'%(year))#2.得到图片的id    image_ids = open('VOCdevkit/VOC%s/ImageSets/Main/%s.txt'%(year, image_set)).read().strip().split()
    #3.创建训练集和验证集文件夹  list_file = open('%s_%s.txt'%(year, image_set), 'w')
    #4.创建绝对路径下的图片文件路径    for image_id in image_ids:list_file.write('%s/VOCdevkit/VOC%s/JPEGImages/%s.jpg\n'%(wd, year, image_id))
    #5.xml 转 labelconvert_annotation(year, image_id)list_file.close()os.system("cat 2018_train.txt 2018_val.txt > train.txt")#扩充训练集数据量
  3. 数据预处理

    voc.data

    classes= 3 #分类类型
    train  = /home/gavin/Machine/darknet/scripts/train.txt #训练集
    valid  = /home/gavin/Machine/darknet/scripts/2018_val.txt #验证集
    names = data/voc.names #类别信息
    backup = backup #存放训练权重
    
  4. yolov3-tiny.cfg

    考虑的笔记本硬件的不足,选择了yolov3-tiny版网络模型,缺点:会丧失一定的准确度

    [net]
    # Testing
    #batch=1
    #subdivisions=1
    Training
    batch=2
    subdivisions=1
    width=416
    height=416
    channels=3
    momentum=0.9
    decay=0.0005
    angle=0
    saturation = 1.5
    exposure = 1.5
    hue=.1learning_rate=0.001
    burn_in=1000
    max_batches = 500200
    policy=steps
    steps=400000,450000
    scales=.1,.1......[convolutional]
    size=1
    stride=1
    pad=1
    filters=24 #classes*8
    activation=linear[yolo]
    mask = 3,4,5
    anchors = 10,14,  23,27,  37,58,  81,82,  135,169,  344,319
    classes=3#classes
    num=6
    jitter=.3
    ignore_thresh = .7
    truth_thresh = 1
    random=1[route]
    layers = -4[convolutional]
    batch_normalize=1
    filters=128
    size=1
    stride=1
    pad=1
    activation=leaky[upsample]
    stride=2[route]
    layers = -1, 8[convolutional]
    batch_normalize=1
    filters=256
    size=3
    stride=1
    pad=1
    activation=leaky[convolutional]
    size=1
    stride=1
    pad=1
    filters=24
    activation=linear[yolo]
    mask = 0,1,2
    anchors = 10,14,  23,27,  37,58,  81,82,  135,169,  344,319
    classes=3
    num=6
    jitter=.3
    ignore_thresh = .7
    truth_thresh = 1
    random=1

网络模型

训练模型

  1. 开始训练

    darknet : sudo ./darknet detector train cfg/voc.data cfg/yolov3-tiny.cfg

    本次训练总共7万次,已经达到了不错的效果

  2. 日志文件解析

    Region 16 Avg IOU: 0.100322, Class: 0.425682, Obj: 0.461557, No Obj: 0.488897, .5R: 0.000000, .75R: 0.000000,  count: 4
    Region 23 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.534580, .5R: -nan, .75R: -nan,  count: 0
    2: 675.922241, 673.001831 avg, 0.000000 rate, 0.177072 seconds, 8 images
    Loaded: 0.315449 seconds
    Region 16 Avg IOU: 0.142092, Class: 0.463787, Obj: 0.288284, No Obj: 0.489365, .5R: 0.000000, .75R: 0.000000,  count: 4
    Region 23 Avg IOU: -nan, Class: -nan, Obj: -nan, No Obj: 0.534735, .5R: -nan, .75R: -nan,  count: 0
    3: 673.221313, 673.023804 avg, 0.000000 rate, 0.173940 seconds, 12 images
    Loaded: 0.325054 seconds
    Region 16 Avg IOU: 0.293639, Class: 0.411060, Obj: 0.413394, No Obj: 0.489323, .5R: 0.000000, .75R: 0.000000,  count: 4
    

    其中每行的参数意义如下:
    Avg IOU:当前迭代中,预测的box与标注的box的平均交并比,越大越好,期望数值为1;
    Class: 标注物体的分类准确率,越大越好,期望数值为1;
    obj: 越大越好,期望数值为1;
    No obj: 越小越好;
    .5R: 以IOU=0.5为阈值时候的recall; recall = 检出的正样本/实际的正样本
    0.75R: 以IOU=0.75为阈值时候的recall;
    count:正样本数目。
    注:存在nan值说明该子批次没有预测到正样本,在训练开始时候有出现是正常现象

    特别的每一个批次结束之后会输出一下结果:
    3: 673.221313, 673.023804 avg, 0.000000 rate, 0.173940 seconds, 12 images
    第几批次,总损失,平均损失,当前学习率,当前批次训练时间,目前为止参与训练的图片总数

  3. 检测图片

    3.1 批量化测试效果

    darknet: ./darknet detector valid cfg/voc.data cfg/yolov3-tiny.cfg backup/yolov3-tiny_70000.weights

    注意 : 此时应该修改yolov3-tiny.cfg文件中的batch和subminibatch为1

    测试结果会存放在results文件夹下:如下

    comp4_det_test_bus.txt
    comp4_det_test_car.txt
    comp4_det_test_truck.txt
    yolo_valid.txtbus.txt
    yolo_valid.txtcar.txt
    yolo_valid.txttruck.txt

    当打开其中comp4_det_test_bus.txt:

    1039 0.008945 1075.546509 642.225098 1427.953003 852.698364
    0822 0.005433 578.461548 576.750000 2930.228027 1478.208252
    0860 0.987352 133.620972 325.751465 3403.745117 2544.819336
    图片名称 该类置信度 坐标信息

    3.2 单张测试效果

    darknet: sudo ./darknet detector test cfg/voc.data cfg/yolov3-tiny.cfg backup/yolov3-tiny_70000.weights

    汽车检测效果:

准确率:

卡车检测效果:

准确率:

公交车检测效果:

准确率:

  1. 对于一些复杂场景下的检测效果

    覆盖车辆下的检测效果

检测结果:未识别

只有部分车身检测效果

检测结果:未识别

多车辆下的检测效果

检测结果:此时的car 的准确率只有57%,并且对其它车辆不能够进行检测

黑夜下的检测效果

检测结果:未识别

结论:由于本次采集的数据未能够采集到特殊条件下的车辆照片,尤其是黑夜和不同角度下的车辆数据,而只是简单的采集了大多数正面和光线条件比较好的情况下的车辆照片,造成了对于复杂环境下未能检测的效果。后期需要如果能够加大数据集的囊括性,便能够达到很好的检测效果。

数据分析

  1. 提取数据

    import inspect
    import os
    import random
    import sys
    def extract_log(log_file,new_log_file,key_word):with open(log_file, 'r') as f:with open(new_log_file, 'w') as train_log:#f = open(log_file)#train_log = open(new_log_file, 'w')for line in f:# 去除多gpu的同步logif 'Syncing' in line:continue# 去除除零错误的logif 'nan' in line:continueif key_word in line:train_log.write(line)f.close()train_log.close()extract_log('yolov3.log','train_log_loss.txt','images')
    extract_log('yolov3.log','train_log_iou.txt','IOU')
    
  2. 绘制数据图

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    #%matplotlib inlinelines =79755    #改为自己生成的train_log_loss.txt中的行数
    result = pd.read_csv('train_log_loss.txt', skiprows=[x for x in range(lines) if ((x%10!=9) |(x<1000))] ,error_bad_lines=False, names=['loss', 'avg', 'rate', 'seconds', 'images'])
    result.head()result['loss']=result['loss'].str.split(' ').str.get(1)
    result['avg']=result['avg'].str.split(' ').str.get(1)
    result['rate']=result['rate'].str.split(' ').str.get(1)
    result['seconds']=result['seconds'].str.split(' ').str.get(1)
    result['images']=result['images'].str.split(' ').str.get(1)
    result.head()
    result.tail()# print(result.head())
    # print(result.tail())
    # print(result.dtypes)print(result['loss'])
    print(result['avg'])
    print(result['rate'])
    print(result['seconds'])
    print(result['images'])result['loss']=pd.to_numeric(result['loss'])
    result['avg']=pd.to_numeric(result['avg'])
    result['rate']=pd.to_numeric(result['rate'])
    result['seconds']=pd.to_numeric(result['seconds'])
    result['images']=pd.to_numeric(result['images'])
    result.dtypesfig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    ax.plot(result['avg'].values,label='avg_loss')
    # ax.plot(result['loss'].values,label='loss')
    ax.legend(loc='best')  #图列自适应位置
    ax.set_title('The loss curves')
    ax.set_xlabel('batches')
    fig.savefig('avg_loss')
    # fig.savefig('loss')
    

    2.1 loss 图:

2.2 IOU图:

2.3 Ap:

classes car bus truck
Ap 0.33 0.29 0.32

mAP = 0.313

Recall:

2.3.1 预备工作

  1. 修改文件

修改darknet根文件下的detector.c

list *plist = get_paths("data/voc.2007.test");
char **paths = (char **)list_to_array(plist);//修改为如下
list *plist = get_paths("scripts/train.txt");
char **paths = (char **)list_to_array(plist);
  1. 如果出现nan% 修改
//在在detector.c 542行
for(k = 0; k <l.w*l.h*l.n; ++k)
//修改为for(k = 0; k < nboxes; ++k)
  1. 测试命令

./darknet detector recall <data_cfg> <test_cfg> <weights>

2.3.2 显示结果

数据:

 Number Correct Total Rps/Img IOU Recall 2940  2933  2940    RPs/Img: 1.42   IOU: 85.75% Recall:99.76%2941  2934  2941   RPs/Img: 1.42   IOU: 85.75% Recall:99.76%2942  2935  2942   RPs/Img: 1.42   IOU: 85.75% Recall:99.76%2943  2936  2943   RPs/Img: 1.42   IOU: 85.75% Recall:99.76%2944  2937  2944   RPs/Img: 1.42   IOU: 85.76% Recall:99.76%2945  2938  2945   RPs/Img: 1.42   IOU: 85.76% Recall:99.76%2946  2939  2946   RPs/Img: 1.42   IOU: 85.76% Recall:99.76%2947  2940  2947   RPs/Img: 1.42   IOU: 85.76% Recall:99.76%

分析:

Number表示处理到第几张图片。

Correct表示正确的识别除了多少bbox。这个值算出来的步骤是这样的,丢进网络一张图片,网络会预测出很多bbox,每个bbox都有其置信概率,概率大于threshold的bbox与实际的bbox,也就是labels中txt的内容计算IOU,找出IOU最大的bbox,如果这个最大值大于预设的IOU的threshold,那么correct加一。

Total表示实际有多少个bbox。

Rps/img表示平均每个图片会预测出来多少个bbox。

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

Recall召回率, 意思是检测出物体的个数 除以 标注的所有物体个数。通过代码我们也能看出来就是Correct除以Total的值。

总结

​ 本次,从darknet的安装到yolo模型的实战,成功的实现了从理论到实战的转换,虽然此次检测结果未能对一些复杂环境下的车型进行识别,但是,还是能够实现对大多数条件比较好的车型进行识别,并且准确率比较高。这次实际操作也能更加对yolov3的论文中的一些知识点进行深刻理解。初次之外,通过这次的练习,也学会了一些其他知识技能,比如图片数据的标记与处理、opencv的使用等等。或许这一次的项目实战在整体性完整性上有许多未能考虑点,有许多知识点暂时还未能触及到或尚未真正理解明白,这就需要我接下来认真的重新看有关方面的知识来进行加强。

​ 总之,这次理论与实践相的融合,让我学习到了很多知识。

YOLO算法之车型识别相关推荐

  1. 【matlab选题推荐二】MATLAB差影法车型识别算法研究

    1.基本设计思路 该设计主要采用的算法是背景差影算法.背景差影法又称为背景差分法,算法的原理是将拍摄得到的已经包含背景图的车型图像和单独的背景图像进行做差来得到差值图像,再对差值图像进行图像预处理,从 ...

  2. 如何实现AI视频车型识别算法

    如题,实现AI视频车型识别,首先要确定采用的深度学习的框架,建议如果在移动设备端检测建议采用 mobilenetv3-large网络模型,在服务器上可采用 Resnet150或更高阶的模型,根据我们司 ...

  3. 河道水面漂浮物识别检测 YOLO算法详解

    河道水面漂浮物识别检测根据监控摄像头搜集江河或河道的水面视频,截取图片中带有海上漂浮物的照片,河道水面漂浮物识别检测训练所需照片,形成数据实体模型,实时检测河道水面的监控画面.如出现数据集模型中的漂浮 ...

  4. YOLO车牌识别,基于深度学习YOLOv3,Yolov4开发,支持车辆车型识别

    YOLO车牌识别,基于深度学习YOLOv3,Yolov4开发,支持车辆车型识别 ID:6999650911717802盐市口会玩的川乌

  5. 论文学习:基于集成YOLO算法的蝴蝶检测与分类

    0.论文名称与地址连接 Butterfly detection and classification based on integrated YOLO algorithm 论文地址:xxx.itp.a ...

  6. 图片相似度识别算法,百度图片识别算法

    图像识别算法都有哪些 图像识别算法:1人脸识别类(Eigenface,Fisherface算法特别多),人脸检测类(j-v算法,mtcnn)2车牌识别类,车型识别类(cnn)3字符识别(cnn)... ...

  7. 基于深度学习的车型识别系统(Python+清新界面+数据集)

    摘要:基于深度学习的车型识别系统用于识别不同类型的车辆,应用YOLO V5算法根据不同尺寸大小区分和检测车辆,并统计各类型数量以辅助智能交通管理.本文详细介绍车型识别系统,在介绍算法原理的同时,给出P ...

  8. 关于YOLO算法的备忘

    YOLO算法(判断是行人 汽车 还是摩托车) 训练过程 1构建训练集 输入一张图片(网格设置成3*3) 设置两个archor box 对面个格子进行卷积 进行一个卷积的输出y={pc bx by bh ...

  9. 目标检测 /yolo算法原理的详解

    前言 谈到计算机视觉时,我们都会联想到图像分类,图像分类是计算机视觉最基本的任务之一,在图像分类的基础上,我们还有更复杂的任务,比如目标检测,物体定位,图像分割等,本文主要讲目标检测,目标检测是分类与 ...

  10. yolo算法的优缺点分析_yolo算法介绍

    yolo算法介绍 (2020-06-06 16:49:28) 把Yolo模型搞清楚后不得不再次为人类的智慧感慨,一个巧妙的模型. 要想理解Yolo我们先要搞清楚Yolo到底要解决一个什么问题,解决这个 ...

最新文章

  1. 【剑指offer-Java版】36数组中的逆序对
  2. 云网融合 — 电信网络云
  3. PHP通过Thrift操作Hbase
  4. 【.Net 学习系列】-- EF Core实践(Code First)
  5. SwiftUI5.x微博入门案例第1部分
  6. hdu 6899 Xor 数位dp
  7. Android 视频图片 轮播,详解android 视频图片混合轮播实现
  8. (转)The POM for 0.0.1-SNAPSHOT is missing, no dependency informat
  9. BZOJ 4443: [Scoi2015]小凸玩矩阵
  10. 智能车PCB设计思路
  11. 手把手教你电脑下载b站视频
  12. 【问链财经-区块链基础知识系列】 第二十课 区块链联盟链攻伐战
  13. 通俗解释什么是NFT,NFT到底是什么
  14. 详谈SSD硬盘接口: SATA、mSATA 、PCIe、M.2和U.2
  15. Elasticsearch(三)——Es搜索(简单使用、全文查询、复合查询)、地理位置查询、特殊查询、聚合操作、桶聚合、管道聚合
  16. 重定向解决国外服务器与国内域名备案的问题
  17. Latex表格线宽修改方法以及内容左对齐。
  18. 基于android餐馆点餐系统报告感想,基于Android的餐厅点餐系统的设计与实现
  19. Navicat for Mysql注册(Navicat 8.2 MySQL 8.2.17注册码)写入注册码后,点不动确认键
  20. 测绘类专业计算机要学什么科目,测绘类专业选考科目要求是什么

热门文章

  1. 原生JS实现HTML文件上传,简单实现js上传文件功能
  2. 诺,你们要的Python进阶来咯!【函数、类进阶必备】
  3. Cocos Creator 实现大厅+子游戏模式
  4. CTFshow wbe41 教你写脚本
  5. linux 抓包教程
  6. 华为手机怎样才算激活了_华为手机激活是怎么回事
  7. 华为android解锁,华为bootloader怎么解锁 华为手机bootloader解锁教程
  8. JS/VUE 自定义效验 统一社会信用代码 营业执照注册号
  9. UG NX 12 草图 (基础知识)
  10. 计算机网络技术云计算简历模板,云计算平台师个人简历模板