实践目标检测--读取数据集

描述

对于普通的图像分类,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文件查看

实践目标检测--读取数据集_第1张图片

使用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)

输出

实践目标检测--读取数据集_第2张图片

下一篇、构造神经网络与训练

 

你可能感兴趣的:(MxNet)