Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Color comparison

Discussion in 'Scripting' started by BeatrizSG, Apr 25, 2016.

  1. BeatrizSG

    BeatrizSG

    Joined:
    Mar 2, 2016
    Posts:
    2
    Hi All

    I'm working on a little project related to colors. So the idea is this:
    - I use the camera from the device (a camera from an android device, or any other type),then I take the pixels from an area from that camera.
    - With that pixels a take the average between all the colors and get a scanned final color. This part is alright and done.
    - The tricky part comes now, I need to compare that color with a list of colors given in the editor. So my question is, what is the best way to compare colors? The problem comes because I only have 10 colors and they are pure. So, for instance, If I scan a color that my eye thinks is a yellow I need to get that the scanned color is yellow.
    Anybody has a good algorithm to compare color? I read a lot about this issue and it's not easy.

    Thanks in advance
     
  2. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
  3. astrokoala

    astrokoala

    Joined:
    Mar 23, 2016
    Posts:
    22
    Color can be represented not just in RGB, but also HSV, and bunch of others

    in your case, you can convert the color to HSV which stands for Hue, saturation, Vibrance?(brightness)
    Code (CSharp):
    1. Color input;
    2. float hue;
    3. float saturation;
    4. float brightness;
    5. Color.RGBToHSV(input, out hue, out saturation, out brightness)
    after this, it is fairly easy to compare colors.
    in your case, yellow is represented by hue in a range of about 40 to 70
     
    gorbit99 likes this.
  4. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    The problem here, that you still need to account for the brightness and saturation values because it's great that you can easily compare greenish yellow or blueish yellow, but dark yellow and light yellow is still there
     
  5. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    True, but OP was talking about finding the nearest colour to a list of 10 colors, that they describe as "pure" (whatever that means).

    More information is needed from OP, but with such a short list, I suspect that the colour differences of the 10 colour palette is probably related to Hue rather than brightness or saturation.

    So astrokoala's HSV scenario could be used.

    Of course, it'd be a very limited use, and if the colour palette ever changed the algorithm would have to be reconsidered. Where as a true colour difference algorithm would be better.
     
  6. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    I think by pure he means, that rgb values are either 255 or 0, so pure green is 0 255 0, pure purple is 255 0 255 and so on
     
    LeftyRighty likes this.
  7. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    we can guess what they mean all we want, we need more information from OP.

    And if that is what they mean... then yes, astrokoala's example would actually work.
     
  8. Zaflis

    Zaflis

    Joined:
    May 26, 2014
    Posts:
    438
    But colors are float values. In case of red color(1, 0, 0) vs color(0.9999, 0, 0) difference would be so small anyone couldn't tell. But it also speaks of comparison between float values, which you can't do with equal sign ==.
     
  9. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    Colours can be float values from 0->1, or they can be byte values (0->255).

    And if you change into some colour spaces, you might have float values in a range of 0->360, because the colour space is defined radially.

    It just happens the Unity 'Color' type stores them as floats from 0->1 in the RGB colour space. But 'Color32' stores them as integers in the '0->255' range and in the RGB colour space. But you can convert from colour space relatively easily, as astrokoala showed where Unity has a built in RGBtoHSV method.
     
  10. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    Not byte, hexadecimal
    Originally, colours are discribed as a 6 digit hexadecimal number, 5F19A4 for example. This is divided into 3 2digit parts (5F, 19 and A4). Becuase it's hexadecimal, there are 16^2=256 different values for these two digits. Because programming logic, it goes from 0 to 255 where 00 is 0 and FF is 255. The color I just wrote down is therefore (96, 25, 164) or in unity standards 255/96 = 2.65625, 255/25=10.2, 255/164=1,56

    This is what you call true color, anything other than this WILL get rounded to the nearest value, this is why i think, that unity's system is stupid, because you CAN'T have as many colors as you want, and showing them in a simple 0-255 style just makes life easier (if the difference in a 0-255 system is 1, so 00 to 01 for example, then that means, that for unity it's 0,0039 in unity's measurement)
     
  11. gorbit99

    gorbit99

    Joined:
    Jul 14, 2015
    Posts:
    1,350
    An idea I found online is to convert the colors into HSL values and then just get the distance like you would with a normal Vector3:
    d = Mathf.Sqrt(Mathf.Pow(c1.h - c2.h, 2), Mathf.Pow(........));
    It's not perfect because the human eye sees a lot more green shades than red shades, but for a small project it's good enough
     
  12. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    facepalm...

    a 2-digit hexadecimal value has a max value of FF. Which is 16^2 - 1 (100 in hex is 16^2).

    16^2 is 256, minus 1, it's 255.

    Why 16? It's what hexadecimal means (hex is 6, deci is 10, it's saying base 16).

    We use base 16 because it's shorter than writing binary, and 4 binary digits (bits) fit into one hex digit. So, 255 in binary is 11111111. Or 2^8 - 1.

    Note how there's 8 1's in that...

    What is an 8 digit binary value referred to as?

    A BYTE
     
    Last edited: Apr 25, 2016
    Munchy2007 and Kiwasi like this.
  13. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    Since you are acquiring the pictures from a camera, it is almost certain that the color is altered (which is normal in photography). You would need to white balance your picture before comparing the colors to references. The best scenario would be to have a "pure" white object in your scene, have a way to detect it, white balance the picture relative to that object, only then you can compare the color with more reliability.