# How can I best compare two BGR colors to determine how similar/different they are?

I apologize for how basic this question is, please bear with me as I'm a beginner to OpenCV

Say I have two colors in BGR format (though I can convert them to another form if I have to - though an explanation on how to do so would be greatly appreciated) - how can I best quantify how similar/different these two colors are? Say, for example, I have a light green and a dark green - these are pretty similar. A light green and a yellow would also be similar, but a dark red and a light blue would be very different.

Is there any simple way to obtain a value that corresponds with the difference between two colors?

all help and advice is appreciated, thanks!

edit retag close merge delete

( 2017-02-21 05:07:12 -0600 )edit

Sort by » oldest newest most voted

The HSV color wheel can be used for color complementary, analogous such as color distance. The H channel from OpenCV BGR2HSV conversion is the Hue, in other words is the angle of the color on the color wheel. You might consider the difference between hues as colors distance without involve darkness or lightness.

Remember that

• hue is a angle over a circle than you have to get the shortest path between 2 hues (clockwise and counter-clockwise). For example hue=1° is RED, hue=120° is GREEN and hue=330° is ROSE. RED -> ROSE = 31° and RED -> GREEN = 119° !
• In OpenCV, 3x8bit images, the hue range 0..360deg is scaled down to 0..180 (or 0..255 if COLOR_BGR2HSV_FULL is used). Therefore GREEN is 60 (or 85 in case of _FULL conversion).

Using the conversion as @LBerger answer, this should check color distance between pt1 and pt2

Point pt1(x1,y1), p2(x2,y2);
Vec3b hsv1 = hsv.at<Vec3b>(p1); // get HSV values for the pixel. Hue is the 1st in the vector
Vec3b hsv2 = hsv.at<Vec3b>(p2);
d1 = abs(hsv1(0)-hsv2(0));  // absolute distance
d = min(d1,180-d1); // correct distance if cross 0deg . full circle at 180 because of Hue scaling

more

Hello @Hstuart!

If you are trying to detect some colored object from the image then all the previous answers that uses HSV Color Space is fine. But if you want to compute the Difference between two colors for Color Quality analysis to find Color metrics then the Answer is different.

First you have to convert your Color Space(CS) from device dependent CS to Device Independent CS. e.g CIE 1931 XYZ, CIELUV, CIELAB, CIEUVW.Unlike the Device dependent Color space like HSV, RGB, YUV,etc.. these DI CS are independent of the device/screen that you view.

There are some standards that are followed by International Color Consortium (ICC) for finding color metrics. Common definitions make use of the Euclidean distance in a device independent color space such as CIE Lab* Color Space.

These are the metrics used to represent the color differences.

Delta E 94

CIEDE2000

http://zschuessler.github.io/DeltaE/l...

http://www.color.org/index.xalter

http://www.imatest.com/2015/09/color-...

more

@Balaji R Thank you for your interesting answer! As know Lab color space also is device dependent where "device" is the human eye. Quoting zschuessler DE is meant How do you put a number to perceived difference in color ... I would add human eye sometime falls (shadow illusion)

@LBerger has the right answer First you have to choose color space because (Color Faq Par.26) colour difference refers to numerical differences between colour specifications.

Are luminance, saturation, shadow relevant ? reading light green and a dark green are pretty similar maybe yes maybe no.

( 2017-02-17 10:50:18 -0600 )edit
1

@pklab Thanks you for your comments! Quoting from the wiki! Due to the distribution of cones in the eye, the tristimulus values depend on the observer's field of view. To eliminate this variable, the CIE defined a color-mapping function called the standard (colorimetric) observer.

Also note that due to various environmental effects caused by lighting, shadows, humidity, etc... these Color values are computed in a Closed and in a controlled environment.

( 2017-02-18 00:41:27 -0600 )edit

First you have to choose color space

To convert an image from one color space to another. use cvtColor function

to get pixel color use :

Mat img=imread("lena.jpg",cv::IMREAD_COLOR);
cout<<img.at<Vec3b>(lig,col);
Mat hsv;
cvtColor(img,hsv,cv::COLOR_BGR2HSV);
cout<<hsv.at<Vec3b>(lig,col);


(result [111, 144, 230][8, 132, 230])

Similarity between colors will depend of context...

more