将 python opencv mat 图像转换为 tensorflow 图像数据
Posted
技术标签:
【中文标题】将 python opencv mat 图像转换为 tensorflow 图像数据【英文标题】:Convert python opencv mat image to tensorflow image data 【发布时间】:2017-03-09 11:01:04 【问题描述】:我想用 python 和 opencv 从视频中捕获帧,然后用 tensorflow 对捕获的 Mat 图像进行分类。问题是我不知道如何将 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)
如果有任何帮助,我将不胜感激,在此先感谢
【问题讨论】:
import tensor with mat format to tensorflow的可能重复 【参考方案1】:使用 imread 加载 OpenCV 图像,然后将其转换为 numpy 数组。
要输入 inception v3,您需要使用 Mult:0 张量作为入口点,这需要一个具有以下布局的 4 维张量:[Batch index,Width,Height,Channel] 最后三个来自 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!
亲切的问候,
克里斯
编辑:我刚刚注意到,初始网络希望将强度值归一化为 [-0.5,0.5],因此请在构建 RGB 图像之前使用此代码对其进行转换:
np_image_data=cv2.normalize(np_image_data.astype('float'), None, -0.5, .5, cv2.NORM_MINMAX)
【讨论】:
即使是视频帧也能完美运行。我使用以下代码使用 OpenCV + Tensorflow 分析视频文件。ret, frame = cap.read()
image = cv2.resize(frame,dsize=(299,299), interpolation = cv2.INTER_CUBIC)
np_image_data = np.asarray(image)
image = np.expand_dims(image, axis=0)
image = preprocess(image)
preds = model.predict(image)
【参考方案2】:
使用 Tensorflow 2.0 和 OpenCV 4.2.0,您可以通过这种方式进行转换:
import numpy as np
import tensorflow as tf
import cv2 as cv
width = 32
height = 32
#Load image by OpenCV
img = cv.imread('img.jpg')
#Resize to respect the input_shape
inp = cv.resize(img, (width , height ))
#Convert img to RGB
rgb = cv.cvtColor(inp, cv.COLOR_BGR2RGB)
#Is optional but i recommend (float convertion and convert img to tensor image)
rgb_tensor = tf.convert_to_tensor(rgb, dtype=tf.float32)
#Add dims to rgb_tensor
rgb_tensor = tf.expand_dims(rgb_tensor , 0)
#Now you can use rgb_tensor to predict label for exemple :
#Load pretrain model, made from: https://www.tensorflow.org/tutorials/images/cnn
model = tf.keras.models.load_model('cifar10_model.h5')
#Create probability model
probability_model = tf.keras.Sequential([model,
tf.keras.layers.Softmax()])
#Predict label
predictions = probability_model.predict(rgb_tensor, steps=1)
【讨论】:
【参考方案3】:看起来您正在使用预训练和预定义的 Inception 模型,该模型有一个名为 DecodeJpeg/contents:0
的张量。如果是这样,这个张量需要一个包含 JPEG 图像字节的标量字符串。
您有两种选择,一种是在网络中进一步查找 JPEG 转换为矩阵的节点。我不确定 MAT 格式是什么,但这将是 [height, width, colour_depth]
表示。如果您可以获取该格式的图像,则可以将 DecodeJpeg...
字符串替换为您要输入的节点的名称。
另一种选择是简单地将图像转换为 JPEG 格式并直接输入。
【讨论】:
谢谢马克,我解决了将 opencv Mat 图像保存到临时文件中然后在我发布时加载的问题。这不是最干净的解决方案,但它有效【参考方案4】:您应该能够将 opencv mat 格式转换为 numpy 数组:
np_image_data = np.asarray(image_data)
一旦您将数据作为 numpy 数组,您就可以通过 feeding mechanism 将其传递给张量流,如 @thesonyman101 引用的链接中所示:
feed_dict = some_tf_input:np_image_data
predictions = sess.run(some_tf_output, feed_dict=feed_dict)
【讨论】:
【参考方案5】:在我的情况下,我必须从文件中读取图像,进行一些处理,然后注入 inception 以从称为最后一层的特征层获得返回。 我的解决方案简短但有效。
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)
【讨论】:
以上是关于将 python opencv mat 图像转换为 tensorflow 图像数据的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Mat 数据(OpenCV,图像数据格式)转换为统一的 3d 纹理
python+opencv2怎么将图像像素值转换为float64用于后续计算
opencv中Mat与IplImage,CVMat类型之间转换