tensorflow对象检测API:生成自定义数据集的TF记录

时间:2019-02-04 08:58:26

标签: python-2.7 tensorflow virtualenv object-detection

我正在尝试使用自己的数据重新训练Tensorflow对象检测API 我已经用labelImg标记了图像,但是当我使用tensorflow / models / research中包含的脚本create_pascal_tf_record.py时,出现了一些错误,我真的不知道为什么会发生

python object_detection/dataset_tools/create_pascal_tf_record.py --data_dir=/home/jim/Documents/tfAPI/workspace/training_cabbage/images/train/ --label_map_path=/home/jim/Documents/tfAPI/workspace/training_cabbage/annotations/label_map.pbtxt --output_path=/home/jim/Desktop/cabbage_pascal.record --set=train --annotations_dir=/home/jim/Documents/tfAPI/workspace/training_cabbage/images/train/ --year=merged
Traceback (most recent call last):
  File "object_detection/dataset_tools/create_pascal_tf_record.py", line 185, in <module>
    tf.app.run()
  File "/home/jim/.virtualenvs/enrouteDeepDroneTF/local/lib/python2.7/site-packages/tensorflow/python/platform/app.py", line 125, in run
    _sys.exit(main(argv))
  File "object_detection/dataset_tools/create_pascal_tf_record.py", line 167, in main
    examples_list = dataset_util.read_examples_list(examples_path)
  File "/home/jim/Documents/tfAPI/models/research/object_detection/utils/dataset_util.py", line 59, in read_examples_list
    lines = fid.readlines()
  File "/home/jim/.virtualenvs/enrouteDeepDroneTF/local/lib/python2.7/site-packages/tensorflow/python/lib/io/file_io.py", line 188, in readlines
    self._preread_check()
  File "/home/jim/.virtualenvs/enrouteDeepDroneTF/local/lib/python2.7/site-packages/tensorflow/python/lib/io/file_io.py", line 85, in _preread_check
    compat.as_bytes(self.__name), 1024 * 512, status)
  File "/home/jim/.virtualenvs/enrouteDeepDroneTF/local/lib/python2.7/site-packages/tensorflow/python/framework/errors_impl.py", line 528, in __exit__
    c_api.TF_GetCode(self.status.status))
tensorflow.python.framework.errors_impl.NotFoundError: /home/jim/Documents/tfAPI/workspace/training_cabbage/images/train/VOC2007/ImageSets/Main/aeroplane_train.txt; No such file or directory

train文件夹包含xml和jpg
注释文件夹包含我的自定义类的labelmap.pbtxt
而且我想在桌面上发布TF记录文件

似乎无法在我的图像和注释文件夹中找到文件,但我不知道为什么 如果有人有主意,请先谢谢

2 个答案:

答案 0 :(得分:0)

发生此错误的原因是您将代码用于PASCAL VOC,这需要某些数据文件夹结构。基本上,您需要下载并解压缩VOCdevkit才能使脚本正常工作。正如phd用户指出的那样,您需要文件VOC2007/ImageSets/Main/aeroplane_train.txt

我建议您编写自己的脚本来创建tfrecords,这并不困难。您只需要两个关键组件:

  • 遍历读取图像和注释的数据
  • 将数据编码为tf.train.Example的函数。为此,您几乎可以重新使用dict_to_tf_example

在循环中创建了tf_example,然后将其传递给TFRecordWriter

writer.write(tf_example.SerializeToString())

答案 1 :(得分:0)

确定以供将来参考,这就是我将背景图像添加到数据集中以允许模型对其进行训练的方式。 datitran/raccoon_dataset

中使用的函数
  1. 生成CSV文件-> xml_to_csv.py
  2. 从CSV文件生成TFRecord-> generate_tfrecord.py

第一步-为此创建XML文件

背景图片XML文件示例

<annotation>
    <folder>test/</folder>
    <filename>XXXXXX.png</filename>
    <path>your_path/test/XXXXXX.png</path>
    <source>
        <database>Unknown</database>
    </source>
    <size>
        <width>640</width>
        <height>640</height>
        <depth>3</depth>
    </size>
    <segmented>0</segmented>
</annotation>

基本上,您会删除整个<object>(即没有注释)

第二步-生成CSV文件

我使用xml_to_csv.py进行了一些更改,以考虑没有任何注释(背景图像)的XML文件,如下所示: 从原始: https://github.com/datitran/raccoon_dataset/blob/93938849301895fb73909842ba04af9b602f677a/xml_to_csv.py#L12-L22

我添加:

value = None
for member in root.findall('object'):
            value = (root.find('filename').text,
                     int(root.find('size')[0].text),
                     int(root.find('size')[1].text),
                     member[0].text,
                     int(member[4][0].text),
                     int(member[4][1].text),
                     int(member[4][2].text),
                     int(member[4][3].text)
                     )
            xml_list.append(value)
        if value is None:
            value = (root.find('filename').text,
                     int(root.find('size')[0].text),
                     int(root.find('size')[1].text),
                     '-1',
                     '-1',
                     '-1',
                     '-1',
                     '-1'
                     )
            xml_list.append(value)

如果XML文件中没有,我只是将负值添加到边界框的坐标中(背景图片就是这种情况,并且在生成TFRecords时将很有用。

第三步也是最后一步-生成TFRecords

现在,当创建TFRecords时,如果相应的行/图像具有负坐标,我只会在记录中添加零值(之前,这甚至是不可能的)。

因此,从原文开始: https://github.com/datitran/raccoon_dataset/blob/93938849301895fb73909842ba04af9b602f677a/generate_tfrecord.py#L60-L66

我添加:

for index, row in group.object.iterrows():
        if int(row['xmin']) > -1:
            xmins.append(row['xmin'] / width)
            xmaxs.append(row['xmax'] / width)
            ymins.append(row['ymin'] / height)
            ymaxs.append(row['ymax'] / height)
            classes_text.append(row['class'].encode('utf8'))
            classes.append(class_text_to_int(row['class']))
        else:
            xmins.append(0)
            xmaxs.append(0)
            ymins.append(0)
            ymaxs.append(0)
            classes_text.append('something'.encode('utf8'))  # this doe not matter for the background
            classes.append(5000)

请注意,在{strong> else 语句的class_text中,由于背景图片没有边界框,因此您可以将字符串替换为所需的在背景情况下,它将不会出现在任何地方。

最后,对于( else 语句的classes),您只需要添加一个不属于您自己的类的数字标签。

对于那些想知道的人,我已经使用了很多次此过程,并且目前适用于我的用例。

希望它会有所帮助。