# How to make a hue distance histogram ?

Hi,

I would like to improve CamShift algorithm by using a Hue distance histogram. It consists to compute a hue reference Href which is the hue value which has the highest frequency in the histogram h(x) obtained from a region of interest at the step 1 of CAMShift. Then using this Href, we compute the distance like that: I know there is a method called CalcHist in Opencv to compute a histogram, but how i can handle with that ?

edit retag close merge delete

I am confused what the question is exactly, but what I have gathered you first want to get a histogram of the hue values. To do this convert the image from BGR to HSV and CalcHist of the first channel; this will be of the hue values.

I know how to make a histogram based on HUE or saturation value but here it's a histogram based on the distance...And i don't know how to do it

Distance of the hue is the same as an edge detection on the hue channel. If you don't want to use an edge detection you can apply the subtraction formula as you described above to the hue channel then take the histogram of the result.

Happy new year ! sorry i don't understand. When i do an histogram i don't use edge detection. Can you explain me again ? Thank you

Sort by » oldest newest most voted

The structure should be as follows: Load image -> convert to HSV -> implement the stated algorithm on the H channel -> calculate the histogram on the new image.

I have quickly put some code together to demonstrate how I would do this; I hope it is what you are after. I have only implemented the basic structure where you can go through and add/tweak what you need. This is only a guide, if you need anything explained in more detail feel free to ask.

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>

using namespace cv;

int main( int argc, char** argv )
{
Mat src = imread( argv );
if( !src.data )
{ return -1; }

Mat img_hsv;

//convert to HSV
cvtColor(img, img_hsv, CV_BGR2HSV);

//allocate memory for hue distance image
Mat distance_hue_img(img_hsv.rows, img_hsv.cols, CV_8UC1);

//implement hue distance calculation
uchar* distance_hue_img_ptr = distance_hue_img.data;
uchar* img_hsv_ptr = img_hsv.data;
//iterate through image
for(int y = 1; y < img_hsv.rows; ++y) for(int x = 1; x < img_hsv.cols; ++x)
{
/*----------------- below is just an example -----------------*/

//subtract bottom pixel from top pixel
int temp_value_y = abs(img_hsv_ptr[((y-1)*img_hsv.cols+3)+(x*3)+0] - img_hsv_ptr[((y+1)*img_hsv.cols+3)+(x*3)+0]);
//subtract right pixel from left pixel
int temp_value_x = abs(img_hsv_ptr[(y*img_hsv.cols+3)+((x-1)*3)+0] - img_hsv_ptr[(y*img_hsv.cols+3)+((x+1)*3)+0]);

//applying average of x and y, should probably use sqrt(x^2+y^2)
int temp_value = (temp_value_y+temp_value_x)/2;

//apply hue wrap around, opencv hue is between 0 to 179 but your algorithim was between 0 to 359
if(temp_value > 90)
distance_hue_img_ptr[(y*img_hsv.cols)+x] = 180-temp_value;
else
distance_hue_img_ptr[(y*img_hsv.cols)+x] = temp_value;
}

//get histogram of distance_hue_img
Mat histogram;
/*-----------------insert histogram code here-----------------*/

imshow("img", img);
imshow("hue_img", distance_hue_img);
imshow("histogram", histogram);

waitKey(0);

return 0;
}

more

Thank you so much for your answer ! Why do you use pointer ? Is not more simpler to so something like image.at<char>(x,y)? Actually i don't understand those lines

int temp_value_y = abs(img_hsv_ptr[((y-1)img_hsv.cols+3)+(x3)+0] - img_hsv_ptr[((y+1)img_hsv.cols+3)+(x3)+0]); //subtract right pixel from left pixel int temp_value_x = abs(img_hsv_ptr[(yimg_hsv.cols+3)+((x-1)3)+0] - img_hsv_ptr[(yimg_hsv.cols+3)+((x+1)3)+0]);

I suppose you apply the formula ?

But that's true i'm a bit destabilized with the way you do the calculation like : distance_hue_img_ptr[(y*img_hsv.cols)+x]

Thank again

I know how to use the pointers off the top of my head and unfortunately not any other way. It was my quick attempt at implementing the formula; the change in the hue channel over the x and y axis. Below is a brief example what the array notation is equivalent to in matrix notation. To get a pixel at position (x,y), below is how to get the value at y-1; the pixel above. For a 3 channel image [((y-1)img_hsv.cols+3)+(x3)+0] => [x][y-1] //x position, y position, channel For a 1 channel image [((y-1)*img_hsv.cols)+x] => [x][y-1] // x position, y position

If there is a better notation you like then use it and I am happy to help convert it to something you can understand.

Thank you for your answer ! Finally i was able to do some stuff but without pointer... I did only:

for (int i=0;i<hueChannel.rows;i++){
for (int j=0;j<hueChannel.cols;j++){

int val_hue_distance=computeHueDistance(hueChannel.at<uchar>(i,j),val_href);
hue_distance_mat.at<uchar>(i,j)=val_hue_distance;

}

retun hue_distance_mat


where ComputeHueDistance is the implementation of the formula which takes in parameters the huechannel image and the Href value i computed before...

It seems very simple in comparison with you, so i don't know if it makes senses what i did.

As long as the function computeHueDistance does what is required; what I wrote was only an example.

Official site

GitHub

Wiki

Documentation