0
$\begingroup$

I want to look for a better way to calculate the distance between two pixels in the HSV color space. In my program I used Euclidean distance. $$ distance(p_1, p_2) = \sqrt{(h_1 - h_2)^2 + (s_1 - s_2)^2 +(v_1 - v_2)^2} $$ $where \,\, h_1, h_2, s_1, s_2, v_1, v_2 \,\, are\,\, the\,\, components\,\, of\,\, the\,\, two\,\, pixels\,\, p_1\,\, and \,\,p_2 \,\,from\,\, HSV\,\, color \,\,space. \quad p_1 = (h_1, s_1, v_1)\,\, p_2 =(h_2, s_2,v_2) $

Using Euclidean distance is not a good approach because the hue value is expressed in degrees, $ hue \in [0^{\circ}, 360 ^{\circ}]$. How can I calculate this distance in another way? My proposal is to use polar coordinates to calculate the distance between two HSV pixels. But I don't know how to express hue, saturation, value in cylindrical space. I think that the x axis is saturation, the value represents the y-axis and $\theta$ is represented by hue value in degrees.

enter image description here

$\endgroup$
0
$\begingroup$

You can use $$\left\lbrace \begin{aligned} x &= s \cos h \\ y &= s \sin h \\ z &= v \end{aligned} \right.$$ with $$d(x_1, y_1, z_1, x_2, y_2, z_2) = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2 + (z_2 - z_1)^2}$$ and therefore, after simplification, $$d(h_1, s_1, v_1, h_2, s_2, v_2) = \sqrt{(v_2 - v_1)^2 + s_1^2 + s_2^2 - 2 s_1 s_2 \cos(h_2 - h_1)} \tag{Cylinder}\label{Cylinder}$$


This cylinder model has the problem that it does not take into account that all hues and saturations at (or very near) zero value are black. The HSV cone (or hexagonal pyramid) described in the Wikipedia HSL and HSV article might work better. Instead of saturation, we use chroma ($C = S V$) instead of the saturation for the radius: $$\left\lbrace \begin{aligned} x &= s v \cos h \\ y &= s v \sin h \\ z &= v \\ \end{aligned} \right .$$ giving a distance function of $$d(h_1, s_1, v_1, h_2, s_2, v_2) = \sqrt{ (v_2 - v_1)^2 + s_1^2 v_1^2 + s_2^2 v_2^2 - 2 s_1 s_2 v_1 v_2 \cos(h_2 - h_1) } \tag{Cone}\label{Cone}$$


Do note that all above assumes $h$ has the same range as your $\sin$ and $\cos$ functions; typically radians. If your $\cos$ function takes radians, and $h_1$ and $h_2$ are in degrees, use cos((h2 - h1)*M_PI/180.0; if your $\cos$ function takes radians, and $h_1$ and $h_2$ are within $[0, 1]$ or $[-0.5, +0.5]$, use cos((h2 - h1)*M_PI); and if your $\cos$ functon takes radians, and $h_1$ and $h_2$ are within $[0, 255]$ or $[-128, 127]$, then use cos((h2 - h1)*M_PI/128.0.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.