fixed chi-square test, ticket #1263
authorVadim Pisarevsky <no@email>
Mon, 26 Mar 2012 09:07:02 +0000 (09:07 +0000)
committerVadim Pisarevsky <no@email>
Mon, 26 Mar 2012 09:07:02 +0000 (09:07 +0000)
doc/tutorials/imgproc/histograms/histogram_comparison/histogram_comparison.rst
modules/imgproc/doc/histograms.rst
modules/imgproc/src/histogram.cpp
modules/imgproc/test/test_histograms.cpp

index 5fd4495..7844d0e 100644 (file)
@@ -45,7 +45,7 @@ Theory
     
         .. math::
     
-           d(H_1,H_2) =  \sum _I  \frac{\left(H_1(I)-H_2(I)\right)^2}{H_1(I)+H_2(I)
+           d(H_1,H_2) =  \sum _I  \frac{\left(H_1(I)-H_2(I)\right)^2}{H_1(I)} 
      
     
      c. **Intersection ( method=CV\_COMP\_INTERSECT )**
index 43769ea..0d4fa36 100644 (file)
@@ -196,7 +196,7 @@ The functions ``compareHist`` compare two dense or two sparse histograms using t
 
     .. math::
 
-        d(H_1,H_2) =  \sum _I  \frac{\left(H_1(I)-H_2(I)\right)^2}{H_1(I)+H_2(I)}
+        d(H_1,H_2) =  \sum _I  \frac{\left(H_1(I)-H_2(I)\right)^2}{H_1(I)}
 
 * Intersection (method=CV\_COMP\_INTERSECT)
 
index 8d1dd6f..960a26f 100644 (file)
@@ -1401,8 +1401,8 @@ double cv::compareHist( InputArray _H1, InputArray _H2, int method )
             for( j = 0; j < len; j++ )
             {
                 double a = h1[j] - h2[j];
-                double b = h1[j] + h2[j];
-                if( fabs(b) > FLT_EPSILON )
+                double b = h1[j];
+                if( fabs(b) > DBL_EPSILON )
                     result += a*a/b;
             }
         }
@@ -1469,7 +1469,7 @@ double cv::compareHist( const SparseMat& H1, const SparseMat& H2, int method )
         CV_Assert( H1.size(i) == H2.size(i) );
     
     const SparseMat *PH1 = &H1, *PH2 = &H2;
-    if( PH1->nzcount() > PH2->nzcount() )
+    if( PH1->nzcount() > PH2->nzcount() && method != CV_COMP_CHISQR )
         std::swap(PH1, PH2);
     
     SparseMatConstIterator it = PH1->begin();
@@ -1482,24 +1482,10 @@ double cv::compareHist( const SparseMat& H1, const SparseMat& H2, int method )
             float v1 = it.value<float>();
             const SparseMat::Node* node = it.node();
             float v2 = PH2->value<float>(node->idx, (size_t*)&node->hashval);
-            if( !v2 )
-                result += v1;
-            else
-            {
-                double a = v1 - v2;
-                double b = v1 + v2;
-                if( b > FLT_EPSILON )
-                    result += a*a/b;
-            }
-        }
-        
-        it = PH2->begin();
-        for( i = 0; i < N2; i++, ++it )
-        {
-            float v2 = it.value<float>();
-            const SparseMat::Node* node = it.node();
-            if( !PH1->find<float>(node->idx, (size_t*)&node->hashval) )
-                result += v2;
+            double a = v1 - v2;
+            double b = v1;
+            if( fabs(b) > DBL_EPSILON )
+                result += a*a/b;
         }
     }
     else if( method == CV_COMP_CORREL )
@@ -1905,7 +1891,7 @@ cvCompareHist( const CvHistogram* hist1,
     CvSparseMatIterator iterator;
     CvSparseNode *node1, *node2;
 
-    if( mat1->heap->active_count > mat2->heap->active_count )
+    if( mat1->heap->active_count > mat2->heap->active_count && method != CV_COMP_CHISQR )
     {
         CvSparseMat* t;
         CV_SWAP( mat1, mat2, t );
@@ -1918,24 +1904,11 @@ cvCompareHist( const CvHistogram* hist1,
         {
             double v1 = *(float*)CV_NODE_VAL(mat1,node1);
             uchar* node2_data = cvPtrND( mat2, CV_NODE_IDX(mat1,node1), 0, 0, &node1->hashval );
-            if( !node2_data )
-                result += v1;
-            else
-            {
-                double v2 = *(float*)node2_data;
-                double a = v1 - v2;
-                double b = v1 + v2;
-                if( fabs(b) > DBL_EPSILON )
-                    result += a*a/b;
-            }
-        }
-
-        for( node2 = cvInitSparseMatIterator( mat2, &iterator );
-             node2 != 0; node2 = cvGetNextSparseNode( &iterator ))
-        {
-            double v2 = *(float*)CV_NODE_VAL(mat2,node2);
-            if( !cvPtrND( mat1, CV_NODE_IDX(mat2,node2), 0, 0, &node2->hashval ))
-                result += v2;
+            double v2 = node2_data ? *(float*)node2_data : 0.f;
+            double a = v1 - v2;
+            double b = v1;
+            if( fabs(b) > DBL_EPSILON )
+                result += a*a/b;
         }
     }
     else if( method == CV_COMP_CORREL )
index da1643b..2f55a5f 100644 (file)
@@ -1009,8 +1009,8 @@ int CV_CompareHistTest::validate_test_results( int /*test_case_idx*/ )
             double v0 = ptr0[i], v1 = ptr1[i];
             result0[CV_COMP_CORREL] += v0*v1;
             result0[CV_COMP_INTERSECT] += MIN(v0,v1);
-            if( fabs(v0 + v1) > DBL_EPSILON )
-                result0[CV_COMP_CHISQR] += (v0 - v1)*(v0 - v1)/(v0 + v1);
+            if( fabs(v0) > DBL_EPSILON )
+                result0[CV_COMP_CHISQR] += (v0 - v1)*(v0 - v1)/v0;
             s0 += v0;
             s1 += v1;
             sq0 += v0*v0;
@@ -1031,11 +1031,11 @@ int CV_CompareHistTest::validate_test_results( int /*test_case_idx*/ )
             const int* idx = CV_NODE_IDX(sparse0, node);
             double v0 = *(float*)CV_NODE_VAL(sparse0, node);
             double v1 = (float)cvGetRealND(sparse1, idx);
-
+            
             result0[CV_COMP_CORREL] += v0*v1;
             result0[CV_COMP_INTERSECT] += MIN(v0,v1);
-            if( fabs(v0 + v1) > DBL_EPSILON )
-                result0[CV_COMP_CHISQR] += (v0 - v1)*(v0 - v1)/(v0 + v1);
+            if( fabs(v0) > DBL_EPSILON )
+                result0[CV_COMP_CHISQR] += (v0 - v1)*(v0 - v1)/v0;
             s0 += v0;
             sq0 += v0*v0;
             result0[CV_COMP_BHATTACHARYYA] += sqrt(v0*v1);
@@ -1044,12 +1044,7 @@ int CV_CompareHistTest::validate_test_results( int /*test_case_idx*/ )
         for( node = cvInitSparseMatIterator( sparse1, &iterator );
              node != 0; node = cvGetNextSparseNode( &iterator ) )
         {
-            const int* idx = CV_NODE_IDX(sparse1, node);
             double v1 = *(float*)CV_NODE_VAL(sparse1, node);
-            double v0 = (float)cvGetRealND(sparse0, idx);
-
-            if( fabs(v0) < DBL_EPSILON )
-                result0[CV_COMP_CHISQR] += v1;
             s1 += v1;
             sq1 += v1*v1;
         }