1. 程式人生 > >手把手教你用深度學習做物體檢測(二):資料標註

手把手教你用深度學習做物體檢測(二):資料標註

  “本篇文章將開始我們訓練自己的物體檢測模型之旅的第一步—— 資料標註。”

  上篇文章介紹瞭如何基於訓練好的模型檢測圖片和視訊中的物體,若你也想先感受一下物體檢測,可以看看上篇文章:《手把手教你用深度學習做物體檢測(一):快速感受物體檢測的酷炫 》。

  其實,網上關於資料標註的文章已有很多,但大多數都會有一些細節問題,比如中文編碼問題,比如標註的資料放置的目錄結構不對導致訓練報錯的問題等等,而這些問題,在本篇文章中都考慮到了,所以只要你按照步驟一步步來,並且使用本文中的程式碼,將會避免遇到上面所說的問題。

  我們已經知道,物體檢測,簡言之就是框出影象中的目標物體,就像下圖這樣:
  

  然而,能夠識別出該圖中的人、狗、馬的模型是經過了大量資料訓練得到的,這些訓練用的資料,包含了圖片本身,圖片中的待檢測目標的類別和矩形框的座標等。一般而言,初始的資料都是需要人工來標註的,比如下面這張圖:
  

  我們除了要把圖片本身餵給神經網路,還要把圖片中的長頸鹿、斑馬的類別以及在圖片中的位置資訊一併餵給神經網路,現在你可能會想,類別資訊倒還好,看一眼就知道有哪些類別了,但是目標的位置資訊如何得到?難道要用畫素尺量麼?

  其實,已經有很多物體檢測的先驅者們開發出了一些便捷的物體檢測樣本標註工具,這裡我們會介紹一個很好用的工具——labelImg,該工具已經在github上開源了,地址:https://github.com/tzutalin/labelImg
  

  該工具對於windows、Linux、Mac作業系統都支援,這裡介紹windows和Linux下的安裝方法,Mac下的安裝可以去看專案的README文件。

  • Windows
    github上提供了windows下的exe檔案,下載下來後直接雙擊執行即可開啟labelImg,進行資料的標註,下載連結如下:https://github.com/tzutalin/labelImg/files/2638199/windows_v1.8.1.zip
  • Linux
    Linux下的安裝,需要從原始碼構建,README文件中提供了python2 + Qt4和python3+Qt5的構建方法,這裡僅介紹後者,在終端中輸入以下命令:
--構建
sudo apt-get install pyqt5-dev-tools
sudo pip3 install -r requirements/requirements-linux-python3.txt
make qt5py3
--開啟
python3 labelImg.py
python3 labelImg.py [IMAGE_PATH] [PRE-DEFINED CLASS FILE]

  無論是windows還是linux下,都提供了一個預定義的類別檔案,data/predefined_classes.txt,其內容如下:
  

  這是方便我們在標註目標類別的時候可以從下拉框中選擇,所以當然也可以修改這個檔案,定義好自己要檢測的目標的類別,支援中文。

  接下來,我們以windows為例,雙擊labelImage.exe,稍等幾秒鐘,就會看到如下介面:
  

  然後,我們載入一個圖片目錄,第一張圖片會自動開啟,此時我們按下 w 鍵,就可以標註目標了,如果發現快捷鍵不能用,可能是目前處在中文輸入法狀態,切換到英文狀態就好了:
  

  標註完成後記得儲存操作,然後按下快捷鍵 d,就可以切換到下一張繼續標註。當所有的圖片標註完成後,我們還有一些事情要做,就是按照voc2007的資料集標準將圖片和xml檔案放到固定的目錄結構下,具體的結構如下:
  

  接著,我們要將圖片資料集劃分成訓練集、驗證集、測試集,可以使用如下python程式碼,將該程式碼檔案和ImageSets目錄放在同一級執行:

"""
將voc_2007格式的資料集劃分下訓練集、測試集和驗證集
"""
import os
import random

trainval_percent = 0.96
train_percent = 0.9
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', encoding="utf-8")
ftest = open('ImageSets/Main/test.txt', 'w', encoding="utf-8")
ftrain = open('ImageSets/Main/train.txt', 'w', encoding="utf-8")
fval = open('ImageSets/Main/val.txt', 'w', encoding="utf-8")

for i  in list:
    name=total_xml[i][:-4]+'\n'
    if i in trainval:
        ftrainval.write(name)
        if i in train:
            ftrain.write(name)
        else:
            fval.write(name)
    else:
        ftest.write(name)

ftrainval.close()
ftrain.close()
fval.close()
ftest .close()

  執行後,會在ImageSets/Main目錄下生成如下檔案:
  

  接下來,可以生成 yolov3 需要的資料格式了,我們使用如下程式碼,將程式碼檔案和VOCdevkit目錄放在同一級執行,注意修改程式碼中的classes為你想要檢測的目標類別集合:

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join

# sets=[('2012', 'train'), ('2012', 'val'), ('2007', 'train'), ('2007', 'val'), ('2007', 'test')]
sets=[('2007', 'train'), ('2007', 'val'), ('2007', 'test')]

# classes = ["aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"]
classes = ["人","狗","滑鼠","車"]
def convert(size, box):
    dw = 1./(size[0])
    dh = 1./(size[1])
    x = (box[0] + box[1])/2.0 - 1
    y = (box[2] + box[3])/2.0 - 1
    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)

def convert_annotation(year, image_id):
    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').text
        cls = obj.find('name').text
        if cls not in classes or int(difficult)==1:
            continue
        cls_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()

for year, image_set in sets:
    if not os.path.exists('VOCdevkit/VOC%s/labels/'%(year)):
        os.makedirs('VOCdevkit/VOC%s/labels/'%(year))
    image_ids = open('VOCdevkit/VOC%s/ImageSets/Main/%s.txt'%(year, image_set)).read().strip().split()
    list_file = open('%s_%s.txt'%(year, image_set), 'w')
    for image_id in image_ids:
        list_file.write('%s/VOCdevkit/VOC%s/JPEGImages/%s.jpg\n'%(wd, year, image_id))
        convert_annotation(year, image_id)
    list_file.close()

# os.system("cat 2007_train.txt 2007_val.txt 2012_train.txt 2012_val.txt > train.txt")
# os.system("cat 2007_train.txt 2007_val.txt 2007_test.txt 2012_train.txt 2012_val.txt > train.all.txt")

os.system("cat 2007_train.txt 2007_val.txt > train.txt")
os.system("cat 2007_train.txt 2007_val.txt 2007_test.txt > train.all.txt")

  執行後,會在當前目錄生成幾個檔案:

2007_train.txt  ——訓練集
2007_val.txt ——驗證集
2007_test.txt ——測試集
train.txt —— 訓練集+驗證集
train.all.txt —— 訓練集+驗證集+測試集

  我們只需要測試集和訓練集,所以保留train.txt和2007_test.txt,其它檔案可以刪除,然後把train.txt重新命名為2007_train.txt(不重新命名也可以的,只是為了和2007_test.txt名字看起來風格一致),如此我們就有了兩個符合yolov3訓練和測試要求的資料集2007_train.txt和2007_test.txt,注意,這兩個txt中包含的僅僅是圖片的路徑。

  除了上面的幾個檔案外,我們還會發現在VOCdevkit/VOC2007目錄下生成了一個labels目錄,該目錄下生成了和JPEGImages目錄下每張圖片對應的txt檔案,所以如果有500張圖片,就會有500個txt,具體內容如下:
  

  可以看到,每一行代表當前txt所對應的圖片裡的一個目標的標註資訊,總共有5列,第一列是該目標的類別,第二、三列是目標的歸一化後的中心位置座標,第四、五列是目標的歸一化後的寬和高。
  當我們得到了2007_train.txt、2007_test.txt、labels目錄和其下的txt檔案後,資料標註工作就算完成了,那麼如何使用這些資料來訓練我們自己的物體檢測模型呢?

  既然我們準備的資料是符合yolov3要求的,那麼我們當然是基於yolov3演算法來使用這些資料訓練出我們自己的模型,具體步驟將會在下一篇《手把手教你用深度學習做物體檢測(三):模型訓練》中介紹。

  ok,本篇就這麼多內容啦~,感謝閱讀O(∩_∩)O,88~

名句分享

孩兒立志出鄉関,學不成名誓不還,埋骨何須桑梓地,人生無處不青山。——毛澤東

為您推薦

如何在阿里雲租一臺GPU伺服器做深度學習?

手把手教你用深度學習做物體檢測(一): 快速感受物體檢測的酷炫
ubuntu16.04安裝Anaconda3
Unbuntu下持續觀察NvidiaGPU的狀態

想看更多好文?長按識別下方二維碼關注滌生吧O(∩_∩)O~

相關推薦

手把手深度學習物體檢測()資料標註

  “本篇文章將開始我們訓練自己的物體檢測模型之旅的第一步—— 資料標註。”   上篇文章介紹瞭如何基於訓練好的模型檢測圖片和視訊中的物體,若你也想先感受一下物體檢測,可以看看上篇文章:《手把手教你用深度學習做物體檢測(一):快速感受物體檢測的酷炫 》。   其實,網上關於資料標註的文章已有很多,但

手把手深度學習物體檢測(三)模型訓練

本篇文章旨在快速試驗使用yolov3演算法訓練出自己的物體檢測模型,所以會重過程而輕原理,當然,原理是非常重要的,只是原理會安排在後續文章中專門進行介紹。所以如果本文中有些地方你有原理方面的疑惑,也沒關係,可以自行網上搜索相關資料,也可以先留著問題,相信你會在後續文章中找到答案。    

手把手深度學習物體檢測(四)模型使用

上一篇《手把手教你用深度學習做物體檢測(三):模型訓練》中介紹瞭如何使用yolov3訓練我們自己的物體檢測模型,本篇文章將重點介紹如何使用我們訓練好的模型來檢測圖片或視訊中的物體。   如果你看過了上一篇文章,那麼就知道我們用的是 AlexeyAB/darknet專案,該專案雖然提供了物體檢測的

手把手深度學習物體檢測(五)YOLOv1介紹

之前寫物體檢測系列文章的時候說過,關於YOLO演算法,會在後續的文章中介紹,然而,由於YOLO歷經3個版本,其論文也有3篇,想全面的講述清楚還是太難了,本週終於能夠抽出時間寫一些YOLO演算法相關的東西。本篇文章,我會先帶大家完整的過一遍YOLOv1的論文,理解了YOLOv1才能更好的理解它的後續版本,YO

手把手深度學習物體檢測(七)YOLOv3介紹

YOLOv3 論文:《 YOLOv3: An Incremental Improvement 》 地址: https://arxiv.org/pdf/1804.02767.pdfyolov3 相比之前版本的改進 網路的特徵提取部分 由 Darknet-19改成了&n

零基礎可上手 | 手把手Cloud AutoML毒蜘蛛分類器

原作:Matt Fraser安妮 編譯自 Shine Solutions量子位 出品 | 公眾號

超有趣!手把手Python實現實時“人臉檢測

  Instagram 的聯合創始人兼首席技術官 Mike Kreiger 說:“計算機視覺和機器學習其實已開始流行起來,但是對於大多數人來說,計算機看了影象後看到了什麼這方面還是比較模糊。”     近年來,計算機視覺這個神奇的領

手把手matlab深度學習(一)- --CNN

1.使用深度學習做目標檢測 上一篇部落格已經講解了怎麼用matlab匯入資料。 [trainingImages,trainingLabels,testImages,testLabels] = helperCIFAR10Data.load('cifar10Data');

手把手Python實踐深度學習|深度學習視頻教程

視頻 ref ati pan 人工神經網絡 com 深度學習 encoder auto 手把手教你用Python實踐深度學習網盤地址:https://pan.baidu.com/s/1mkoC9ELXDglvTNN_xPUWlQ 提取碼: zgpy備用地址(騰訊微雲):ht

深度學習入門篇——手把手 TensorFlow 訓練模型

Tensorflow在更新1.0版本之後多了很多新功能,其中放出了很多用tf框架寫的深度網路結構,大大降低了開發難度,利用現成的網路結構,無論fine-tuning還是重新訓練方便了不少。最近筆者終於跑通TensorFlow Object Detection API的ssd_mobilenet_v1模型,

深度學習入門篇--手把手 TensorFlow 訓練模型

歡迎大家前往騰訊雲技術社群,獲取更多騰訊海量技術實踐乾貨哦~ 作者:付越 導語 Tensorflow在更新1.0版本之後多了很多新功能,其中放出了很多用tf框架寫的深度網路結構(https://github.com/tensorflow/mode

手把手 | 幾行Python和消費資料客戶細分

    細分客戶群是向客戶提供個性化體驗的關鍵。它可以提供關於客戶行為、習慣與偏好的相關資訊,幫助企業提供量身定製的營銷活動從而改善客戶體驗。在業界人們往往把他吹噓成提高收入的萬能藥,但實際上這個操作並不複雜,本文就將帶你用簡單的程式碼實現這一專案。 客戶

手把手 幾行Python和消費資料客戶細分

  細分客戶群是向客戶提供個性化體驗的關鍵。它可以提供關於客戶行為、習慣與偏好的相關資訊,幫助企業提供量身定製的營銷活動從而改善客戶體驗。在業界人們往往把他吹噓成提高收入的萬能藥,但實際上這個操作並不複雜,本文就將帶你用簡單的程式碼實現這一專案。 我們需要建立什麼?

【Python量化】手把手python股票分析入門

內容來自:微信公眾號:python金融量化 關注可瞭解更多的金融與Python乾貨。 目前,獲取股票資料的渠道有很多,而且基本上是免費的,比如,行情軟體有同花順、東方財富等,入口網站有新浪財經、騰訊財經、和訊網等。Python也有不少免費的開源api可以獲取交易行情資料,如pandas自

手把手GAN實現半監督學習

引言 本文主要介紹如何在tensorflow上僅使用200個帶標籤的mnist影象,實現在一萬張測試圖片上99%的測試精度,原理在於使用GAN做半監督學習。前文主要介紹一些原理部分,後文詳細介紹程式碼及其實現原理。前文介紹比較簡單,有基礎的同學請掠過直接看第二

手把手R實現標記化(附程式碼、學習資料、語料庫)

作者:Rachael Tatman翻譯:樑傅淇本文長度為1600字,建議閱讀4分鐘標記化是自然語

手把手圖靈機器人微信公眾號自動回覆助手

本文首發於我的個人部落格:尾尾部落 閱讀這篇文章,你將會學會以下內容: 如何用flask搭建微信公眾平臺服務 如何將在微信公眾平臺呼叫圖靈機器人 如何用uwsgi+supervisor+nginx部署flask應用 實驗

手把手C#疫情傳播模擬

手把手教你用C#做疫情傳播模擬 姐妹篇:手把手教你用C#做疫情傳播模擬 產品經理版 在上篇文章中,我介紹了用C#做的疫情傳播模擬程式的使用和配置,演示了其執行效果,但沒有著重講其中的程式碼。 今天我將抽絲剝繭,手把手分析程式的架構,以及妙趣橫生的細節。 首先來回顧一下執行效果: 注意看,程式中的資訊,

機器學習決策樹ID3演算法,手把手Python實現

本文始發於個人公眾號:**TechFlow**,原創不易,求個關注 今天是機器學習專題的第21篇文章,我們一起來看一個新的模型——決策樹。 決策樹的定義 決策樹是我本人非常喜歡的機器學習模型,非常直觀容易理解,並且和資料結構的結合很緊密。我們學習的門檻也很低,相比於那些動輒一堆公式的模型來說,實在是簡單