0

can someone explain me how the main function for the code below works? what does it mean by the average_image_color() function take argument of sys.argv[1] in the main function?

from PIL import Image

def average_image_color(filename):

    i = Image.open(filename)
    h = i.histogram()

    # split into red, green, blue
    r = h[0:256]
    g = h[256:256*2]
    b = h[256*2: 256*3]

    # perform the weighted average of each channel:
    # the *index* is the channel value, and the *value* is its weight
    return (
        sum( i*w for i, w in enumerate(r) ) / sum(r),
        sum( i*w for i, w in enumerate(g) ) / sum(g),
        sum( i*w for i, w in enumerate(b) ) / sum(b)
    )

if __name__ == '__main__':

    import sys

    if len(sys.argv) > 1:
       print average_image_color(sys.argv[1])
    else:
      print 'usage: average_image_color.py FILENAME'
      print 'prints the average color of the image as (R,G,B) where R,G,B are between 0 and 255.'

I found code above from githubsThank you so much!

Saksham Varma
  • 2,122
  • 13
  • 15
Flora
  • 11
  • 1
  • 1
  • 5

2 Answers2

1

sys.argv[1] is the argument provided to the program while running it, which is the image filename in this case.

So you run the program as, python myprogram.py path/to/image/filename.jpg. So argv[1] will be path/to/image/filename.jpg

Saksham Varma
  • 2,122
  • 13
  • 15
Barun Sharma
  • 1,452
  • 2
  • 15
  • 20
0

sys.argv is a the list of command line arguments that you pass to your script, when you run them from the command line. The first element in this list is always the path of your python script itself. So, sys.argv[0] is the path to your python script. In your case, the second argument is the path to color/input file.

In case the second argument is not supplied, the len of the argv list would be just 1, and the the function average_image_color won't be called. If this second arg is supplied, it would call the function, passing this arg as a parameter. The command would look like this:

python script.py /path/to/the/image/input/file

If you would not like to use command line then, image files can be read from a directory:

import os

if __name__ == '__main__':

    dirpath, dirnames, filenames = next(os.walk('/path/to/images/directory'))
    for filename in filenames:
        print average_image_color(os.path.join(dirpath, filename))
Saksham Varma
  • 2,122
  • 13
  • 15
  • Thank you so much! but when I run, the output is ''usage: average_image_color.py FILENAME' and 'the average color of the image as (R,G,B) where R,G,B are between 0 and 255.' which means there is no argument supplied. how do I supply the argument anyway? thanks – Flora Apr 19 '15 at 06:00
  • @Flora You need to open your command line (CMD for windows), terminal for Linux/Mac, and call your script with the image file path, from there, using the command I mentioned in my answer. The other option is to remove the if-else clause with just this ```print average_image_color("path/to/image/file")```. Hope it helps! – Saksham Varma Apr 19 '15 at 06:05
  • its worked. thank you so much. alright, will do. but anyway, can you explain to me how this line works? "sum( i*w for i, w in enumerate(r) ) / sum(r)" ? what does 'w' stands for? – Flora Apr 19 '15 at 15:50
  • ```enumerate(r)``` basically unpacks to a list of ```(i, w)``` pairs, where ```i``` is the index of item ```w``` in ```r``` . ```i*w for i, w in enumerate(r)``` will return a list where each element is the product of the index in ```r``` to which it corresponds and the value at that index in ```r```. The ```sum()``` function around would sum up all these products. Similarly, ```sum(r)``` would sum up all items in list ```r```. – Saksham Varma Apr 19 '15 at 18:49
  • Thank you so much @SakshamVarma. You help alot. and one more last thing, I have tried to change from load an image to get an Image by **cam.getImage()** , but it doesn't work. Here is the code I have changed: **cam = Camera() >>> img = cam.getImage() >>> if len(sys.argv) > 1: >>>print average_image_color(img)** – Flora Apr 20 '15 at 01:58
  • Not sure what is cam.getImage(). The code in the comment has some syntax issues, `if __name__ == '__main__':`. I can't tell what you tried to change here? – Saksham Varma Apr 20 '15 at 02:06
  • Sorry, I'm not familiar with this package that you are using :-| – Saksham Varma Apr 20 '15 at 02:13
  • I'm actually trying to call images from a folder to go through the **average_image_color()** function. Let say I have captured 10 images in loop, process the images and save it in the same directory of my program file. Do you have any idea on how can I call these images one by one to go through this function and get their rbg color? – Flora Apr 20 '15 at 02:17
  • You should use `os.walk` for this purpose, I'll edit my answer indicating it's use. – Saksham Varma Apr 20 '15 at 02:27