-2

I just begin to learn about python. When I execute the code below, I get an error. It tells that Traceback (most recent call last): File "predict_1.py", line 87, in main(sys.argv[1]) IndexError: list index out of range

Any help is greatly appreciated. Thank for your reading!

#import modules
import sys
import tensorflow as tf
from PIL import Image,ImageFilter

def predictint(imvalue):
  """
  This function returns the predicted integer.
  The imput is the pixel values from the imageprepare() function.
  """

  # Define the model (same as when creating the model file)
  x = tf.placeholder(tf.float32, [None, 784])
  W = tf.Variable(tf.zeros([784, 10]))
  b = tf.Variable(tf.zeros([10]))
  y = tf.nn.softmax(tf.matmul(x, W) + b)

  init_op = tf.initialize_all_variables()
  saver = tf.train.Saver()

  """
  Load the model.ckpt file
  file is stored in the same directory as this python script is started
  Use the model to predict the integer. Integer is returend as list.

  Based on the documentatoin at
  https://www.tensorflow.org/versions/master/how_tos/variables/index.html
  """
  with tf.Session() as sess:
      sess.run(init_op)
      new_saver = tf.train.import_meta_graph('model.ckpt.meta')
  new_saver.restore(sess, "model.ckpt")
      #print ("Model restored.")

      prediction=tf.argmax(y,1)
      return prediction.eval(feed_dict={x: [imvalue]}, session=sess)


def imageprepare(argv):
  """
  This function returns the pixel values.
  The imput is a png file location.
  """
  im = Image.open(argv).convert('L')
  width = float(im.size[0])
  height = float(im.size[1])
  newImage = Image.new('L', (28, 28), (255)) #creates white canvas of 28x28 pixels

  if width > height: #check which dimension is bigger
      #Width is bigger. Width becomes 20 pixels.
      nheight = int(round((20.0/width*height),0)) #resize height according to ratio width
      if (nheigth == 0): #rare case but minimum is 1 pixel
          nheigth = 1  
      # resize and sharpen
      img = im.resize((20,nheight), Image.ANTIALIAS).filter(ImageFilter.SHARPEN)
      wtop = int(round(((28 - nheight)/2),0)) #caculate horizontal pozition
      newImage.paste(img, (4, wtop)) #paste resized image on white canvas
  else:
      #Height is bigger. Heigth becomes 20 pixels. 
      nwidth = int(round((20.0/height*width),0)) #resize width according to ratio height
      if (nwidth == 0): #rare case but minimum is 1 pixel
          nwidth = 1
       # resize and sharpen
      img = im.resize((nwidth,20), Image.ANTIALIAS).filter(ImageFilter.SHARPEN)
      wleft = int(round(((28 - nwidth)/2),0)) #caculate vertical pozition
      newImage.paste(img, (wleft, 4)) #paste resized image on white canvas

  #newImage.save("sample.png")

  tv = list(newImage.getdata()) #get pixel values

  #normalize pixels to 0 and 1. 0 is pure white, 1 is pure black.
  tva = [ (255-x)*1.0/255.0 for x in tv] 
  return tva
  #print(tva)

def main(argv):
  """
  Main function.
  """
  imvalue = imageprepare(argv)
  predint = predictint(imvalue)
  print (predint[0]) #first value in list

  if __name__ == "__main__":
  main(sys.argv[1])
Marco N.
  • 185
  • 2
  • 8
  • 2
    No, _this_ code will just give indentation errors. You need to reproduce your indentation accurately when posting Python code. Badly indented Python code is nonsense. – khelwood Jun 02 '17 at 08:28
  • 1
    Please read [ask] and try to provide a [mcve] - currently your code has severe indentation problems (most likely due to formatting). – Christian König Jun 02 '17 at 08:28
  • Why do we need to see all that code? Most of it is irrelevant to this error. How did you run the script? Did you supply a proper `imageprepare` argument string on the command line? – PM 2Ring Jun 02 '17 at 08:30
  • 1
    Your error clearly states that you try to access the second command line argument (by `sys.argv[1]`), which obviously does not exist, thus throwing an `IndexError`. – Christian König Jun 02 '17 at 08:30

2 Answers2

0

You should provide an argument to your script, i.e. call it like

predict_1.py path_to_your_file
Vahagn
  • 386
  • 2
  • 21
0

First, before to access item in a list by index, you always must check bounds of a list OR to catch exception and to process case of "out-of-range" (IndexError in the case).

Second, better is to begin to use argparse module. Also there is simpler getopt module, you can find many examples for them in Web, in Python standard documentation, etc. They allow to your script to have more convenient command line arguments, like in Unix tools (optional, positional, with default values, etc, etc, etc).

RandomB
  • 3,367
  • 19
  • 30