Пример #1
0
double EnsembleTracker::compareHisto(Mat& frame, Rect win)
{
	Rect roi_win = win & Rect(0,0,frame.cols,frame.rows);
	Mat roi(frame,roi_win);
	Mat temp;
	Mat mask_win=Mat::zeros(roi.size(),CV_8UC1);
	ellipse(mask_win,Point((int)(0.5*mask_win.cols),(int)(0.5*mask_win.rows)),Size((int)(0.35*mask_win.cols),(int)(0.35*mask_win.rows)),0,0,360,Scalar(1),-1);
	calcHist(&roi,1,channels,Mat(),temp,3,histSize,hRange);
	normalize(temp,temp,1,0,NORM_L1);
	return compareHist(hist,temp,CV_COMP_INTERSECT);
}
Пример #2
0
double FeatureHOG::prob(FeatureHOG& feature) {
    double p = 1;
    double bc[3];
    
    for (int i = 0; i < 3; i++) {
        bc[i] = compareHist(h[i], feature.h[i], CV_COMP_BHATTACHARYYA);
        p *= exp(-1.0 * bc[i]);
    }
    
    
    return p;
}
Пример #3
0
double ColorMatch::compare(const Mat& target_image)
{
    target_hist_ = hist_.getHistogram(target_image);

    //to-do: allow different comparison methods:
    //       CV_COMP_CORRELL    - correlation
    //       CV_COMP_CHISQR     - chi-square
    //       CV_COMP_INTERSECT  - intersection
    //       CV_COMP_BHATTACHARYYA - Bhattacharyya distance
    //Official Documentaton:
    //  http://opencv.willowgarage.com/documentation/cpp/histograms.html#cv-comparehist
    return compareHist(reference_hist_, target_hist_, CV_COMP_CORREL);
}
double ImageAnalysis::HistogramCompare(IplImage* n, IplImage *p)
{
    //Сравнение гистограмм

     Mat nw(n);
     Mat pr(p);
     Mat hvs_nw,hvs_pr;

     /// Convert to HSV
     cvtColor( nw, hvs_nw, COLOR_BGR2HSV );
     cvtColor( pr, hvs_pr, COLOR_BGR2HSV );

     int h_bins = 50; int s_bins = 60;
     int histSize[] = { h_bins, s_bins };

     // hue varies from 0 to 179, saturation from 0 to 255
     float h_ranges[] = { 0, 180 };
     float s_ranges[] = { 0, 256 };

     const float* ranges[] = { h_ranges, s_ranges };

     // Use the o-th and 1-st channels
     int channels[] = { 0, 1 };

     MatND hist_nw;
     MatND hist_pr;

     /// Calculate the histograms for the HSV images
     calcHist( &hvs_nw, 1, channels, Mat(), hist_nw, 2, histSize, ranges, true, false );
     normalize( hist_nw, hist_nw, 0, 1, NORM_MINMAX, -1, Mat() );

     calcHist( &hvs_pr, 1, channels, Mat(), hist_pr, 2, histSize, ranges, true, false );
     normalize( hist_pr, hist_pr, 0, 1, NORM_MINMAX, -1, Mat() );

     double percent=compareHist( hist_nw, hist_pr, 0);//using Correlation method
     nw.release();
     pr.release();
     hist_nw.release();
     hist_pr.release();
     hvs_nw.release();
     hvs_pr.release();

     return percent;
}
ImageData* DiffSamplingFilter::filter(ImageData* image)
{
    if(prevImage == NULL)
    {
        prevImage = image;
        return image;
    }

    Mat prev;
    Mat current;

    cvtColor(prevImage->image, prev, COLOR_BGR2HSV);
    cvtColor(image->image, current, COLOR_BGR2HSV);

    int h_bins = 50;
    int s_bins = 60;
    int histSize[] = {h_bins, s_bins};

    float h_ranges[] = {0, 180};
    float s_ranges[] = {0, 256};

    const float* ranges[] = {h_ranges, s_ranges};

    int channels[] = {0, 1};

    MatND prevHist;
    MatND currentHist;

    calcHist(&prev, 1, channels, Mat(), prevHist, 2, histSize, ranges, true, false);
    normalize(prevHist, prevHist, 0, 1, NORM_MINMAX, -1, Mat());

    calcHist(&current, 1, channels, Mat(), currentHist, 2, histSize, ranges, true, false);
    normalize(prevHist, prevHist, 0, 1, NORM_MINMAX, -1, Mat());

    double comparisonValue = compareHist(prevHist, currentHist, CV_COMP_BHATTACHARYYA);
    prevImage = image;

    if (comparisonValue > thresholdValue)
    {
        return image;
    }

    return NULL;
}
Пример #6
0
double HistogramSimilarityCalculator::calculate(Mat a, Mat b)
{
    MatND hista, histb;
    Mat a_hsv, b_hsv;

    int histsize[] = { 64, 64 };
    int channels[] = { 0, 1 };
    float hrange[] = { 0, 180 };
    float srange[] = { 0, 255 };
    const float *ranges[] = { hrange, srange };

    cvtColor(a, a_hsv, CV_BGR2HSV);
    cvtColor(b, b_hsv, CV_BGR2HSV);

    calcHist(&a_hsv, 1, channels, Mat(), hista, 2, histsize, ranges, true, false);
    calcHist(&b_hsv, 1, channels, Mat(), histb, 2, histsize, ranges, true, false);
    double similarity = compareHist(hista, histb, CV_COMP_INTERSECT) /((a.rows-1) * (a.cols-1));
    return similarity;
}
Пример #7
0
double SameClassSemblanceVariance(int ClassNumber,int SampleNumber[],Mat SameClassHistogram[][10],double mean)
{
	double Variance = 0.0;
	for (int i=0;i<ClassNumber;i++)
	{
		double sum = 0.0;
		for (int k=1;k<SampleNumber[i];k++)
		{
			for (int j=0;j<k-1;j++)
			{
				double dis = compareHist(SameClassHistogram[i][j],SameClassHistogram[i][k],CV_COMP_CHISQR);
				double cha = dis - mean;
				double temp = cha*cha;
				sum += temp;
			}
		}	
		Variance += sum;
	}
	return Variance;
}
Пример #8
0
double SameClassMean(int ClassNumber,int SampleNumber[],Mat SameClassHistogram[][10])
{
	double mean = 0.0;
	double C_sum = 0.0;
	for (int i=0;i<ClassNumber;i++)
	{
		double sum = 0.0;
		for (int k=1;k<SampleNumber[i];k++)
		{
			for (int j=0;j<k-1;j++)
			{
				double dis = compareHist(SameClassHistogram[i][j],SameClassHistogram[i][k],CV_COMP_CHISQR);
				sum+=dis;
			}
		}	
		double temp = (2*sum)/(SampleNumber[i]*(SampleNumber[i]-1));
		C_sum+=temp;
	}
	mean = C_sum/ClassNumber;
	return mean;
}
Пример #9
0
/*
inputImage	input image as used by doSomethingThatMyTutorIsGonnaLike()
outputImage	output image as created by doSomethingThatMyTutorIsGonnaLike()
*/
void Dip1::test_doSomethingThatMyTutorIsGonnaLike(Mat& inputImage, Mat& outputImage){

	// ensure that input and output have equal number of channels
	if ( (inputImage.channels() == 3) && (outputImage.channels() == 1) )
		cvtColor(inputImage, inputImage, CV_BGR2GRAY);

	// split (multi-channel) image into planes
	vector<Mat> inputPlanes, outputPlanes;
	split( inputImage, inputPlanes );
	split( outputImage, outputPlanes );

	// number of planes (1=grayscale, 3=color)
	int numOfPlanes = inputPlanes.size();

	// calculate and compare image histograms for each plane
	Mat inputHist, outputHist;
	// number of bins
	int histSize = 100;
	float range[] = { 0, 256 } ;
	const float* histRange = { range };
	bool uniform = true; bool accumulate = false;
	double sim = 0;
	for(int p = 0; p < numOfPlanes; p++){
		// calculate histogram
		calcHist( &inputPlanes[p], 1, 0, Mat(), inputHist, 1, &histSize, &histRange, uniform, accumulate );
		calcHist( &outputPlanes[p], 1, 0, Mat(), outputHist, 1, &histSize, &histRange, uniform, accumulate );
		// normalize
		inputHist = inputHist / sum(inputHist).val[0];
		outputHist = outputHist / sum(outputHist).val[0];
		// similarity as histogram intersection
		sim += compareHist(inputHist, outputHist, CV_COMP_INTERSECT);
	}
	sim /= numOfPlanes;

	// check whether images are to similar after transformation
	if (sim >= 0.8)
		cout << "The input and output image seem to be quite similar (similarity = " << sim << " ). Are you sure your tutor is gonna like your work?" << endl;

}
Пример #10
0
void LBPH::predict(InputArray _src, Ptr<PredictCollector> collector) const {
    if(_histograms.empty()) {
        // throw error if no data (or simply return -1?)
        String error_message = "This LBPH model is not computed yet. Did you call the train method?";
        CV_Error(Error::StsBadArg, error_message);
    }
    Mat src = _src.getMat();
    // get the spatial histogram from input image
    Mat lbp_image = elbp(src, _radius, _neighbors);
    Mat query = spatial_histogram(
            lbp_image, /* lbp_image */
            static_cast<int>(std::pow(2.0, static_cast<double>(_neighbors))), /* number of possible patterns */
            _grid_x, /* grid size x */
            _grid_y, /* grid size y */
            true /* normed histograms */);
    // find 1-nearest neighbor
    collector->init((int)_histograms.size());
    for (size_t sampleIdx = 0; sampleIdx < _histograms.size(); sampleIdx++) {
        double dist = compareHist(_histograms[sampleIdx], query, HISTCMP_CHISQR_ALT);
        int label = _labels.at<int>((int)sampleIdx);
        if (!collector->collect(label, dist))return;
    }
}
Пример #11
0
//Cập nhật hist
void EnsembleTracker::updateMatchHist(Mat& frame)
{
	Rect roi_result=getResult();
	Rect roi_result_bodysize = scaleWin(roi_result,1/TRACKING_TO_BODYSIZE_RATIO);
	Rect win = roi_result_bodysize & Rect(0,0,frame.cols,frame.rows);
	Mat roi(frame,win);
	Mat temp;
	Mat mask_win = Mat::zeros(roi.size(),CV_8UC1);
	ellipse(mask_win,Point((int)(0.5*mask_win.cols),(int)(0.5*mask_win.rows)),Size((int)(0.35*mask_win.cols),(int)(0.35*mask_win.rows)),0,0,360,Scalar(1),-1);
	calcHist(&roi,1,channels,mask_win,temp,3,histSize,hRange);
	normalize(temp,temp,1,0,NORM_L1);

	if (_result_history.size()==1)//Nếu là tracker mới
	{
		hist_match_score=1;
		hist=temp;
		return;
	}

	hist_match_score = compareHist(hist,temp,CV_COMP_INTERSECT);
	hist += HIST_MATCH_UPDATE*temp;
	normalize(hist,hist,1,0,NORM_L1);
}
Пример #12
0
    void clusterHistograms(const std::vector<Mat> &hists, std::vector<cluster_t> &clusters, const cluster_vars &vars) {

        // calculate hist distances
        Mat dists = Mat::zeros((int)hists.size(), (int)hists.size(), CV_64FC1);
        tbb::parallel_for(0, (int)hists.size()-1, 1, 
            [&hists, &dists](int i) {
                tbb::parallel_for(i, (int)hists.size(), 1, 
                    [&hists, &dists, &i](int j) {
                        double dist = compareHist(hists.at(i), hists.at(j), COMP_ALG);
                        dists.at<double>(i, j) = dist;
                        dists.at<double>(j, i) = dist;
                    } 
                );
            } 
        );
        
        // find optimal clusters
        std::vector<idx_cluster_t> idxClusters;
        find_optimal_clustering(dists, idxClusters, vars);

        // calculate the cluster average for each cluster
        for(size_t i = 0; i < idxClusters.size(); i++) {
            idx_cluster_t cluster = idxClusters.at((int)i);
            
            std::vector<Mat> clusterHists;
            Mat clusterAvg;
            
            for(size_t i = 0; i < cluster.size(); i++) {
            //for(idx_cluster_t::const_iterator it = cluster.begin(); it != cluster.end(); it++) {
                clusterHists.push_back(hists.at(cluster.at(i)));
            }
            
            averageHistograms(clusterHists, clusterAvg);

            clusters.push_back(cluster_t(clusterAvg, cluster));
        }
    }
Пример #13
0
double DistinctClassMean(int ClassNumber,int SampleNumber[],Mat SameClassHistogram[][10])
{
	double mean = 0.0;
	double C_sum = 0.0;
	for (int i=0;i<ClassNumber-1;i++)
	{
		for (int j=i+1;j<ClassNumber;j++)
		{
			double sum = 0.0;
			for (int k=0;k<SampleNumber[i];k++)
			{
				for (int l=0;l<SampleNumber[j];k++)
				{
					double dis = compareHist(SameClassHistogram[i][k],SameClassHistogram[j][l],CV_COMP_CHISQR);
					sum+= dis;
				}
			}
			double temp = sum/(SampleNumber[i]*SampleNumber[j]);
			C_sum+= temp;
		}
	}
	mean = (C_sum*2)/(ClassNumber*(ClassNumber-1));
	return mean;
}
Пример #14
0
void ParticleFilter::measurement(Mat_<double>& particles, Rect detection_new, Mat HSVinterpolated,vector<Mat>& MultiHSVInterpolated, Mat& image, int use_hist, int frame){
//! Measurement step of particle filter
/*!
*/
	int x;
    int y;
    
    if (rely_detection) { // when no occlusion
        x = (int)(detection_new.x + detection_new.width/2);
        y = (int)(detection_new.y + detection_new.height/2);
    }
    else{	// when there is an occlusion
		x = PFTrack.x + PFTrackVel.x;
		y = PFTrack.y + PFTrackVel.y;
    }
     //detection term
    double w_det;
    vector<double> w_detm_temp(numParticles,0.0);
    vector<double> w_detm(numParticles,0.0);
    double w_sum = 0.0;
    for (unsigned int index = 0; index < numParticles; index++) {
        double x_term = pow(double(particles_new[index][X_POS]-x), 2)/(2*pow(sigma_measurement,2));
        double y_term = pow(double(particles_new[index][Y_POS]-y), 2)/(2*pow(sigma_measurement,2));
        w_det = (1/sqrt(2*PI*pow(sigma_measurement,2)))*exp(-1*(x_term+y_term));
        w_det = w_det + 1e-99;
        //        w_sum += w_det;
        
        w_detm_temp[index]=w_det;
    }
    
    // normalize weight
    for (unsigned int index = 0; index < numParticles; index++) {
        w_sum += w_detm_temp[index];
    }
    for (unsigned int index = 0; index < numParticles; index++) {
        w_detm[index] = w_detm_temp[index]/w_sum;
    }

    
    //appearance term
    double w_col;
    w_sum = 0.0;
    vector<double> w_colm(numParticles,0.0);
    vector<double> w_colm_temp(numParticles,0.0);
    Mat ibox;
    for (unsigned int index = 0; index < numParticles; index++) {
        
    	// get the bounding box size
        int xcbox = particles_new[index][X_POS]-(int)(width_tracker/2);
        int ycbox = particles_new[index][Y_POS]-(int)(height_tracker/2);
        Rect cbox(xcbox,ycbox,width_tracker,height_tracker);
        
        if(use_hist==1) { // only take one regions
            
            if ((cbox.x < 0) || (cbox.x+cbox.width > image.cols) || (cbox.y < 0) || (cbox.y+cbox.height > image.rows) )
            {
               w_col = 0.0000001;
            }
            else
            {
               Mat HSVCalc;
               ibox = image(cbox);
               computeHSVHist(ibox, HSVCalc);
               w_col = compareHist(HSVinterpolated, HSVCalc, CV_COMP_CORREL);
               HSVCalc.release();
                
            }
            w_sum += w_col;
            w_colm_temp.push_back(w_col);
        }
        else if (use_hist==2){ // only take three regions
            
            if ((cbox.x < 0) || (cbox.x+cbox.width > image.cols) || (cbox.y < 0) || (cbox.y+cbox.height > image.rows) )
            {
                w_col = 0.0000001;
            }
            else{
                vector<Mat> HSVCalc;
                ibox = image(cbox);
                vector<Mat> MultiIMHSV;
                Mat tempHSV;
                int third = ibox.rows/3;
                tempHSV = ibox.rowRange(0, third);
                MultiIMHSV.push_back(tempHSV);
                tempHSV = ibox.rowRange(third,third+third);
                MultiIMHSV.push_back(tempHSV);
                tempHSV = ibox.rowRange(third+third, ibox.rows);
                MultiIMHSV.push_back(tempHSV);
                
                for (unsigned int hs = 0; hs < MultiHSVTemplate.size(); hs++) {
                    Mat HSTemp;
                    computeHSVHist(MultiIMHSV[hs], HSTemp);
                    HSVCalc.push_back(HSTemp);
                }
                w_col = 0.0;
                for (unsigned int hs = 0; hs < MultiHSVTemplate.size(); hs++) {
                    int wtemp = compareHist(MultiHSVInterpolated[hs], HSVCalc[hs], CV_COMP_INTERSECT);
                   w_col += wtemp;
                }
           }
            w_sum += w_col;
            w_colm_temp.push_back(w_col);
        }
        else if(use_hist == 3){	// divide into three regions and overlap
            // if out of image bound
            if ((cbox.x < 0) || (cbox.x+cbox.width > image.cols) || (cbox.y < 0) || (cbox.y+cbox.height > image.rows) )
            {
                w_col = 0.0000001;
            }
            else{
                vector<Mat> HSVCalc(3);
                ibox = image(cbox);
                vector<Mat> MultiIMHSV(3);

                int third = ibox.rows/3;
                int half = ibox.rows/2;
                // Partition step
                MultiIMHSV.at(0) = ibox.rowRange(0, half);
                MultiIMHSV.at(1) = ibox.rowRange(third,half+third);
                MultiIMHSV.at(2) = ibox.rowRange(half, ibox.rows);
                // Calculate histogran for every region
                Mat HSTemp;
                for (unsigned int hs = 0; hs < MultiHSVTemplate.size(); hs++) {
                    computeHSVHist(MultiIMHSV[hs], HSTemp);
                    normalize(HSTemp, HSTemp, 0, HSTemp.rows, NORM_MINMAX, -1, Mat() );
                    HSVCalc.at(hs) = HSTemp;
                }
                // calculate the weight by comparing them
                w_col = 0.0;
                for (unsigned int hs = 0; hs < MultiHSVTemplate.size(); hs++) {

                    double wtemp = compareHist(MultiHSVInterpolated[hs], HSVCalc[hs], CV_COMP_BHATTACHARYYA);

                    wtemp = 1.0 - wtemp;
                    w_col += wtemp;
                    w_col /= (int)(MultiHSVTemplate.size());
                }
            }

            w_sum += w_col;
            w_colm_temp.at(index) = w_col;
        }
        else if(use_hist==4){
            
        }
        else{
            w_colm_temp.push_back(0.0);
            w_sum = 1.0;
        }
        
    }
    
    if (!rely_detection) { //dont rely on detection if there is an occlusion
        c_det = m_c_det;
        c_col = m_c_col;
    }
    // normalize weight
    for (unsigned int index = 0; index < numParticles; index++) {

        w_colm.at(index) = w_colm_temp.at(index)/w_sum; //diubah
    }
    //accumulate
    for (unsigned int index = 0; index < numParticles; index++) {
        w_det = w_detm.at(index) * c_det;
        w_detm.at(index) = w_det;
    }
    
    for (unsigned int index = 0; index < numParticles; index++) {
          w_col = w_colm.at(index) * c_col;
        w_colm.at(index) = w_col;

    }
    // total weight
    for (unsigned int index = 0; index < numParticles; index++) {
        weight.at(index) = w_detm.at(index) + w_colm.at(index);
    }
}
Пример #15
0
// pair selection algorithm from a set of training images and corresponding keypoints
std::vector<int> FREAK::selectPairs(const std::vector<Mat>& images
                                        , std::vector<std::vector<KeyPoint> >& keypoints
                                        , const double corrTresh
                                        , bool verbose )
{
    extAll = true;
    // compute descriptors with all pairs
    Mat descriptors;

    if( verbose )
        std::cout << "Number of images: " << images.size() << std::endl;

    for( size_t i = 0;i < images.size(); ++i )
    {
        Mat descriptorsTmp;
        computeImpl(images[i],keypoints[i],descriptorsTmp);
        descriptors.push_back(descriptorsTmp);
    }

    if( verbose )
        std::cout << "number of keypoints: " << descriptors.rows << std::endl;

    //descriptor in floating point format (each bit is a float)
    Mat descriptorsFloat = Mat::zeros(descriptors.rows, 903, CV_32F);

    std::bitset<1024>* ptr = (std::bitset<1024>*) (descriptors.data+(descriptors.rows-1)*descriptors.step[0]);
    for( int m = descriptors.rows; m--; )
    {
        for( int n = 903; n--; )
        {
            if( ptr->test(n) == true )
                descriptorsFloat.at<float>(m,n)=1.0f;
        }
        --ptr;
    }

    std::vector<PairStat> pairStat;
    for( int n = 903; n--; )
    {
        // the higher the variance, the better --> mean = 0.5
        PairStat tmp = { fabs( mean(descriptorsFloat.col(n))[0]-0.5 ) ,n};
        pairStat.push_back(tmp);
    }

    std::sort( pairStat.begin(),pairStat.end(), sortMean() );

    std::vector<PairStat> bestPairs;
    for( int m = 0; m < 903; ++m )
    {
        if( verbose )
            std::cout << m << ":" << bestPairs.size() << " " << std::flush;
        double corrMax(0);

        for( size_t n = 0; n < bestPairs.size(); ++n )
        {
            int idxA = bestPairs[n].idx;
            int idxB = pairStat[m].idx;
            double corr(0);
            // compute correlation between 2 pairs
            corr = fabs(compareHist(descriptorsFloat.col(idxA), descriptorsFloat.col(idxB), HISTCMP_CORREL));

            if( corr > corrMax )
            {
                corrMax = corr;
                if( corrMax >= corrTresh )
                    break;
            }
        }

        if( corrMax < corrTresh/*0.7*/ )
            bestPairs.push_back(pairStat[m]);

        if( bestPairs.size() >= 512 )
        {
            if( verbose )
                std::cout << m << std::endl;
            break;
        }
    }

    std::vector<int> idxBestPairs;
    if( (int)bestPairs.size() >= FREAK_NB_PAIRS )
    {
        for( int i = 0; i < FREAK_NB_PAIRS; ++i )
            idxBestPairs.push_back(bestPairs[i].idx);
    }
    else
    {
        if( verbose )
            std::cout << "correlation threshold too small (restrictive)" << std::endl;
        CV_Error(Error::StsError, "correlation threshold too small (restrictive)");
    }
    extAll = false;
    return idxBestPairs;
}
Пример #16
0
//Perform statistical comparison 
int IMCSEngine::compare(const char* image_file2, 
						double&		result,
						int&		result_type,
						int&		message_len,
						char*		message) {


	//Check if prepared successfully 
	if (im_prepared == false) {
		message_len = snprintf(message, message_len, "Invalid prepared state: %d", im_prepared);
		return ST_INVALID_PARAMETERS;	
	}


	//Read image file data
	image2 = imread(image_file2, CV_LOAD_IMAGE_COLOR);
	if (image2.empty() == true || image2.channels() != 3) {
		message_len = snprintf(message, message_len, "Invalid image file: %s", image_file2);
		return ST_INVALID_IMAGE;
	}


	//Reduce image colors
	if (im_reduce_factor >= RF_MIN) {
		colorReduce(image2, im_reduce_factor);
	}
	

	//Create image histogram 
	calcHistBGR(image2, image_histo2, im_dim_size);


	#ifdef IMCS_DEBUG_TIMES
	double tStart = getTimingStart();													//Start timing
	#endif

	double identity = 0.0;																//Used only in IM_COMP_INTERSECT

	switch (im_compare_method){
		case COMP_CORREL:
			result = compareHist(image_histo1, image_histo2, CV_COMP_CORREL);			//Comparison result (1 is perfect)
			result = (result > 0) ? result : 0;											//Eliminate negative values
			result_type = RES_TYPE_PERCENT;
			break;

		case COMP_CHISQR:
			result = compareHist(image_histo1, image_histo2, CV_COMP_CHISQR);			//Comparison result (0 is perfect)
			result_type = RES_TYPE_VALUE;
			break;

		case COMP_INTERSECT:
			identity = compareHist(image_histo1, image_histo1, CV_COMP_INTERSECT);		//Calculate "identity" value for image1 histogram
			result = compareHist(image_histo1, image_histo2, CV_COMP_INTERSECT);		//Comparison result (higher score is better match)
			result = (result / identity);												//Express as identity fraction
			result_type = RES_TYPE_PERCENT;
			break;

		case COMP_BHATTACHARYYA:
			result = compareHist(image_histo1, image_histo2, CV_COMP_BHATTACHARYYA);	//Comparison result (0 is perfect match)
			result = (1.0 - result);													//Invert scale (1 is perfect)										 
			result_type = RES_TYPE_PERCENT;
			break;

		case COMP_EMD_L1:
			calcEMDSig(image_histo2, emd_sig2, im_dim_size);
			result = EMD(emd_sig1, emd_sig2, CV_DIST_L1);								//Calculate distance (0 is perfect match)
			result_type = RES_TYPE_VALUE;
			break;

		case COMP_EMD_L2:
			calcEMDSig(image_histo2, emd_sig2, im_dim_size);
			result = EMD(emd_sig1, emd_sig2, CV_DIST_L2);								//Calculate distance (0 is perfect match)
			result_type = RES_TYPE_VALUE;
			break;
	}


	#ifdef IMCS_DEBUG_TIMES
	double tElapsed = getTimingResult(tStart);											//Get timing result
	printf("image_compare_stat() exec time: %fms\n", tElapsed);							//Display timing results
	#endif


	//Info message on success
	if (result_type == RES_TYPE_PERCENT) {
		message_len = snprintf(message, message_len, "Result: %f%% for compare method: %d", (result * 100), im_compare_method);
	} else {
		message_len = snprintf(message, message_len, "Result: %f for compare method: %d", result, im_compare_method);
	}

	//Success
	return ST_OK;
}