Serialisieren Sie die variable Anzahl von Binärinstanzmasken mit dem tfrecord-Format von Tensorflow
Für das MS Coco 2014-Dataset verfügt jedes Bild über eine variable Anzahl von Begrenzungsrahmen und entsprechende binäre Instanzmasken, die aus dem in der Anmerkungsdatei angegebenen Instanzpolygon abgerufen werden können. Ich erreiche dies mit pycocotools (insbesondere der Datei coco.py). Jetzt möchte ich Bildinformationen mit dem tfrecords-Format von Tensorflow serialisieren. Nachdem ich die Anmerkungen zu einem Python-Diktat gelesen hatte, das durch jede Bild-ID indiziert war, konnte ich eine variable Anzahl von Begrenzungsrahmen wie folgt serialisieren:
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]))
Und dann habe ich für die Verwendung meines Feature- tf.train.Example
Dikts jede Liste in eine int64-Feature-Liste konvertiert als:
def _int64_feature_list(value):
return tf.train.Feature(int64_list=tf.train.Int64List(value=value))
Da das Problem jedoch zweidimensional ist, bin ich mir nicht sicher, mit welcher Strategie ich sie serialisieren soll. Wenn es nur eine Maske gäbe, wie in einer Segmentierungsmaske, könnte ich einfach das Array reduzieren und eine 64-Bit-Feature-Liste schreiben und dann die Bildhöhe und -breite verwenden, um das Array beim Deserialisieren neu zu formen, aber ich kann dies nicht tun für variable Anzahl von Masken. Alle Erkenntnisse geschätzt.
Antworten
Notwendigkeit der Verwendung von FixedLenSequenceFeature wie weiter unten erläutert:
Ein Beispiel für 2 Bilder mit jeweils 3 und 2 Begrenzungsrahmen
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)
Ausgabe:
{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())
Überprüfen Sie die geschriebene Aufzeichnung:
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))
Ausgabe:
0 [[1806 1172 1919 1547]
[1478 1654 498 1689]
[131 515 1654 1586]]
1 [[601 1473 1670 756]
[1791 993 1049 1793]]