2016-01-27 2 views
5

Я создал набор данных и сохранил его в файле TFRecord. Дело в том, что изображения имеют разный размер, поэтому я хочу также сохранить размер с изображениями. Таким образом, я использовал TFRecordWriter и определены функции, такие как:Как читать изображения с разным размером в файле TFRecord

example = tf.train.Example(features=tf.train.Features(feature={ 
    'rows': _int64_feature(image.shape[0]), 
    'cols': _int64_feature(image.shape[1]), 
    'image_raw': _bytes_feature(image_raw)})) 

Я ожидал, что я могу читать и декодировать изображение с помощью TFRecordReader, но дело в том, что я не могу получить значение строк и перевалы из файла, потому что они тензоры. Итак, как я должен делать, чтобы динамически читать размер и соответствующим образом изменять изображение. Спасибо ребятам

ответ

2

Вы можете позвонить tf.reshape с динамическим параметром shape.

image_rows = tf.cast(features['rows'], tf.int32) 
image_cols = tf.cast(features['cols'], tf.int32) 
image_data = tf.decode_raw(features['image_raw'], tf.uint8) 
image = tf.reshape(image_data, tf.pack([image_rows, image_cols, 3])) 
+0

он поднял ошибку «Все формы должны быть полностью определены: 1». из журнала, похоже, что он имеет какое-то отношение к функции «tf.train.shuffle_batch()». Что я должен делать тогда? –

+0

пакет должен знать фигуры во время построения графика (чтобы он знал, сколько памяти выделяется для очереди), возможно, используйте tf.image.resize_images перед tf.batch? Если вы используете какой-либо из стандартных коннектов, вам все равно придется изменять размер изображений до одинакового размера –

+0

+ Tong Shen, так как вы создаете пакет, изображения должны иметь одинаковый размер. Если вы знаете этот размер заранее, возможно, вы можете вызвать что-то вроде 'image.set_shape ([32,32,3])', чтобы полностью определить форму. – bgshi

2

Я предлагаю рабочий процесс, как:

TARGET_HEIGHT = 500 
TARGET_WIDTH = 500 

image = tf.image.decode_jpeg(image_buffer, channels=3) 
image = tf.image.convert_image_dtype(image, dtype=tf.float32) 

# Choose your bbox here. 
bbox_begin = ... (should be (h_start, w_start, 0)) 
bbox_size = tf.constant((TARGET_HEIGHT, TARGET_WIDTH, 3), dtype=tf.int32) 

cropped_image = tf.slice(image, bbox_begin, bbox_size) 

cropped_image имеет постоянный размер тензор, а затем может быть выброшен в случайном порядке партии.

Вы можете динамически получать доступ к размеру декодированного изображения, используя tf.shape(image). Вы можете делать вычисления на результирующих подэлементах, а затем сшивать их вместе, используя что-то вроде bbox_begin = tf.pack([bbox_h_start, bbox_y_start, 0]). Просто нужно вставить свою собственную логику для определения начальных точек урожая и того, что вы хотите сделать, если изображение начнет меньше, чем вы хотите для своего конвейера.

Если вы хотите переместить только, если изображение меньше ваших целевых размеров, вам необходимо использовать tf.control_flow_ops.cond или его эквивалент. Но у вас может использовать минимальные и максимальные операции для установки размера окна обрезки, чтобы вы возвращали полное изображение, если оно меньше требуемых размеров, а затем безоговорочно изменяют размер до 500x500. Обрезанное изображение уже будет размером 500x500, поэтому изменение размера должно стать эффективным no-op.

+0

Этот рабочий процесс будет работать с файловой очередью FIFO? Теперь дело в том, что я хочу случайным образом обрезать картинку с использованием 500 * 500, ваш путь кажется обрезкой фиксированной области. Теперь я изменил размер изображений заранее, так что минимальный размер равен или больше 500. Единственное, с чем я столкнулся, это то, как декодировать изображение из необработанной строки и изменить его на исходный размер. Поскольку вес и высота изменяются в изображениях, мы не можем использовать фиксированный размер. –

+0

Правильно, вам нужно случайно выбрать начало 500x500 bbox. Установив bbox_size в [500, 500, 3] (3 для # каналов), вы получите урожай 500x500. Вы должны установить начальные точки для вашего случайного урожая в зависимости от вашего предпочтительного алгоритма случайных уроков. Учитывая, что вы изменили размер, вы можете просто сделать «imageshape = tf.shape (image)», а затем установить начальные и конечные точки, например: 'h_start = tf.random_uniform ([], minval = 0, maxval = imageshape [0 ] -500, dtype = tf.int32) 'и аналогично для w_start. – dga

Смежные вопросы