日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

YOLO算法之车型识别

發(fā)布時間:2024/8/1 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 YOLO算法之车型识别 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

理論知識

干貨

論文鏈接

論文解讀

darknet安裝

? 在darknet安裝之前,需要預先裝好cuda、cudnn和opencv環(huán)境。也可以不用裝GPU版本直接編譯運行使用cpu版本,但是,為了體現(xiàn)更好的處理效率,推薦使用GPU。

? 安裝方法直接按照官網(wǎng)教程就可以,鏈接如下:

? darknet安裝

車型識別

車型識別目標: 要精確識別給定車輛圖片的車型信息

零碎知識點

標注軟件Colabeler

參考鏈接1

參考鏈接2

yolo可視化

darknet命令總結

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

mAp、P、IOU

數(shù)據(jù)集準備與處理

車型數(shù)據(jù)集共有1500張車輛照片,主要為汽車、公共汽車、卡車三種類型,拍攝時盡可能從不同角度、不同場景、不同環(huán)境下采集圖片,初次之外,每種類型車型的圖片量盡可能相差不大。

  • 數(shù)據(jù)標記
  • 注意:標注圖片時,要時常查看標注的數(shù)據(jù)是否已經(jīng)保存,并且要非常注意要勾選標注圖片的類型

  • xml文件

    [外鏈圖片轉存失敗(img-FuNiXWdz-1568511457921)(/home/gavin/NoteBook/學習匯報/DeepinScreenshot_select-area_20190516185547.png)]

    注意:一定要生成指定的XML格式文件,此次主要是根據(jù)pascal xml數(shù)據(jù)制作數(shù)據(jù)標簽。

  • 生成標簽

    VOCdevkit
    └── VOC2018
    ├── Annotations #存放標記生成的XML文件
    ├── ImageSets #存放訓練集和驗證集的照片信息(照片的名稱)
    ├── JPEGImages #存放車型數(shù)據(jù)集
    └── 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): #此函數(shù)主要生成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.創(chuàng)建labels文件夾 for year, image_set in sets: #此處第一個循環(huán)訓練集 第二個循環(huán)驗證集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.創(chuàng)建訓練集和驗證集文件夾 list_file = open('%s_%s.txt'%(year, image_set), 'w') #4.創(chuàng)建絕對路徑下的圖片文件路徑 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")#擴充訓練集數(shù)據(jù)量
  • 數(shù)據(jù)預處理

    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 #存放訓練權重
  • yolov3-tiny.cfg

    考慮的筆記本硬件的不足,選擇了yolov3-tiny版網(wǎng)絡模型,缺點:會喪失一定的準確度

    [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
  • 網(wǎng)絡模型

    訓練模型

  • 開始訓練

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

    本次訓練總共7萬次,已經(jīng)達到了不錯的效果

  • 日志文件解析

    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

    其中每行的參數(shù)意義如下:
    Avg IOU:當前迭代中,預測的box與標注的box的平均交并比,越大越好,期望數(shù)值為1;
    Class: 標注物體的分類準確率,越大越好,期望數(shù)值為1;
    obj: 越大越好,期望數(shù)值為1;
    No obj: 越小越好;
    .5R: 以IOU=0.5為閾值時候的recall; recall = 檢出的正樣本/實際的正樣本
    0.75R: 以IOU=0.75為閾值時候的recall;
    count:正樣本數(shù)目。
    注:存在nan值說明該子批次沒有預測到正樣本,在訓練開始時候有出現(xiàn)是正常現(xiàn)象

    特別的每一個批次結束之后會輸出一下結果:
    3: 673.221313, 673.023804 avg, 0.000000 rate, 0.173940 seconds, 12 images
    第幾批次,總損失,平均損失,當前學習率,當前批次訓練時間,目前為止參與訓練的圖片總數(shù)

  • 檢測圖片

    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

    汽車檢測效果:

  • 準確率:

    卡車檢測效果:

    準確率:

    公交車檢測效果:

    準確率:

  • 對于一些復雜場景下的檢測效果

    覆蓋車輛下的檢測效果

  • 檢測結果:未識別

    只有部分車身檢測效果

    檢測結果:未識別

    多車輛下的檢測效果

    檢測結果:此時的car 的準確率只有57%,并且對其它車輛不能夠進行檢測

    黑夜下的檢測效果

    檢測結果:未識別

    結論:由于本次采集的數(shù)據(jù)未能夠采集到特殊條件下的車輛照片,尤其是黑夜和不同角度下的車輛數(shù)據(jù),而只是簡單的采集了大多數(shù)正面和光線條件比較好的情況下的車輛照片,造成了對于復雜環(huán)境下未能檢測的效果。后期需要如果能夠加大數(shù)據(jù)集的囊括性,便能夠達到很好的檢測效果。

    數(shù)據(jù)分析

  • 提取數(shù)據(jù)

    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')
  • 繪制數(shù)據(jù)圖

    import pandas as pd import numpy as np import matplotlib.pyplot as plt #%matplotlib inlinelines =79755 #改為自己生成的train_log_loss.txt中的行數(shù) 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:

    classescarbustruck
    Ap0.330.290.32

    mAP = 0.313

    Recall:

    2.3.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);
  • 如果出現(xiàn)nan% 修改
  • //在在detector.c 542行 for(k = 0; k <l.w*l.h*l.n; ++k) //修改為for(k = 0; k < nboxes; ++k)
  • 測試命令
  • ./darknet detector recall <data_cfg> <test_cfg> <weights>

    2.3.2 顯示結果

    數(shù)據(jù):

    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。這個值算出來的步驟是這樣的,丟進網(wǎng)絡一張圖片,網(wǎng)絡會預測出很多bbox,每個bbox都有其置信概率,概率大于threshold的bbox與實際的bbox,也就是labels中txt的內容計算IOU,找出IOU最大的bbox,如果這個最大值大于預設的IOU的threshold,那么correct加一。

    Total表示實際有多少個bbox。

    Rps/img表示平均每個圖片會預測出來多少個bbox。

    IOU: 這個是預測出的bbox和實際標注的bbox的交集 除以 他們的并集。顯然,這個數(shù)值越大,說明預測的結果越好。

    Recall召回率, 意思是檢測出物體的個數(shù) 除以 標注的所有物體個數(shù)。通過代碼我們也能看出來就是Correct除以Total的值。

    總結

    ? 本次,從darknet的安裝到y(tǒng)olo模型的實戰(zhàn),成功的實現(xiàn)了從理論到實戰(zhàn)的轉換,雖然此次檢測結果未能對一些復雜環(huán)境下的車型進行識別,但是,還是能夠實現(xiàn)對大多數(shù)條件比較好的車型進行識別,并且準確率比較高。這次實際操作也能更加對yolov3的論文中的一些知識點進行深刻理解。初次之外,通過這次的練習,也學會了一些其他知識技能,比如圖片數(shù)據(jù)的標記與處理、opencv的使用等等。或許這一次的項目實戰(zhàn)在整體性完整性上有許多未能考慮點,有許多知識點暫時還未能觸及到或尚未真正理解明白,這就需要我接下來認真的重新看有關方面的知識來進行加強。

    ? 總之,這次理論與實踐相的融合,讓我學習到了很多知識。

    總結

    以上是生活随笔為你收集整理的YOLO算法之车型识别的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。