float Histogram::compareHist(Histogram h2,int method=comparison_method::NORM_L1)
{

    Mat H1=this->getHist();
    Mat H2=h2.getHist();
    const Mat* arrays[] = {&H1, &H2, 0};

    //  H1.t()
//    cv::pyrDown()
    //planes,number of channels of histogram
    Mat planes[2];


    //N Dimensional array iterator
    NAryMatIterator it(arrays, planes);

    int len = it.planes[0].rows*it.planes[0].cols;
    float result=0;
    float a=0,b=0,s1=0,s2=0;
    float s11=0,s12=0,s22=0;
    //cerr << it.nplanes << endl;
    //cerr << it.planes[0].rows << ":" <<  it.planes[0].cols << endl;
    for( size_t i = 0; i < it.nplanes; i++, ++it )
    {
        const float* h1 = (const float*)it.planes[0].data;
        const float* h2 = (const float*)it.planes[1].data;


        if(method==comparison_method::NORM_L1)
        {
            for( int j = 0; j < len; j++ )
            {
                double a = abs(h1[j] - h2[j]);
                if( fabs(a) > DBL_EPSILON )
                    result += a;
            }
            result=result/len;
        }
        else if(method==comparison_method::NORM_L2)
        {
            for( int j = 0; j < len; j++ )
            {
                double a = (h1[j] - h2[j])*(h1[j] - h2[j]);
                if( fabs(a) > DBL_EPSILON )
                    result += a;
            }
            result=result/len;

        }
        else if(method == comparison_method::CHI_SQUARED)
        {
            for( int j = 0; j < len; j++ )
            {
                double a = h1[j] - h2[j];
                double b = h1[j];
                if( fabs(b) > DBL_EPSILON )
                    result += a*a/b;
            }

        }
        else if( method == comparison_method::INTERSECTION )
        {
            for( int  j = 0; j < len; j++ )
                result += std::min(h1[j], h2[j]);
        }
        else if( method == comparison_method::BHATTACHRYA || method == comparison_method::BHATTACHRYA1 )
        {
            for( int j = 0; j < len; j++ )
            {
                double a = h1[j];
                double b = h2[j];
                result += std::sqrt(a*b);
                s1 += a;
                s2 += b;
            }
            cerr << (float)s1 <<":" << (float)s2 << endl;



        }
        else if( method == comparison_method::CORRELATION )
        {
            for( int j = 0; j < len; j++ )
            {
                double a = h1[j];
                double b = h2[j];

                s12 += a*b;
                s1 += a;
                s11 += a*a;
                s2 += b;
                s22 += b*b;
            }

        }
        else
        {
            CV_Error( CV_StsBadArg, "Unknown comparison method" );
        }

    }

    if(method==comparison_method::CORRELATION)
    {
        s1=s1/len;
        s2=s2/len;

        size_t total = len;
        double scale = 1./total;
        double num = s12 -(total*s1*s2);
        double denom2 = (s11 - s1*s1*total)*(s22 - s2*s2*total);
        result = std::abs(denom2) > DBL_EPSILON ? num/std::sqrt(denom2) : 1.;

    }
    else if( method == comparison_method::BHATTACHRYA|| method == comparison_method::BHATTACHRYA1)
    {

        s1 *= s2;

        s1 = fabs(s1) > FLT_EPSILON ? 1./std::sqrt(s1) : 1.;
        if( method == comparison_method::BHATTACHRYA1)
            result=result*s1;
        else
            result = std::sqrt(std::max(1. - result*s1, 0.));

    }

    return result;
}