Je veux capturer des images d'une vidéo avec Python et OpenCV, puis classifier les images Mat capturées avec tensorflow. Le problème est que je ne sais pas comment convertir le format Mat en une variable 3D Tensor. Voici comment je me débrouille avec tensorflow (chargement de l'image à partir d'un fichier):
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})
J'apprécierai toute aide, merci d'avance
Chargez l'image OpenCV en utilisant imread, puis convertissez-la en un tableau numpy.
Pour alimenter inception v3, vous devez utiliser le tenseur Mult: 0 comme point d’entrée. Cela suppose un tenseur à 4 dimensions doté de la présentation suivante: [Index de lot, Largeur, Hauteur, Canal] bien d'un cv :: Mat, le premier doit simplement être 0, car vous ne voulez pas alimenter un lot d'images, mais une seule image. Le code ressemble à ceci:
#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!
Sincères amitiés,
Chris
Edit: Je viens de remarquer que le réseau d’initialisation souhaite que les valeurs d’intensité soient normalisées sous la forme de valeurs flottantes définies à [-0.5,0.5]. Veuillez donc utiliser ce code pour les convertir avant de créer l’image RVB:
np_image_data=cv2.normalize(np_image_data.astype('float'), None, -0.5, .5, cv2.NORM_MINMAX)
Il semble que vous utilisiez le modèle Inception pré-formé et prédéfini, qui a un tenseur nommé DecodeJpeg/contents:0
. Si tel est le cas, ce tenseur attend une chaîne scalaire contenant les octets d'une image JPEG.
Vous avez deux options. L’une consiste à examiner plus en profondeur le nœud où le fichier JPEG est converti en matrice. Je ne suis pas sûr du format MAT, mais ce sera une représentation [height, width, colour_depth]
. Si vous pouvez obtenir votre image dans ce format, vous pouvez remplacer la chaîne DecodeJpeg...
par le nom du nœud que vous souhaitez alimenter.
L’autre option consiste à convertir simplement vos images au format JPEG et à les transférer directement.
Vous devriez être capable de convertir le format mat opencv en un tableau numpy en tant que:
np_image_data = np.asarray(image_data)
Une fois que vous avez les données sous forme de tableau numpy, vous pouvez le transmettre au flux de tenseurs via un mécanisme d'alimentation comme dans le lien référencé par @ thesonyman101:
feed_dict = {some_tf_input:np_image_data}
predictions = sess.run(some_tf_output, feed_dict=feed_dict)
Dans mon cas, je devais lire une image à partir d'un fichier, effectuer un traitement, puis l'injecter dans le début pour obtenir le retour d'un calque d'entités appelé dernier calque.
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})