Сериализация переменного количества масок двоичных экземпляров с помощью формата tfrecord Tensorflow

Для набора данных MS Coco 2014 каждое изображение имеет переменное количество ограничивающих рамок и соответствующие маски двоичных экземпляров, которые могут быть получены из многоугольника экземпляра, указанного в файле аннотации. Я добиваюсь этого с помощью pycocotools (в частности, файла coco.py). Теперь я хочу сериализовать информацию об изображении, используя формат tfrecords Tensorflow. После прочтения аннотаций к Python dict, проиндексированных по каждому идентификатору изображения, я смог сериализовать номера переменных ограничивающих прямоугольников, например:

x_min_values = []
x_max_values = []
y_min_values = []
y_max_values = []
for bb in bounding_boxes:
    x_min_values.append(int(bb[0]))
    y_min_values.append(int(bb[1]))
    x_max_values.append(int(bb[2]))
    y_max_values.append(int(bb[3]))

А затем, чтобы моя функция dict использовалась в tf.train.Example, я преобразовал каждый список в список функций int64 как:

def _int64_feature_list(value):
    return tf.train.Feature(int64_list=tf.train.Int64List(value=value)) 

Но теперь проблема в том, что, поскольку маски экземпляров двумерны, я не уверен, какую стратегию мне следует использовать для их сериализации. Если бы была только одна маска, как в маске сегментации, то я мог бы просто сгладить массив и написать 64-битный список функций, а затем использовать высоту и ширину изображения для изменения формы массива при десериализации, но я не могу этого сделать. для переменного количества масок. Любые идеи приветствуются.


person IntegrateThis    schedule 26.11.2020    source источник


Ответы (1)


Необходимо использовать FixedLenSequenceFeature, как описано ниже:


Пример 2 изображений с 3 и 2 ограничивающими рамками каждое

bounding_boxes = []
bounding_boxes.append(np.random.randint(low=0, high=2000,size=(3, 4)))  
bounding_boxes.append(np.random.randint(low=0, high=2000,size=(2, 4)))  
for i, box in enumerate(bounding_boxes):
    print({i},box)

Вывод:

{0} [[1806 1172 1919 1547]
[1478 1654 498 1689]
[ 131 515 1654 1586]]

{1} [[ 601 1473 1670 756]
[1791 993 1049 1793]]

#Write tfrecord
def _int64_feature(list_of_ints):
    return tf.train.Feature(int64_list=tf.train.Int64List(value=list_of_ints))

out_path = './test.tfrec'
with tf.io.TFRecordWriter(out_path) as out:
    for box in bounding_boxes:            
        
        example = tf.train.Example(features=tf.train.Features(feature={
            'boxes': _int64_feature(np.array(box).flatten().tolist()),
            }))
        out.write(example.SerializeToString())

Проверьте записанную tfrecord:

ds = tf.data.TFRecordDataset(out_path)

for i, data in enumerate(ds):
    process_each = {
        'boxes': tf.io.FixedLenSequenceFeature([], dtype=tf.int64, allow_missing=True),            
    }
    samples = tf.io.parse_example(data, process_each)
    print(i, samples['boxes'].numpy().reshape(-1, 4))
    

Вывод:

0 [[1806 1172 1919 1547]
[1478 1654 498 1689]
[ 131 515 1654 1586]]
1 [[ 601 1473 1670 756]
[1791 993 1049 1793]]

person vijay m    schedule 07.12.2020
comment
Первоначальный вопрос касался масок экземпляров. Это хороший ответ для сериализации номеров переменных ограничивающих прямоугольников, и я включу его в свой код. Спасибо за помощь. - person IntegrateThis; 07.12.2020