0

I wrote a small piece of code that gives me hue values for a set of images in a folder. My goal is to create a hue-histogram much like in this article: http://blog.scottlogic.com/2014/04/12/app-colour-analysis.html

I'm currently collecting the data, but I'm only getting 0.0s, 60.0s, 120.0s, 180.0s, 240.0s, 300.0s values from a set of +5000 images. I heard hue goes from 0 to 360 and in the article, it looks like he gets 0.0s, 1.0s, 2.0s, 3.0s... etc. How? What is wrong with my code?

from PIL import Image
import _imaging
import colorsys
import os

h = 0

for file in os.listdir("/path/"):
    im = Image.open(file)
    width, height = im.size
    rgb_im = im.convert('RGB')

    widthRange = range(width)
    heightRange = range(height)

    for i in widthRange:
        for j in heightRange:
            r, g, b = rgb_im.getpixel((i, j))
            h, s, v = colorsys.rgb_to_hsv(r, g, b)
            h = h * 360
            # Rest of code stores h value for each pixel with a counter

"h" should be the HUE value for every pixel, it's all stored in a file.

vandernath
  • 3,665
  • 3
  • 15
  • 24

1 Answers1

1

Looks like PIL represents RGB values in the range of 0 to 255, whereas colorsys expects them to be in the range of 0 to 1. Try dividing before passing the values to rgb_to_hsv.

        r, g, b = rgb_im.getpixel((i, j))
        h, s, v = colorsys.rgb_to_hsv(r/255.0, g/255.0, b/255.0)
Kevin
  • 74,910
  • 12
  • 133
  • 166
  • Excellent solution. I'm still getting a big number of 0.0s compared to the rest--should I just assume it's just a popular colour in my set of images? I don't think it's the case because there's like 1947978 0.0s for, say, 10541 180.0s, the second biggest number. – vandernath Aug 04 '15 at 18:29
  • According to `help(colorsys)` all inputs and outputs are in the range `[0,1]` inclusive, so I think the denominator should be 255.0. – unutbu Aug 04 '15 at 18:36
  • @vandernath, that seems pretty high. The article you linked does seem to indicate that low saturation is more common, but not ten times more common than the next highest value. I would suspect an arithmetic problem somewhere else in your code. Are you using 2.7 or below? Watch out for [integer division](http://stackoverflow.com/questions/183853/in-python-what-is-the-difference-between-and-when-used-for-division). – Kevin Aug 04 '15 at 18:41
  • Yep, I'm using 2.7. I divided by 255.0 using / at first same number of 0.0s. Now 255.0 using // -- now I get 3003543 of 0.0s which is even higher. Not sure where the problem might be coming from. – vandernath Aug 04 '15 at 18:59
  • What I mean is, you might be dividing by an integer somewhere, expecting a floating point result, and getting a truncated integer instead. So replacing `/` with `//` will have the opposite of the desired effect. – Kevin Aug 04 '15 at 19:06
  • I switched back to /. Same number. Any idea where else the problem might be coming from? – vandernath Aug 04 '15 at 20:13
  • It's hard to investigate further without an [MCVE](http://stackoverflow.com/help/mcve). – Kevin Aug 04 '15 at 20:16