Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate distance between colors in HSV space

I intend to find a distance metric between two colours in HSV space.

Suppose that each colour element has 3 components: hue, saturation, and value. Hue is ranged between 0 to 360, saturation is ranged between 0 to 1, and value is ranged between 0 to 255.

Also hue has a circular property, for example, 359 in hue is closer to 0 in hue value than 10 in hue.

Can anyone provide a good metric to calculate the distance between 2 colour element in HSV space here?

like image 910
user1304846 Avatar asked Jan 31 '16 12:01

user1304846


People also ask

How do you find the distance between colors?

In order to measure the difference between two colors, the difference is assigned to a distance within the color space. In an equidistant-method color space, the color difference ∆E can be determined from the distance between the color places: ΔE = √ (L*₁-L*₂)² + (a*₁-a*₂)² + (b*₁-b*₂)².

What is HSV color scale?

1. HSV Color Scale: The HSV (which stands for Hue Saturation Value) scale provides a numerical readout of your image that corresponds to the color names contained therein. Hue is measured in degrees from 0 to 360. For instance, cyan falls between 181–240 degrees, and magenta falls between 301–360 degrees.

Is HSV a color space?

The HSV (Hue, Saturation, Value) model, also known as HSB (Hue, Saturation, Brightness), defines a color space in terms of three constituent components: Hue, the color type (such as red, blue, or yellow) ranges from \mathrm{0} – \mathrm{360} {}^{\circ} (but normalized to \mathrm{0} – \mathrm{100} %)

Why is HSV color space?

HSV is a cylindrical color model that remaps the RGB primary colors into dimensions that are easier for humans to understand. Like the Munsell Color System, these dimensions are hue, saturation, and value. Hue specifies the angle of the color on the RGB color circle.


1 Answers

First a short warning: Computing the distance of colors does not make sense (in most cases). Without considering the results of 50 years of research in Colorimetry, things like the CIECAM02 Color Space or perceptual linearity of distance measures, the result of such a distance measure will be counterintuitive. Colors that are "similar" according to your distance measure will appear "very different" to a viewer, and other colors, that have a large "distance" will be undistinguishable by viewers. However...


The actual question seems to aim mainly at the "Hue" part, which is a value between 0 and 360. And in fact, the values of 0 and 360 are the same - they both represent "red", as shown in this image:

Hue

Now, computing the difference of two of these values boils down to computing the distance of two points on a circle with a circumference of 360. You already know that the values are strictly in the range [0,360). If you did not know that, you would have to use the Floating-Point Modulo Operation to bring them into this range.

Then, you can compute the distance between these hue values, h0 and h1, as

hueDistance = min(abs(h1-h0), 360-abs(h1-h0));

Imagine this as painting both points on a circle, and picking the smaller "piece of the cake" that they describe - that is, the distance between them either in clockwise or in counterclockwise order.


EDIT Extended for the comment:

  • The "Hue" elements are in the range [0,360]. With the above formula, you can compute a distance between two hues. This distance is in the range [0,180]. Dividing the distance by 180.0 will result in a value in [0,1]

  • The "Saturation" elements are in the range [0,1]. The (absolute) difference between two saturations will also be in the range [0,1].

  • The "Value" elements are in the range [0,255]. The absolute difference between two values will thus be in the range [0,255] as well. Dividing this difference by 255.0 will result in a value in [0,1].

So imagine you have two HSV tuples. Call them (h0,s0,v0) and (h1,s1,v1). Then you can compute the distances as follows:

dh = min(abs(h1-h0), 360-abs(h1-h0)) / 180.0
ds = abs(s1-s0)
dv = abs(v1-v0) / 255.0

Each of these values will be in the range [0,1]. You can compute the length of this tuple:

distance = sqrt(dh*dh+ds*ds+dv*dv)

and this distance will be a metric for the HSV space.

like image 92
Marco13 Avatar answered Sep 29 '22 22:09

Marco13