}
else if( method == CV_COMP_KL_DIV )
{
- for( j = 0; j < len; j++ ){
+ for( j = 0; j < len; j++ )
+ {
double p = h1[j];
double q = h2[j];
- if( p == 0.0 )
+ if( fabs(p) <= DBL_EPSILON ) {
continue;
- if( q == 0.0 )
- q += 1e-10;
+ }
+ if( fabs(q) <= DBL_EPSILON ) {
+ q = 1e-10;
+ }
result += p * cv::log( p / q );
}
}
CV_Assert( H1.size(i) == H2.size(i) );
const SparseMat *PH1 = &H1, *PH2 = &H2;
- if( PH1->nzcount() > PH2->nzcount() && method != CV_COMP_CHISQR && method != CV_COMP_CHISQR_ALT)
+ if( PH1->nzcount() > PH2->nzcount() && method != CV_COMP_CHISQR && method != CV_COMP_CHISQR_ALT && method != CV_COMP_KL_DIV )
std::swap(PH1, PH2);
SparseMatConstIterator it = PH1->begin();
s1 = fabs(s1) > FLT_EPSILON ? 1./std::sqrt(s1) : 1.;
result = std::sqrt(std::max(1. - result*s1, 0.));
}
+ else if( method == CV_COMP_KL_DIV )
+ {
+ for( i = 0; i < N1; i++, ++it )
+ {
+ float v1 = it.value<float>();
+ const SparseMat::Node* node = it.node();
+ float v2 = PH2->value<float>(node->idx, (size_t*)&node->hashval);
+ if( !v2 )
+ v2 = 1e-10;
+ result += v1 * cv::log( v1 / v2 );
+ }
+ }
else
CV_Error( CV_StsBadArg, "Unknown comparison method" );
CvSparseMatIterator iterator;
CvSparseNode *node1, *node2;
- if( mat1->heap->active_count > mat2->heap->active_count && method != CV_COMP_CHISQR && method != CV_COMP_CHISQR_ALT)
+ if( mat1->heap->active_count > mat2->heap->active_count && method != CV_COMP_CHISQR && method != CV_COMP_CHISQR_ALT && method != CV_COMP_KL_DIV )
{
CvSparseMat* t;
CV_SWAP( mat1, mat2, t );
result = 1. - result*s1;
result = sqrt(MAX(result,0.));
}
+ else if( method == CV_COMP_KL_DIV )
+ {
+ cv::SparseMat sH1, sH2;
+ ((const CvSparseMat*)hist1->bins)->copyToSparseMat(sH1);
+ ((const CvSparseMat*)hist2->bins)->copyToSparseMat(sH2);
+ result = cv::compareHist( sH1, sH2, CV_COMP_KL_DIV );
+ }
else
CV_Error( CV_StsBadArg, "Unknown comparison method" );
sq0 += v0*v0;
sq1 += v1*v1;
result0[CV_COMP_BHATTACHARYYA] += sqrt(v0*v1);
- if( fabs(v0) > DBL_EPSILON )
{
- if( fabs(v1) < DBL_EPSILON )
- v1 += 1e-10;
- result0[CV_COMP_KL_DIV] += v0 * cv::log( v0 / v1 );
+ if( fabs(v0) <= DBL_EPSILON )
+ continue;
+ if( fabs(v1) <= DBL_EPSILON )
+ v1 = 1e-10;
+ result0[CV_COMP_KL_DIV] += v0 * std::log( v0 / v1 );
}
}
}
s0 += v0;
sq0 += v0*v0;
result0[CV_COMP_BHATTACHARYYA] += sqrt(v0*v1);
- if( fabs(v0) > DBL_EPSILON )
{
- if( fabs(v1) < DBL_EPSILON )
- v1 += 1e-10;
- result0[CV_COMP_KL_DIV] += v0 * cv::log( v0 / v1 );
+ if (v0 <= DBL_EPSILON)
+ continue;
+ if (!v1)
+ v1 = 1e-10;
+ result0[CV_COMP_KL_DIV] += v0 * cv::log( v0 / v1 );
}
}