I'm a newbie on using OpenCV and i urgently need help about an application that i'm doing.
I'm working with a CBIR(Content-based Image Retrieval) project which will draw RGB histogram of images and also calculate the distance between other images with query image.
I'm using VS 2008 - MFC and OpenCV Library. The method i wanted to use for calculating the distance is Euclidean Distance(ED), but somehow i failed to work it out.
I found a function - cvCalcEMD2() that can help me calculate the distance between two histogram. To use this function, i need to create signature for my histogram.
Here is an example for creating signature that i found in Learning OpenCv:
CvMat* sig1,sig2;
int numrows = h_bins*s_bins;
sig1 = cvCreateMat(numrows, 3, CV_32FC1);
sig2 = cvCreateMat(numrows, 3, CV_32FC1);
for( int h = 0; h < h_bins; h++ ) {
for( int s = 0; s < s_bins; s++ ) {
float bin_val = cvQueryHistValue_2D( hist1, h, s );
cvSet2D(sig1,h*s_bins + s,0,cvScalar(bin_val));
cvSet2D(sig1,h*s_bins + s,1,cvScalar(h));
cvSet2D(sig1,h*s_bins + s,2,cvScalar(s));
bin_val = cvQueryHistValue_2D( hist2, h, s );
cvSet2D(sig2,h*s_bins + s,0,cvScalar(bin_val));
cvSet2D(sig2,h*s_bins + s,1,cvScalar(h));
cvSet2D(sig2,h*s_bins + s,2,cvScalar(s));
}
}
and also
the link to a page that with an example on calc HSV histogram and create signature using it. (It is exactly the same with the code above but with the code where she create histogram)
in the For loop, there is a line where i need to pass in my histogram:
float bin_val = cvQueryHistValue_2D( hist1, h, s );
and in my function for histogram don't have something like the variable h_bins and s_bins
In my program, i calculate/draw my histogram into R, G and B. means, each image i've 3 histogram. eg: CvHistogram *hist_red, *hist_green, *hist_blue;
the function that i used to draw histogram:
void CMy04Dlg::CalcHistogram(IplImage* img)
{
IplImage* channel = cvCreateImage( cvGetSize(img), 8, 1 );
IplImage *hist_img = cvCreateImage(cvSize(100,100), 8, 3);
cvSet( hist_img, cvScalarAll(255), 0 );
CvHistogram *hist_red;
CvHistogram *hist_green;
CvHistogram *hist_blue;
int hist_size = 256;
float range[]={0,256};
float* ranges[] = { range };
float max_value = 0.0;
float max = 0.0;
float w_scale = 0.0;
hist_red = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);
hist_green = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);
hist_blue = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);
cvSetImageCOI(img,3);
cvCopy(img,channel);
cvResetImageROI(img);
cvCalcHist( &channel, hist_red, 0, NULL );
cvSetImageCOI(img,2);
cvCopy(img,channel);
cvResetImageROI(img);
cvCalcHist( &channel, hist_green, 0, NULL );
cvSetImageCOI(img,1);
cvCopy(img,channel);
cvResetImageROI(img);
cvCalcHist( &channel, hist_blue, 0, NULL );
cvGetMinMaxHistValue( hist_red, 0, &max_value, 0, 0 );
cvGetMinMaxHistValue( hist_green, 0, &max, 0, 0 );
max_value = (max > max_value) ? max : max_value;
cvGetMinMaxHistValue( hist_blue, 0, &max, 0, 0 );
max_value = (max > max_value) ? max : max_value;
cvScale( hist_red->bins, hist_red->bins, ((float)hist_img->height)/max_value, 0 );
cvScale( hist_green->bins, hist_green->bins, ((float)hist_img->height)/max_value, 0 );
cvScale( hist_blue->bins, hist_blue->bins, ((float)hist_img->height)/max_value, 0 );
w_scale = ((float)hist_img->width)/hist_size;
for( int i = 0; i < hist_size; i++ )
{
cvRectangle( hist_img, cvPoint((int)i*w_scale , hist_img->height),cvPoint((int)(i+1)*w_scale, hist_img->height - cvRound(cvGetReal1D(hist_red->bins,i))),CV_RGB(255,0,0), -1, 8, 0 );
cvRectangle( hist_img, cvPoint((int)i*w_scale , hist_img->height),cvPoint((int)(i+1)*w_scale, hist_img->height - cvRound(cvGetReal1D(hist_green->bins,i))),CV_RGB(0,255,0), -1, 8, 0 );
cvRectangle( hist_img, cvPoint((int)i*w_scale , hist_img->height),cvPoint((int)(i+1)*w_scale, hist_img->height - cvRound(cvGetReal1D(hist_blue->bins,i))),CV_RGB(0,0,255), -1, 8, 0 );
}
ShowImage( hist_img, IDC_IHist );
cvSaveImage("myoutput.jpg",hist_img);
}
How do i use my histogram to create signature?
anyone can help me?