BourbonCreams
BourbonCreams

Reputation: 383

How do I convert a numpy Array to a data type that tensorflow can classify?

I am writing a Python program to detect the state of a chess board and I am using a sliding window to detect the position of each piece. My main program detects the chessboard within an image and passes its cropped picture to the my_sliding_window method. This is supposed to use Tensorflow to detect a piece in the sliding window. From this tutorial I saw that pictures are read like this:

image_data = tf.gfile.FastGFile('picture.jpg', 'rb').read()

But I don't want to read it from file as I already have the picture in a numpy array. How do make my numpy array in such a way that it can be classified by Tensorflow?

Thank you.

Code:

import tensorflow as tf, sys
import cv2

image_path = sys.argv[1]


img = cv2.imread('picture.jpg')
image_data = tf.convert_to_tensor(img)
print type(image_data)    # this returns <class 'tensorflow.python.framework.ops.Tensor'>

# This is what is used in the tutorial I mentioned above
image_data2 = tf.gfile.FastGFile(image_path, 'rb').read()
print type(image_data2)    # this returns <type 'str'>


# Loads label file, strips off carriage return
label_lines = [line.rstrip() for line
               in tf.gfile.GFile("retrained_labels.txt")]

# Unpersists graph from file
with tf.gfile.FastGFile("retrained_graph.pb", 'rb') as f:
    graph_def = tf.GraphDef()
    graph_def.ParseFromString(f.read())
    _ = tf.import_graph_def(graph_def, name='')

with tf.Session() as sess:
    # Feed the image_data as input to the graph and get first prediction
    softmax_tensor = sess.graph.get_tensor_by_name('final_result:0')

    predictions = sess.run(softmax_tensor, \
         {'DecodeJpeg/contents:0': image_data})

    # Sort to show labels of first prediction in order of confidence
    top_k = predictions[0].argsort()[-len(predictions[0]):][::-1]

    for node_id in top_k:
        human_string = label_lines[node_id]
        score = predictions[0][node_id]
        print('%s (score = %.5f)' % (human_string, score))

Upvotes: 4

Views: 5958

Answers (2)

jzzzx
jzzzx

Reputation: 31

I solved the problem by using this one-liner:

image_data = cv2.imencode('.jpg', cv_image)[1].tostring()

Upvotes: 0

jabalazs
jabalazs

Reputation: 1264

You could use tf.convert_to_tensor() to convert your numpy array into a TensorFlow tensor:

This function converts Python objects of various types to Tensor objects. It accepts Tensor objects, numpy arrays, Python lists, and Python scalars.

Update

Ok, so what you're trying to do is to feed the numpy array image_data, with dimensions [123, 82] to the placeholder DecodeJpeg/contents:0. However that placeholder was defined with shape=() meaning it only accepts 0D tensors as input (see tensor shapes), hence throwing you an error.

What the original code does is to read an image as a dimensionless string with:

image_data = tf.gfile.FastGFile(image_path, 'rb').read()

which is then fed to the DecodeJpeg/contents:0 placeholder in:

predictions = sess.run(softmax_tensor, {'DecodeJpeg/contents:0': image_data})

The easiest way to proceed and try to run your images through the pretrained graph would be to use the same tf.gfile.FastGFile() call for loading the images.

Upvotes: 1

Related Questions