Преобразование изображения python opencv mat в данные изображения tensorflow

Я хочу захватить кадры из видео с python и opencv, а затем классифицировать захваченные изображения Мата с tensorflow. Проблема в том, что я не знаю, как преобразовать формат de Mat в переменную тензора 3D. Вот как я сейчас делаю с tensorflow (загрузка изображения из файла):

image_data = tf.gfile.FastGFile(imagePath, 'rb').read()
with tf.Session() as sess:
    softmax_tensor = sess.graph.get_tensor_by_name('final_result:0')
    predictions = sess.run(softmax_tensor,
                           {'DecodeJpeg/contents:0': image_data})

Я буду признателен за любую помощь, заранее спасибо

4 ответов


загрузите изображение OpenCV с помощью imread, затем преобразуйте его в массив numpy.

для подачи в inception v3 вам нужно использовать Тензор Mult:0 в качестве точки входа, это ожидает 4-мерный Тензор, который имеет макет: [индекс партии, ширина, высота, канал] Последние три отлично подходят для cv:: Mat, первый просто должен быть 0, так как вы не хотите кормить партию изображений, а одно изображение. Код выглядит так:

#Loading the file
img2 = cv2.imread(file)
#Format for the Mul:0 Tensor
img2= cv2.resize(img2,dsize=(299,299), interpolation = cv2.INTER_CUBIC)
#Numpy array
np_image_data = np.asarray(img2)
#maybe insert float convertion here - see edit remark!
np_final = np.expand_dims(np_image_data,axis=0)

#now feeding it into the session:
#[... initialization of session and loading of graph etc]
predictions = sess.run(softmax_tensor,
                           {'Mul:0': np_final})
#fin! 

вид с уважением,

Крис

Edit: я только что заметил, что начальная сеть хочет нормализовать значения интенсивности как поплавки до [-0.5, 0.5], поэтому, пожалуйста, используйте этот код для их преобразования перед построением изображения RGB:

np_image_data=cv2.normalize(np_image_data.astype('float'), None, -0.5, .5, cv2.NORM_MINMAX)

похоже, что вы используете предварительно обученную и заранее определенную модель начала, которая имеет тензор с именем DecodeJpeg/contents:0. Если это так, этот тензор ожидает скалярную строку, содержащую байты для изображения JPEG.

у вас есть несколько вариантов, один из которых-посмотреть дальше по сети для узла, где JPEG преобразуется в матрицу. Я не уверен, что формат мата, но это будет [height, width, colour_depth] представление. Если вы можете получить изображение в этом формате, вы можете заменить DecodeJpeg... строка с именем узла, в который вы хотите ввести канал.

другой вариант - просто конвертировать ваши изображения в JPEG и кормить их прямо.


вы должны иметь возможность конвертировать формат OpenCV mat в массив numpy как:

np_image_data = np.asarray(image_data)

Как только у вас есть данные в виде массива numpy, вы можете передать его тензорному потоку через механизм подачи как в ссылке, что @thesonyman101 ссылка:

feed_dict = {some_tf_input:np_image_data}
predictions = sess.run(some_tf_output, feed_dict=feed_dict)

в моем случае я должен был прочитать изображение из файла, выполнить некоторую обработку, а затем ввести в начало, чтобы получить возврат из слоя объектов, называемого последним слоем. Мое решение короткое, но эффективное.

        img = cv2.imread(file)
        ... do some processing 
        img_as_string = cv2.imencode('.jpg', img)[1].tostring()
        features = sess.run(last_layer, {'DecodeJpeg/contents:0': img_as_string})