Results 1 to 4 of 4

Thread: Colours

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Jul 2000
    Posts
    225
    Hiyas,

    Let's set the scene - I have a world map in a game. There's three colours - the clicked colour, and two other colours which represent two different terrain types.

    Say we have a dark tropical rainforest and grassland for the two different terrain types.

    The clicked colour is somewhere in between the above colours, perhaps a slightly dark green.

    How do I figure out which one it's closer to, taking into account the actual colour and the shading? (eg. it would pick blue over red if the colour picked was green)

    I'm using the GetPixel function and I have the value in RGB.

    Hope someone knows what I'm talking about... =)

    Thanks.

    -Git

  2. #2

    Thread Starter
    Addicted Member
    Join Date
    Jul 2000
    Posts
    225
    Hmm... was just thinking.

    I could get the average from the RGB value ((R + B + G) / 3), converting it to B&W, for all 3 values, and then check which one is closer... Would that work? Or would it screw up because of shading?

    Hmm............... I think too much. ;-)

    -Git

  3. #3
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    Well, here's something i just put together, put all these stuff in a module and use the colordistance function. Two closer colors will return a lower number than two distant ones.
    Code:
    Type LngColor
        Color As Long
    End Type
    Type RGBColor
        Red As Byte
        Green As Byte
        Blue As Byte
    End Type
    
    
    Function ColorDistance(Color1 As Long, Color2 As Long) As Long
        Dim L1 As LngColor, L2 As LngColor, RGB1 As RGBColor, RGB2 As RGBColor
        L1.Color = Color1
        L2.Color = Color2
        LSet RGB1 = L1
        LSet RGB2 = L2
        ColorDistance = Abs(CLng(RGB1.Red) - RGB2.Red) + Abs(CLng(RGB1.Green) - RGB2.Green) + Abs(CLng(RGB1.Blue) - RGB2.Blue)
    End Function
    'Print ColorDistance(vbRed, vbBlue)
    '510
    'Print ColorDistance(vbYellow, vbBlue)
    '765
    'Print ColorDistance(vbYellow, vbRed)
    '255
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  4. #4
    Member
    Join Date
    Aug 2000
    Location
    USA
    Posts
    32

    May want to treat colorspace as 3Dimensional

    We don't want to add the three lengths, really. We can imagine colour existing in a three dimensional "colour space". The three axis are Red, Green, and Blue respectively. Given that visualization, we want to use the Pythagorean Thereom (aka The Distance Formula.)

    I'll just copy kedaman's code and make the appropriate changes, to make it easy to see what's happening ... (and because I'm lazy!)

    Code:
    Type LngColor
        Color As Long
    End Type
    Type RGBColor
        Red As Byte
        Green As Byte
        Blue As Byte
    End Type
    
    
    Function ColorDistance(Color1 As Long, Color2 As Long) As Long
        Dim L1 As LngColor, L2 As LngColor, RGB1 As RGBColor, RGB2 As RGBColor
        Dim rd As Long, gd As Long, bd As Long
        L1.Color = Color1
        L2.Color = Color2
        LSet RGB1 = L1
        LSet RGB2 = L2
    
        rd = RGB1.Red - RGB2.Red
        gd = RGB1.Green - RGB2.Green
        bd = RGB1.Blue - RGB2.Blue
        ColorDistance = Int(Sqr(rd * rd + gd * gd + bd * bd))
         'Note:  if all you care about is which color is *CLOSEST* to some other color, you can drop the "Sqr"
    End Function


    The thing is, well, as far as a computer cares, while working with RGB format, Green is *completely* unlike Blue--as in completely. Of course, Blue is even more different from Yellow. Even bright blue. That's wrong. We need to compare the brightness and the coloration slightly differently ... so ...

    (btw, you can head to http://www.wotsit.org ... lots of format info -- I got the YCbCr info out of the JPEG format ... probably not too useful for VB, tho')

    Here's a matrix to convert to chrominance/luminance:

    Code:
    (R,G,B are 8-bit unsigned values)
    
    	| Y  |     |  0.299       0.587       0.114 |   | R |     | 0 |
    
    	| Cb |  =  |- 0.1687    - 0.3313      0.5   | * | G |   + |128|
    
    	| Cr |     |  0.5       - 0.4187    - 0.0813|   | B |     |128|
    Ok, so matrices aren't too useful. Let's turn this into some VB code ...

    Code:
    'R G B are all single byte values -- from 0 to 255
    Dim Y As Single, Cb As Single, Cr As Single
    
    Y = 0.299*R + 0.587*G + 0.114*B
    Cb =  - 0.1687*R - 0.3313*G + 0.5   *B + 128
    Cr =    0.5   *R - 0.4187*G - 0.0813*B + 128
    
    
    'Converting back ... this isn't as important, but ...
    R = Y                    + 1.402  *(Cr-128)
    G = Y - 0.34414*(Cb-128) - 0.71414*(Cr-128)
    B = Y + 1.772  *(Cb-128)
    Now, we can use the Y, Cb, and Cr values in the distance formula like we did with RGB. That should work, although a little bit of tweaking may be in order. btw, if you want to take the average of two colors, you'll be best off if you convert both RGBs to YCbCr, average those, and convert it back, although that takes way longer. ;)
    -Koralt

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width