Как изменить размер изображения для размещения в tf.train.Example

#python #tensorflow

#python #тензорный поток

Вопрос:

У меня есть изображение (JPEG или PNG) в виде байтового буфера (считанного из Интернета), и именно так я помещал его в tf.train.Example раньше:

 record = tf.train.Example(features=tf.train.Features(feature={
    'image/encoded': dataset_util.bytes_feature(image_bytes)
    # there are more features but they're not relevant
}))
  

Однако для моего использования изображения слишком большие, поэтому я хотел бы изменить их размер либо до того, как я помещу их в tf.train.Example , либо сразу после (в зависимости от того, что проще).

Вот что я пытаюсь:

 # predeclared
# - image_bytes
# - image_format
# - height
# - width

# resize image
if image_format == b'jpeg':
    image = tf.image.decode_jpeg(image_bytes, None, tf.float32)
elif image_format == b'png':
    image = tf.image.decode_png(image_bytes, None, tf.float32)

image = tf.image.resize_images(image, (int(height), int(width)))

image = tf.image.convert_image_dtype(image, tf.uint8)
record = tf.train.Example(features=tf.train.Features(feature={
    'image/encoded': dataset_util.bytes_feature(tf.image.encode_jpeg(image))
    # there are more features but they're not relevant
}))
  

Я подозреваю, что это действительно до тех пор, пока я на самом деле не попытаюсь поместить его в tf.train.Example , после чего он сообщает мне TypeError: <tf.Tensor 'EncodeJpeg:0' shape=() dtype=string> has type Tensor, but expected one of: bytes . Я пытался выяснить, как получить Tensor в BytesList или что-то подобное, но я не смог найти никакой документации для этого. Я подозреваю, что может быть лучший способ приблизиться ко всему процессу, однако.

Как я могу сделать это правильно?

Комментарии:

1. Вы храните изображения в виде массивов байтов?

2. Они поступают из Интернета в виде массивов байтов. На самом деле это не связано с TF.

3. Ошибка указывает, что этот тензор должен быть оценен. Вы пробовали использовать numpy или cv2 для кодирования / декодирования?

4. Нет. Я действительно не знаю, как это сделать. Как указано, что этот тензор должен быть оценен? Мне кажется, что он просто говорит, что хочет быть преобразован в байты, что я бы не назвал «оценкой». Это просто данные, верно?

5. tf.image.encode_jpeg возвращает тензор, и для того, чтобы получить его содержимое, его следует запустить внутри сеанса

Ответ №1:

Вы можете изменить размер перед кодированием.

 def int64_feature(value):
    return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))

def bytes_feature(value):
    return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))
  

Преобразовать из строки и изменить размер

 image = numpy.fromstring(byte_arr).reshape((height, width, channels))
image_raw = image.tostring()
  

Затем сериализуйте как файл tfrecords

 writer = tf.python_io.TFRecordWriter(tfr_name)
example = tf.train.Example(features=tf.train.Features(feature{'height':int64_feature(height),
                                                              'width': int64_feature(width),
                                                              'channels': int64_feature(channels),
                                                              'image_raw': bytes_feature(image_raw),

writer.write(example.SerializeToString())
writer.close()
  

Комментарии:

1. Понял, спасибо. В итоге я использовал cv2, но я думаю, что это та же идея. Я думал, что мог бы использовать tensorflow для этого, но, похоже, оно того не стоит. Эта часть не критична к производительности.