Computing the distance between two color vectors

To compute the distance between two color vectors, we used the following simple formula:

return abs(color[0]-target[0])+ 
       abs(color[1]-target[1])+ 
       abs(color[2]-target[2]);

However, OpenCV includes a function to compute the Euclidean norm of a vector. Consequently, we could have computed our distance as follows:

return static_cast<int>( 
   cv::norm<int,3>(cv::Vec3i(color[0]-target[0], 
                             color[1]-target[1], 
                             color[2]-target[2]))); 

A very similar result would then be obtained, using this definition of the getDistance method. Here, we use cv::Vec3i (a three-vector array of integers), because the result of the subtraction is an integer value.

It is also interesting to recall from Chapter 2, Manipulating the Pixels, that the OpenCV matrix and vector data structures include a definition of the basic arithmetic operators. Consequently, one could have proposed the following definition for distance computation:

return static_cast<int>( 
   cv::norm<uchar,3>(color-target)); // wrong! 

This definition may look right at first glance; however, it is wrong. This is because all these operators always include a call to saturate_cast (see the Scanning an image with neighbor access recipe in Chapter 2, Manipulating the Pixels) in order to ensure that the results stay within the domain of the input type (here, it is uchar). Therefore, in the cases where the target value is greater than the corresponding color value, the value 0 will be assigned instead of the negative value that one would have expected. A correct formulation would then be as follows:

   cv::Vec3b dist; 
   cv::absdiff(color,target,dist); 
   return cv::sum(dist)[0]; 

However, using two function calls to compute the distance between two three-vector arrays is inefficient.