1. 程式人生 > >實踐目標檢測--讀取資料集

實踐目標檢測--讀取資料集

描述

對於普通的影象分類,label只用表示圖片的類別就行,而目標檢測,不僅僅包括了類別的判斷,還包含了類別的位置資訊。所以在神經網路的構造上和資料的讀取上都大不相同。

深度學習框架選用

MxNet Gluon,經過個人的對比,對於單GPU或CPU,MxNet的速度和記憶體佔用要遠優於TensorFlow,個人認為TensorFlow的優勢則在於分散式和多GPU上。

選用生成方式

MxNet對於讀取資料集的方式也有多種。

1、生成lst,直接讀取

2、生成rec檔案,讀取rec檔案

3、使用目前新出的gluoncv的方式讀取,據說這種方式是最快的。

(下面我們只使用簡單的第一種方式進行讀取)

讀取xml檔案生成lst檔案

lst檔案格式:

format:0  4  5(4,5為label的大小,表示訓練圖片中最多可以容納4個標籤物)  640(width)  480(height)  1(class)  0.1  0.2  0.8  0.9(xmin, ymin, xmax, ymax)  2  0.5  0.3  0.6  0.8  data/xxx.jpg
import os
import mxnet as mx
import numpy as np
import matplotlib.pyplot as plt
import xml.dom.minidom  # 處理xml資料

ddd = {'sign1':0,'sign2':1,'sign3':2,'sign4':3,'sign5':4}
# 首先定義一個讀取xml檔案的函式:
def xmlDecode(path):
    annotation = xml.dom.minidom.parse(path)

    size = annotation.getElementsByTagName('size')[0]
    width = size.getElementsByTagName('width')[0].firstChild.data
    height = size.getElementsByTagName('height')[0].firstChild.data

    obj = annotation.getElementsByTagName('object')[0]
    cla = ddd[obj.getElementsByTagName('name')[0].firstChild.data]  # 類別
    bndbox = obj.getElementsByTagName('bndbox')[0]  # 座標
    x1 = bndbox.getElementsByTagName('xmin')[0].firstChild.data
    x2 = bndbox.getElementsByTagName('xmax')[0].firstChild.data
    y1 = bndbox.getElementsByTagName('ymin')[0].firstChild.data
    y2 = bndbox.getElementsByTagName('ymax')[0].firstChild.data

    width = int(width)
    height = int(height)
    x1 = int(x1)
    x2 = int(x2)
    y1 = int(y1)
    y2 = int(y2)
    result = [cla, (width, height), (x1, y1), (x2, y2)]
    return result


# 定義儲存資料和標籤資料夾路徑
path = './VOCtemplate/VOC2012/Annotations/'

# 假設圖片名和對應的標籤名稱一致,這裡直接替換xml為jpg
# TODO:read xml and write as lst file, jpg name as path + xml name
# format:0  4  5  640(width)  480(height)  1(class)  0.1  0.2  0.8  0.9(xmin, ymin, xmax, ymax)  2  0.5  0.3  0.6  0.8  data/xxx.jpg
names = os.listdir(path)
lst = []
i = 0
path2 = './'
f = open(path2 + 'train.lst', 'w')
for name in names:
    if name.endswith('.xml'):
        result = xmlDecode(path + name)
        img_name = name.replace('xml', 'jpg')
        lst_tmp = str(i)+'\t4'+'\t5'+'\t'+str(result[1][0])+'\t'+str(result[1][1])+'\t'\
        +str(result[0])+'\t'\
        +str(result[2][0]/result[1][0])+'\t'+str(result[2][1]/result[1][1])+'\t'\
        +str(result[3][0]/result[1][0])+'\t'+str(result[3][1]/result[1][1])+'\t'\
        +img_name+'\n'
        # print(lst_tmp)
        f.write(lst_tmp)
        i += 1
f.close()

# 執行結束就可以在path對應資料夾下看到lst檔案了。
# reference
# https://blog.csdn.net/u010642383/article/details/80426971
# https://discuss.mxnet.io/t/imagedetiter-label-shape-mismatch/200
# https://github.com/leocvml/mxnet-im2rec_tutorial/
# https://discuss.gluon.ai/t/topic/4143/18
# 資料增強:https://zhuanlan.zhihu.com/p/30547553


#要是資料集格式錯誤,會報錯類似這樣的資訊,注意檢查最後空行/class位置等。
#--> 681         label_shape = self._estimate_label_shape()
#--> 702                 label = self._parse_label(label)

lst檔案檢視

使用image.ImageDetIter()函式來讀取圖片及標籤。(檔名:load_my_data.py)

from mxnet import image

path = './VOCtemplate/VOC2012/Annotations/'
def load_my_data(batch_size, edge_size=256):  # edge_size:輸出影象的寬和高。
    train_iter = image.ImageDetIter(batch_size=batch_size, data_shape=(3, edge_size, edge_size), path_imglist='train.lst', path_root=path)
    return train_iter#, val_iter

batch_size,edge_size = 4,256
train_data=load_my_data(batch_size,edge_size)
batch = train_data.next()
print(batch.data[0].shape)
print(batch.label[0].shape)

輸出

下一篇、構造神經網路與訓練