Click to See Complete Forum and Search --> : match color


May 15th, 1999, 06:56 AM
If I have known the RGB value of some basic colors and another specific color, how to judge which basic color the specific color is most visually similar to? Hope your help.

JonJon
May 15th, 1999, 09:24 AM
The simplistic approach would be to use the distance formula. The Distance value below can be used to indicate how large of a distance between two color coordinates (or points in space). The algorithm follows:

Given

RGB(r1,g1,b1)
RGB(r2,g2,b2)

Distance = squareroot( square(r2 - r1) + square(g2 - g1) + square(b2 - b1) )

I am not sure how effective this method would be for computing "color distance". For example, human vision is more sensitive to green than to other hues, but in theory it should work fairly well.

May 16th, 1999, 01:18 AM
Thank your help. I had tried the method you mentioned before I posted the question. But the result is incorrect because the visual effect is not proportional to RGB value. For example, the color(128,255,255) is more similar to white(255,255,255) than cyan(0,255,255) according to calculation, actually, this color is almost same as cyan visually.

JonJon
May 17th, 1999, 12:55 AM
You are right! After thinking it over I realized that what you should really use is a different color model to make your color comparisons. If you have already solved this problem, please disregard the rest of this...

I wrote a small test program that converts input RGB values into HSV (HSB). It then uses the hue, saturation and brightness values to compare the colors. Hue proximity should be weighted more heavily, followed by saturation, and finally brightness. The algorithm is not complete, but it may serve as a starting point if nothing else.
The code to convert from RGB to HSV follows:

#define MIN(a,b) ( (a > b)? b : a )
#define MAX(a,b) ( (a > b)? a : b )

typedef struct
{
double red;
double green;
double blue;
} RGB_DATA;

typedef struct
{
double hue; /* Angle in degrees about the HSV hexcone. */
double saturation; /* from 0.0 to 1.0 (0 percent to 100 percent) */
double value; /* from 0.0 to 1.0 (sometimes called brightness) */
} HSV_DATA;



/*
*-----------------------------------------------------------------------
*
* FUNCTION: RGB_to_HSV
*
* This function converts an RGB color to an HSV color.
*
* The color model conversion algorithms are based on the
* algorithms published in Computer Graphics: Principles and Practice -
* Second Edition in C, by James D. Foley, Andries van Dam, Steven K. Feiner,
* and John F. Hughes, published by Addison-Wesley Publishing Company
* (Reprinted with corrections November 1992, November 1993, and July 1995),
* Copyright 1996, 1990 by Addison-Wesley Publishing Company, Inc.
*
*-----------------------------------------------------------------------
*/
HSV_DATA CColormatchDlg::RGB_to_HSV(RGB_DATA rgb_in)
{
HSV_DATA hsv_out;

double max = MAX(rgb_in.red, MAX(rgb_in.green, rgb_in.blue));
double min = MIN(rgb_in.red, MIN(rgb_in.green, rgb_in.blue));
double delta = max - min;

hsv_out.value = max;

if (max==min) /* red, green, and blue were all identical */
{
/*
* This is the achromatic case.
*/
hsv_out.saturation = 0.0;
hsv_out.hue = 0.0;
}
else
{
hsv_out.saturation = delta / max;

if (rgb_in.red == max)
{
hsv_out.hue = (rgb_in.green - rgb_in.blue) / delta;
}
else if (rgb_in.green == max)
{
hsv_out.hue = 2.0 + (rgb_in.blue - rgb_in.red) / delta;
}
else /* (rgb_in.blue == max) */
{
hsv_out.hue = 4.0 + (rgb_in.red - rgb_in.green) / delta;
}

hsv_out.hue *= 60.0;

if (hsv_out.hue < 0.0)
hsv_out.hue += 360.0;
}

return (hsv_out);
}

May 19th, 1999, 02:32 PM
can you use getnearestcolor(COLORREF) ?