天天看点

(Tensorflow Object Detection Api)标注数据获取及格式转换

tensorflow object detection api 安装完之后,你需要下载一下已有的整理好的代码:

Windows 10

raccoon_dataset

这些代码写好了必要的流程文件。当然还有很多,大同小异。

1、物体检测数据标注

一般都用下面这个软件. 该软件是用python+Qt编写的,最终的标注文件为XML文件,以PASCAL VOC格式进行存储。安装的时候一定要注意python版本和Qt版本的对应,建议通过anaconda创建一个Python2的虚拟环境来进行此软件的安装。

LabelImg is a graphical image annotation tool and label object bounding boxes in images

这里 有一些关于安装LabelImage的讨论,如果遇到问题可以参考。

标注之后的文件大概是如下格式:

<annotation>
    <folder>save62</folder>
    <filename>6_td_6_1_5.jpg.bmp</filename>
    <path>C:\Users\Desktop\6\save62\6_td_6_1_5.jpg.bmp</path>
    <source>
        <database>Unknown</database>
    </source>
    <size>
        <width>160</width>
        <height>120</height>
        <depth>3</depth>
    </size>
    <segmented>0</segmented>
    <object>
        <name>coffee</name>
        <pose>Unspecified</pose>
        <truncated>0</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>144</xmin>
            <ymin>50</ymin>
            <xmax>159</xmax>
            <ymax>91</ymax>
        </bndbox>
    </object>
</annotation>
           

还有另外一个软件FIAT,想尝试的可以去玩一下。

2、标注数据转化为Tfrecord格式

(1)将标注数据转换为CSV格式,使用xml_to_csv.py. 当然我给的这个链接里的代码需要你的文件路径设置为./Images/train 和test文件夹,这都没关系,路径写好就行。不过在读取xml的时候可能因为标注的时候发生错误而导致读取失败,所以在下面的代码外面加一下try except.

value = (root.find('filename').text,
                     int(root.find('size')[].text),
                     int(root.find('size')[].text),
                     member[].text,
                     int(member[][].text),
                     int(member[][].text),
                     int(member[][].text),
                     int(member[][].text)
                     )
            xml_list.append(value)
           

(2)将csv和原始图数据一起,转化为tfrecord格式文件,使用generate_tfrecord.py

I)根据你自己的数据来修改下面的部分代码:

# TO-DO replace this with label map
def class_text_to_int(row_label):
    if row_label == 'nine':
        return 
    elif row_label == 'ten':
        return 
    elif row_label == 'jack':
        return 
    elif row_label == 'queen':
        return 
    elif row_label == 'king':
        return 
    elif row_label == 'ace':
        return 
    else:
        None
           

比如你的数据集只有一类物体,假设只有猫,那就改成下面的样子:

# TO-DO replace this with label map
def class_text_to_int(row_label):
    if row_label == 'cat':
        return 
    else:
        None
           

II)在终端运行如下代码:

python generate_tfrecord.py --csv_input=images/train_labels.csv 
--image_dir=images/train --output_path=train.record
           

其中 csv_input, image_dir,output_path 分别对应刚才产出的csv文件路径,原图的文件路径,及tfrecord的存储路径。

III) 一个坑点

def create_tf_example(group, path):
    with tf.gfile.GFile(os.path.join(path, '{}'.format(group.filename)), 'rb') as fid:
        encoded_jpg = fid.read()
    encoded_jpg_io = io.BytesIO(encoded_jpg)
    image = Image.open(encoded_jpg_io)
    width, height = image.size
           

注意: 这里读取图片数据用的PIL的Image,这个读出来的图片的通道顺序是RGB,因此之后的所有训练数据输入的都是RGB顺序的图片数据。 为什么要提这一点? 因为模型训练完后,在真实图片上进行测试时,如果你用opencv的imread来读入测试图片,那基本就入坑了,完全检测的乱七八糟,这是因为imread读取的是BGR顺序的图片。这肯定是不行的。具体的更改可以如下:

frame = cv2.imread("图片地址")
            b,g,r = cv2.split(frame) // 将b,g,r通道数据读出
            frame = cv2.merge([r,g,b]) // 重新归序为 rgb
           

参考 Python之cv2.imread与PIL库中Image.open读入图像颜色顺序比较,

cv2.imread BGR模式,

OpenCV读取的图片从BGR转换为RGB

Opencv Imread 文档

IV) 什么是tfrecord?

tfrecord数据文件是一种将图像数据和标签统一存储的二进制文件,能更好的利用内存,在tensorflow中快速的复制,移动,读取,存储等。当然你也可以在训练模型的时候使用python来把数据喂给神经网络,那也是一种方式。可以参看下面的一些资料。

tensorflow读取数据-tfrecord格式

Tensorflow Records? What they are and how to use them

TFRecord-formatted files

继续阅读