📄 cvhistogram.cpp
字号:
"The histograms have different numbers of dimensions" );
for( i = 0; i < dims1; i++ )
{
if( size1[i] != size2[i] )
CV_ERROR( CV_StsUnmatchedSizes, "The histograms have different sizes" );
total *= size1[i];
}
if( !CV_IS_SPARSE_MAT(hist1->bins))
{
union { float* fl; uchar* ptr; } v;
float *ptr1, *ptr2;
v.fl = 0;
CV_CALL( cvGetRawData( hist1->bins, &v.ptr ));
ptr1 = v.fl;
CV_CALL( cvGetRawData( hist2->bins, &v.ptr ));
ptr2 = v.fl;
switch( method )
{
case CV_COMP_CHISQR:
for( i = 0; i < total; i++ )
{
double a = ptr1[i] - ptr2[i];
double b = ptr1[i] + ptr2[i];
if( fabs(b) > DBL_EPSILON )
result += a*a/b;
}
break;
case CV_COMP_CORREL:
{
double s1 = 0, s11 = 0;
double s2 = 0, s22 = 0;
double s12 = 0;
double num, denom2, scale = 1./total;
for( i = 0; i < total; i++ )
{
double a = ptr1[i];
double b = ptr2[i];
s12 += a*b;
s1 += a;
s11 += a*a;
s2 += b;
s22 += b*b;
}
num = s12 - s1*s2*scale;
denom2 = (s11 - s1*s1*scale)*(s22 - s2*s2*scale);
result = fabs(denom2) > DBL_EPSILON ? num/sqrt(denom2) : 1;
}
break;
case CV_COMP_INTERSECT:
for( i = 0; i < total; i++ )
{
float a = ptr1[i];
float b = ptr2[i];
if( a <= b )
result += a;
else
result += b;
}
break;
case CV_COMP_BHATTACHARYYA:
{
double s1 = 0, s2 = 0;
for( i = 0; i < total; i++ )
{
double a = ptr1[i];
double b = ptr2[i];
result += sqrt(a*b);
s1 += a;
s2 += b;
}
s1 *= s2;
s1 = fabs(s1) > FLT_EPSILON ? 1./sqrt(s1) : 1.;
result = 1. - result*s1;
result = sqrt(MAX(result,0.));
}
break;
default:
CV_ERROR( CV_StsBadArg, "Unknown comparison method" );
}
}
else
{
CvSparseMat* mat1 = (CvSparseMat*)(hist1->bins);
CvSparseMat* mat2 = (CvSparseMat*)(hist2->bins);
CvSparseMatIterator iterator;
CvSparseNode *node1, *node2;
if( mat1->heap->active_count > mat2->heap->active_count )
{
CvSparseMat* t;
CV_SWAP( mat1, mat2, t );
}
switch( method )
{
case CV_COMP_CHISQR:
for( node1 = cvInitSparseMatIterator( mat1, &iterator );
node1 != 0; node1 = cvGetNextSparseNode( &iterator ))
{
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;
}
break;
case CV_COMP_CORREL:
{
double s1 = 0, s11 = 0;
double s2 = 0, s22 = 0;
double s12 = 0;
double num, denom2, scale = 1./total;
for( node1 = cvInitSparseMatIterator( mat1, &iterator );
node1 != 0; node1 = cvGetNextSparseNode( &iterator ))
{
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 )
{
double v2 = *(float*)node2_data;
s12 += v1*v2;
}
s1 += v1;
s11 += v1*v1;
}
for( node2 = cvInitSparseMatIterator( mat2, &iterator );
node2 != 0; node2 = cvGetNextSparseNode( &iterator ))
{
double v2 = *(float*)CV_NODE_VAL(mat2,node2);
s2 += v2;
s22 += v2*v2;
}
num = s12 - s1*s2*scale;
denom2 = (s11 - s1*s1*scale)*(s22 - s2*s2*scale);
result = fabs(denom2) > DBL_EPSILON ? num/sqrt(denom2) : 1;
}
break;
case CV_COMP_INTERSECT:
{
for( node1 = cvInitSparseMatIterator( mat1, &iterator );
node1 != 0; node1 = cvGetNextSparseNode( &iterator ))
{
float v1 = *(float*)CV_NODE_VAL(mat1,node1);
uchar* node2_data = cvPtrND( mat2, CV_NODE_IDX(mat1,node1),
0, 0, &node1->hashval );
if( node2_data )
{
float v2 = *(float*)node2_data;
if( v1 <= v2 )
result += v1;
else
result += v2;
}
}
}
break;
case CV_COMP_BHATTACHARYYA:
{
double s1 = 0, s2 = 0;
for( node1 = cvInitSparseMatIterator( mat1, &iterator );
node1 != 0; node1 = cvGetNextSparseNode( &iterator ))
{
double v1 = *(float*)CV_NODE_VAL(mat1,node1);
uchar* node2_data = cvPtrND( mat2, CV_NODE_IDX(mat1,node1),
0, 0, &node1->hashval );
s1 += v1;
if( node2_data )
{
double v2 = *(float*)node2_data;
result += sqrt(v1 * v2);
}
}
for( node1 = cvInitSparseMatIterator( mat2, &iterator );
node1 != 0; node1 = cvGetNextSparseNode( &iterator ))
{
double v2 = *(float*)CV_NODE_VAL(mat2,node1);
s2 += v2;
}
s1 *= s2;
s1 = fabs(s1) > FLT_EPSILON ? 1./sqrt(s1) : 1.;
result = 1. - result*s1;
result = sqrt(MAX(result,0.));
}
break;
default:
CV_ERROR( CV_StsBadArg, "Unknown comparison method" );
}
}
_result = result;
__END__;
return _result;
}
// copies one histogram to another
CV_IMPL void
cvCopyHist( const CvHistogram* src, CvHistogram** _dst )
{
CV_FUNCNAME( "cvCopyHist" );
__BEGIN__;
int eq = 0;
int is_sparse;
int i, dims1, dims2;
int size1[CV_MAX_DIM], size2[CV_MAX_DIM], total = 1;
float* ranges[CV_MAX_DIM];
float** thresh = 0;
CvHistogram* dst;
if( !_dst )
CV_ERROR( CV_StsNullPtr, "Destination double pointer is NULL" );
dst = *_dst;
if( !CV_IS_HIST(src) || (dst && !CV_IS_HIST(dst)) )
CV_ERROR( CV_StsBadArg, "Invalid histogram header[s]" );
is_sparse = CV_IS_SPARSE_MAT(src->bins);
CV_CALL( dims1 = cvGetDims( src->bins, size1 ));
for( i = 0; i < dims1; i++ )
total *= size1[i];
if( dst && is_sparse == CV_IS_SPARSE_MAT(dst->bins))
{
CV_CALL( dims2 = cvGetDims( dst->bins, size2 ));
if( dims1 == dims2 )
{
for( i = 0; i < dims1; i++ )
if( size1[i] != size2[i] )
break;
}
eq = i == dims1;
}
if( !eq )
{
cvReleaseHist( _dst );
CV_CALL( dst = cvCreateHist( dims1, size1,
!is_sparse ? CV_HIST_ARRAY : CV_HIST_SPARSE, 0, 0 ));
*_dst = dst;
}
if( CV_HIST_HAS_RANGES( src ))
{
if( CV_IS_UNIFORM_HIST( src ))
{
for( i = 0; i < dims1; i++ )
ranges[i] = (float*)src->thresh[i];
thresh = ranges;
}
else
thresh = src->thresh2;
CV_CALL( cvSetHistBinRanges( dst, thresh, CV_IS_UNIFORM_HIST(src)));
}
CV_CALL( cvCopy( src->bins, dst->bins ));
__END__;
}
// Sets a value range for every histogram bin
CV_IMPL void
cvSetHistBinRanges( CvHistogram* hist, float** ranges, int uniform )
{
CV_FUNCNAME( "cvSetHistBinRanges" );
__BEGIN__;
int dims, size[CV_MAX_DIM], total = 0;
int i, j;
if( !ranges )
CV_ERROR( CV_StsNullPtr, "NULL ranges pointer" );
if( !CV_IS_HIST(hist) )
CV_ERROR( CV_StsBadArg, "Invalid histogram header" );
CV_CALL( dims = cvGetDims( hist->bins, size ));
for( i = 0; i < dims; i++ )
total += size[i]+1;
if( uniform )
{
for( i = 0; i < dims; i++ )
{
if( !ranges[i] )
CV_ERROR( CV_StsNullPtr, "One of <ranges> elements is NULL" );
hist->thresh[i][0] = ranges[i][0];
hist->thresh[i][1] = ranges[i][1];
}
hist->type |= CV_HIST_UNIFORM_FLAG + CV_HIST_RANGES_FLAG;
}
else
{
float* dim_ranges;
if( !hist->thresh2 )
{
CV_CALL( hist->thresh2 = (float**)cvAlloc(
dims*sizeof(hist->thresh2[0])+
total*sizeof(hist->thresh2[0][0])));
}
dim_ranges = (float*)(hist->thresh2 + dims);
for( i = 0; i < dims; i++ )
{
float val0 = -FLT_MAX;
if( !ranges[i] )
CV_ERROR( CV_StsNullPtr, "One of <ranges> elements is NULL" );
for( j = 0; j <= size[i]; j++ )
{
float val = ranges[i][j];
if( val <= val0 )
CV_ERROR(CV_StsOutOfRange, "Bin ranges should go in ascenting order");
val0 = dim_ranges[j] = val;
}
hist->thresh2[i] = dim_ranges;
dim_ranges += size[i] + 1;
}
hist->type |= CV_HIST_RANGES_FLAG;
hist->type &= ~CV_HIST_UNIFORM_FLAG;
}
__END__;
}
#define ICV_HIST_DUMMY_IDX (INT_MIN/3)
static CvStatus
icvCalcHistLookupTables8u( const CvHistogram* hist, int dims, int* size, int* tab )
{
const int lo = 0, hi = 256;
int is_sparse = CV_IS_SPARSE_HIST( hist );
int have_range = CV_HIST_HAS_RANGES(hist);
int i, j;
if( !have_range || CV_IS_UNIFORM_HIST(hist))
{
for( i = 0; i < dims; i++ )
{
double a = have_range ? hist->thresh[i][0] : 0;
double b = have_range ? hist->thresh[i][1] : 256;
int sz = size[i];
double scale = sz/(b - a);
int step = 1;
if( !is_sparse )
step = ((CvMatND*)(hist->bins))->dim[i].step/sizeof(float);
for( j = lo; j < hi; j++ )
{
int idx = cvFloor((j - a)*scale);
if( (unsigned)idx < (unsigned)sz )
idx *= step;
else
idx = ICV_HIST_DUMMY_IDX;
tab[i*(hi - lo) + j - lo] = idx;
}
}
}
else
{
for( i = 0; i < dims; i++ )
{
double limit = hist->thresh2[i][0];
int idx = -1, write_idx = ICV_HIST_DUMMY_IDX, sz = size[i];
int step = 1;
if( !is_sparse )
step = ((CvMatND*)(hist->bins))->dim[i].step/sizeof(float);
if( limit > hi )
limit = hi;
j = lo;
for(;;)
{
for( ; j < limit; j++ )
tab[i*(hi - lo) + j - lo] = write_idx;
if( (unsigned)(++idx) < (unsigned)sz )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -