PutraKg
PutraKg

Reputation: 2246

Categorize a random color into one of the primary colors Windows Phone

I am trying to create a method that accepts a random color value then check which primary colors it's closest to.

enter image description here

I imagine I have to compare its RGB value and see where it falls within the range of those primary colors and then set it as Red, or Yellow or Blue etc.

What is the best way of doing this? Thanks

EDIT This question is marked as duplicate but I checked the other answer of the said duplicate question but it doesn't offer the answer I am after.

using the formula

d = sqrt((r2-r1)^2 + (g2-g1)^2 + (b2-b1)^2)

sometimes produce the same value for different colors. For instance take an input color of R170 : G0 : B255. The distances from both white R255 : G255 : B255 and red R255 : G0 : B0 produce (int)269 using the formula. So which color is closer, red or white? I removed black and white from the list but the problem still occurs for some other colors.

I am comparing with several colors i.e: black, white, red, lime. blue, yellow, cyan. magenta and gray as listed in the RGB color table here rapidtables.com/web/color/RGB_Color.htm

Upvotes: 2

Views: 693

Answers (2)

jHogen
jHogen

Reputation: 123

If you want a real comparison between two colors you shouldn't use the RGB color space. It's not suited for color calculations.

Your best bet is to convert it to LAB color space. LAB space

To achieve this you need to convert the RGB to XYZ values and then convert these to LAB. You can find the calculations for this on this website: Bruce Lindbloom

When you have the LAB colors you can choose a difference formula. The easiest is the CIE74, but if you want the most accurate results you need to use the CIEDE2000. Difference Formulas

I've used these formulas for the last 5 months on a project I worked on, so if you need any help just let me know.

Upvotes: 0

Sayse
Sayse

Reputation: 43300

I don't have an IDE infront of me but here's my comment in pseudo (Can update later if necessary)

var closestColor

Get vector magnitude of( myR + 255, myG, myB)
set closestColor to Red

Get vector magnitude of( myR , myG+ 255, myB)
If(Green is closer than red)
 set closestColor to Green

Get vector magnitude of( myR , myG, myB + 255)
If(Blue is closer than closestColor)
 set closestColor to Blue

Return closest color

Update

I did a quick linq example with extension

    public static double VectorMagnitude(this Color c, Color otherC)
    {
        return Math.Sqrt(((int)(c.R + otherC.R))^2 + 
            ((int)(c.G + otherC.G))^2 + 
            ((int)(c.B + otherC.B))^2); 
    }

    private static List<Color> Colors()
    {
        return new List<Color>()
        {
            Color.Red,
            Color.Blue,
            Color.FromArgb(0,255,0)
        };
    }

 var l = Colors().OrderBy(x => x.VectorMagnitude(
                Color.FromArgb(255, R, G, B))).FirstOrDefault();

Upvotes: 2

Related Questions