Преобразование изображения 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})