天天看點

yolov4訓練nuscenes資料集/nuscenes資料集轉coco格式1. nuscenes資料集下載下傳2. nuscenes資料集轉COCO格式3. yolov4訓練

1. nuscenes資料集下載下傳

1.1 nuscenes資料集簡介

nuScenes資料集 是自動駕駛公司nuTonomy建立的大規模自動駕駛資料集,該資料集不僅包含了Camera和Lidar,還記錄了雷達資料。這個資料集由1000個場景組成(即scenes,這就是該資料集名字的由來),每個scenes長度為20秒,包含了各種各樣的情景。在每一個scenes中,有40個關鍵幀(key frames),也就是每秒鐘有2個關鍵幀,其他的幀為sweeps。關鍵幀經過手工的标注,每一幀中都有了若幹個annotation,标注的形式為bounding box。不僅标注了大小、範圍、還有類别、可見程度等等。這個資料集不久前釋出了一個teaser版本(包含100個scenes),正式版(1000個scenes)的資料要2019年釋出。這個資料集在sample的數量上、标注的形式上都非常好,記錄了車的自身運動軌迹(相對于全局坐标),包含了非常多的傳感器,可以用來實作更加智慧的識别算法和感覺融合算法。

我需要包含毫米波雷達/雷射雷達/攝像頭的資料集,是以需要在資料集的選擇上選取包含這三類傳感器的資料集,故選擇了nuscenes資料集。

1.2 nuscenes資料類型選擇

資料集下載下傳位址https://www.nuscenes.org/download

yolov4訓練nuscenes資料集/nuscenes資料集轉coco格式1. nuscenes資料集下載下傳2. nuscenes資料集轉COCO格式3. yolov4訓練

資料集類型一共有以上六種,從上到下分别是圖檔資料集/雷射雷達資料集/CAN資料集/地圖資料集/完整資料集/先前的作廣告的資料集(已棄用)

yolov4訓練nuscenes資料集/nuscenes資料集轉coco格式1. nuscenes資料集下載下傳2. nuscenes資料集轉COCO格式3. yolov4訓練

這裡我們隻能選擇Full dataset,原因會在之後的章節詳細說明,作者下載下傳了Mini版本,圖中高亮的部分,點選Asia即可下載下傳,下載下傳速度較慢,建議複制下載下傳連結使用迅雷下載下傳。

如果需要大量訓練集,則使用Trainval,需要下載下傳MetaData和Camera blobs only for part 1,後面的part也可以下載下傳,下載下傳方式相同,都是點選後面的Asia。

2. nuscenes資料集轉COCO格式

2.1 3D标注框轉2D

nuscenes資料集采用的是三維框标注的資料集,故需要将3D标注框轉化為2D格式。

使用官方工具nuscenes-devkthttps://github.com/nutonomy/nuscenes-devkit

克隆下來

cd ~
git clone https://github.com/nutonomy/nuscenes-devkit
           

找到

export_2d_annotations_as_json.py

路徑在

/nuscenes-devkit/python-sdk/nuscenes/scripts/export_2d_annotations_as_json.py

該檔案有以下5種選項,分别是

--dataroot

/

--version

/

--filename

/

--visibilities

/

--image_limit

--dataroot

是我們下載下傳的MetaData的路徑

--version

是我們需要轉化的json檔案的存放檔案夾名

--filename

是我們對生成的2D框的json檔案的儲存名稱

parser.add_argument('--dataroot', type=str, default='/data/sets/nuscenes', help="Path where nuScenes is saved.")
    parser.add_argument('--version', type=str, default='v1.0-trainval', help='Dataset version.')
    parser.add_argument('--filename', type=str, default='image_annotations.json', help='Output filename.')
    parser.add_argument('--visibilities', type=str, default=['', '1', '2', '3', '4'],
                        help='Visibility bins, the higher the number the higher the visibility.', nargs='+')
    parser.add_argument('--image_limit', type=int, default=-1, help='Number of images to process or -1 to process all.')
           

運作該python檔案即可獲得2D-box型的json檔案,例如,我下載下傳了Mini的資料包,我的MetaData路徑是

~/nuscenes

,該檔案下有以下四個檔案夾

yolov4訓練nuscenes資料集/nuscenes資料集轉coco格式1. nuscenes資料集下載下傳2. nuscenes資料集轉COCO格式3. yolov4訓練

/nuscenes-devkit/python-sdk/nuscenes/scripts/

路徑下打開終端,我的指令如下,大家自行修改自己的路徑及檔案夾名稱

python3 export_2d_annotations_as_json.py --dataroot ~/nuscenes --version v1.0-mini --filename 2D-box.json
           

這樣就會在v1.0-mini檔案夾下生成一個2D-box.json的檔案。

PS:在這裡詳細說一下為什麼下載下傳資料集的時候要選擇full dataset而不是nuImages,因為

export_2d_annotations_as_json.py

程式需要的很多json檔案在nuImages資料集中沒有包含,是以無法轉化成2D框,是以在下載下傳資料集的時候務必下載下傳Full dataset。

2.2 nuscenes 2D格式轉為COCO

在github上找到一個nuscenes 2D框轉為COCO格式的一個工程https://github.com/AlizadehAli/2D_label_parser

cd ~
git clone https://github.com/AlizadehAli/2D_label_parser
           

包含labels和target_labels兩個檔案夾,labels是存放剛剛上一步生成的json檔案的,把我們上一步生成的檔案放進去,并修改檔案名為2D_nuscenes.json放入labels檔案夾中

打開檢視一下我們的json檔案

gedit 2D_nuscenes.json
           
yolov4訓練nuscenes資料集/nuscenes資料集轉coco格式1. nuscenes資料集下載下傳2. nuscenes資料集轉COCO格式3. yolov4訓練

這裡可以看到box的資料結構,分别是四個角點的像素坐标,從上到下為x1,y1,x2,y2

我們打開label_parser.py,如下可以看到convert這個函數,對應上面box的資料結構可以明顯看出xywh的計算是有問題的

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)
           

将convert函數改為下面的:

def convert(size, box):
    dw = 1./size[0]
    dh = 1./size[1]
    x = (box[0] + box[2])/2.0
    y = (box[1] + box[3])/2.0
    w = box[2] - box[0]
    h = box[3] - box[1]
    x = x*dw
    w = w*dw
    y = y*dh
    h = h*dh
    return (x,y,w,h)
           

儲存

檢視代碼中的nuscenes_parser函數這裡表示了未來yolo訓練的類别名稱有以下10類,可以根據自己的需要進行修改。

for idx, name in enumerate(data):
                    if unique_img_names[i] == name['filename']:
                        x, y, w, h = convert((1600, 900), name['bbox_corners'])
                        if 'pedestrian' in name['category_name']:
                            obj_class = 0
                        elif 'bicycle' in name['category_name']:
                            obj_class = 1
                        elif 'motorcycle' in name['category_name']:
                            obj_class = 2
                        elif 'car' in name['category_name']:
                            obj_class = 3
                        elif 'bus' in name['category_name']:
                            obj_class = 4
                        elif 'truck' in name['category_name']:
                            obj_class = 5
                        elif 'emergency' in name['category_name']:
                            obj_class = 6
                        elif 'construction' in name['category_name']:
                            obj_class = 7
                        elif 'movable_object' in name['category_name']:
                            obj_class = 8
                        elif 'bicycle_rack' in name['category_name']:
                            obj_class = 9

                        temp = [str(obj_class), str(x), str(y), str(w), str(h), '\n']
                        L = " "
                        L = L.join(temp)
                        f.writelines(L)
           

然後檢視代碼可以看到有以下選項

parser.add_argument("-dt", "--data_type",
                        default="yolo",
                        help="data type of interest; yolo, bdd, nuscenes")
    parser.add_argument("-l", "--label_dir", default="./labels/",
                        help="root directory of the labels for YOLO json file, Berkeley Deep Drive (BDD) json-file, nuscenes")
    parser.add_argument("-s", "--save_dir", default="./target_labels/",
                        help="path directory to save the the converted label files")
    parser.add_argument("-i", "--image_dir",
                        default=None, required=False,
                        help="path where the images are located to BDD100K, nescenes, etc.")
    parser.add_argument("-o", "--output_dir",
                        default=None, required=False,
                        help="output directory to save the manipulated image files")
           

然後就是運作該程式,我們資料格式是nuscenes我的運作指令如下,注意save_dir必須包含以下六個檔案夾,否則程式會報找不到檔案之類的的錯誤

yolov4訓練nuscenes資料集/nuscenes資料集轉coco格式1. nuscenes資料集下載下傳2. nuscenes資料集轉COCO格式3. yolov4訓練
python3 label_parser.py -dt nuscenes -s ~/nuscenes/samples/
           

等待程式運作結束,可能有些會報os之類的一些錯誤,隻要txt成功生成了就沒有問題。

2.3 資料集檔案名對齊

首先将所有txt檔案放在一個新檔案夾TXT/中,将所有圖檔放在一個新檔案夾CAM_ALL/中

使用如下程式data.py,比對兩個檔案夾下的檔案名,删除沒有标簽的圖檔或者沒有圖檔的标簽。

data.py

import xml.dom.minidom
import os
root_path = '/home/hit/nuscenes/'
annotation_path = root_path + 'TXT/'
img_path = root_path + 'CAM_ALL/'
annotation_list = os.listdir(annotation_path)
img_list = os.listdir(img_path)
if len(img_list) != len(annotation_list):
    print("圖檔和标簽數目不比對")
    if len(img_list) < len(annotation_list):
        print("标簽比圖檔多")
        error_xml = []
        for _ in annotation_list:
            xml_name = _.split('.')[0]
            img_name = xml_name + '.jpg'
            if img_name not in img_list:
                error_xml.append(_)
				os.remove(_)
        print("error xml:", error_xml)
    else:
        print("圖檔比标簽多")
        error_img = []
        for _ in img_list:
            img_name = _.split('.')[0]
            xml_name = img_name + '.txt'
            if xml_name not in annotation_list:
                error_img.append(_)
                os.remove(_)
        print("缺少标簽的圖檔:", error_img)
           

使用如下指令運作該程式

python3 data.py
           

運作後檢視txt總數與圖檔總數是否一緻,一緻就可以放入darknet訓練了

3. yolov4訓練

首先需要darknet源碼https://github.com/AlexeyAB/darknet

git clone https://github.com/AlexeyAB/darknet
           

然後就是源碼的編譯,建議檢視官方文檔或其他部落格,此部分不再贅述

然後就是将上述第二步的txt和jpg分别放入訓練的指定檔案夾,由于我們沒有voc格式的xml标簽格式,是以無法使用程式自動配置設定資料集,我們在圖檔/你的darknet路徑/你的訓練圖檔路徑/下運作以下指令

ls -R /你的darknet路徑/你的訓練圖檔路徑/*.jpg > file.txt
           

這樣會生成一個file.txt,将該檔案的内容複制到/你的darknet路徑/scripts/,将file.txt的檔案内容複制到該檔案夾下的所有txt檔案,如果沒有就建立2007_test.txt,2007_train.txt,2007_val.txt,train.all.txt,train.txt這五個檔案,并把file.txt檔案内容放進去

修改cfg/voc.data中的類别改為10類,修改data/voc.name為上述10類的類名

修改cfg/yolov4.cfg,建議跟随官網修改方式修改https://github.com/AlexeyAB/darknet

啟動訓練

./darknet detector train cfg/voc.data cfg/yolov4.cfg yolov4.conv.137
           

至此,yolo訓練nuscenes資料集結束

繼續閱讀