1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
43 /* Creates new histogram */
45 cvCreateHist( int dims, int *sizes, CvHistType type, float** ranges, int uniform )
47 CvHistogram *hist = 0;
49 CV_FUNCNAME( "cvCreateHist" );
52 if( (unsigned)dims > CV_MAX_DIM )
53 CV_ERROR( CV_BadOrder, "Number of dimensions is out of range" );
56 CV_ERROR( CV_HeaderIsNull, "Null <sizes> pointer" );
58 CV_CALL( hist = (CvHistogram *)cvAlloc( sizeof( CvHistogram )));
60 hist->type = CV_HIST_MAGIC_VAL;
63 if( type == CV_HIST_ARRAY )
65 CV_CALL( hist->bins = cvInitMatNDHeader( &hist->mat, dims, sizes,
66 CV_HIST_DEFAULT_TYPE ));
67 CV_CALL( cvCreateData( hist->bins ));
69 else if( type == CV_HIST_SPARSE )
71 CV_CALL( hist->bins = cvCreateSparseMat( dims, sizes, CV_HIST_DEFAULT_TYPE ));
75 CV_ERROR( CV_StsBadArg, "Invalid histogram type" );
79 CV_CALL( cvSetHistBinRanges( hist, ranges, uniform ));
83 if( cvGetErrStatus() < 0 )
84 cvReleaseHist( &hist );
90 /* Creates histogram wrapping header for given array */
92 cvMakeHistHeaderForArray( int dims, int *sizes, CvHistogram *hist,
93 float *data, float **ranges, int uniform )
95 CvHistogram* result = 0;
97 CV_FUNCNAME( "cvMakeHistHeaderForArray" );
102 CV_ERROR( CV_StsNullPtr, "Null histogram header pointer" );
105 CV_ERROR( CV_StsNullPtr, "Null data pointer" );
108 hist->type = CV_HIST_MAGIC_VAL;
109 CV_CALL( hist->bins = cvInitMatNDHeader( &hist->mat, dims, sizes,
110 CV_HIST_DEFAULT_TYPE, data ));
115 CV_ERROR( CV_StsBadArg, "Only uniform bin ranges can be used here "
116 "(to avoid memory allocation)" );
117 CV_CALL( cvSetHistBinRanges( hist, ranges, uniform ));
124 if( cvGetErrStatus() < 0 && hist )
135 cvReleaseHist( CvHistogram **hist )
137 CV_FUNCNAME( "cvReleaseHist" );
142 CV_ERROR( CV_StsNullPtr, "" );
146 CvHistogram* temp = *hist;
148 if( !CV_IS_HIST(temp))
149 CV_ERROR( CV_StsBadArg, "Invalid histogram header" );
153 if( CV_IS_SPARSE_HIST( temp ))
154 cvRelease( &temp->bins );
157 cvReleaseData( temp->bins );
162 cvFree( &temp->thresh2 );
171 cvClearHist( CvHistogram *hist )
173 CV_FUNCNAME( "cvClearHist" );
177 if( !CV_IS_HIST(hist) )
178 CV_ERROR( CV_StsBadArg, "Invalid histogram header" );
180 cvZero( hist->bins );
186 // Clears histogram bins that are below than threshold
188 cvThreshHist( CvHistogram* hist, double thresh )
190 CV_FUNCNAME( "cvThreshHist" );
194 if( !CV_IS_HIST(hist) )
195 CV_ERROR( CV_StsBadArg, "Invalid histogram header" );
197 if( !CV_IS_SPARSE_MAT(hist->bins) )
200 CV_CALL( cvGetMat( hist->bins, &mat, 0, 1 ));
201 CV_CALL( cvThreshold( &mat, &mat, thresh, 0, CV_THRESH_TOZERO ));
205 CvSparseMat* mat = (CvSparseMat*)hist->bins;
206 CvSparseMatIterator iterator;
209 for( node = cvInitSparseMatIterator( mat, &iterator );
210 node != 0; node = cvGetNextSparseNode( &iterator ))
212 float* val = (float*)CV_NODE_VAL( mat, node );
222 // Normalizes histogram (make sum of the histogram bins == factor)
224 cvNormalizeHist( CvHistogram* hist, double factor )
228 CV_FUNCNAME( "cvNormalizeHist" );
231 if( !CV_IS_HIST(hist) )
232 CV_ERROR( CV_StsBadArg, "Invalid histogram header" );
234 if( !CV_IS_SPARSE_HIST(hist) )
237 CV_CALL( cvGetMat( hist->bins, &mat, 0, 1 ));
238 CV_CALL( sum = cvSum( &mat ).val[0] );
239 if( fabs(sum) < DBL_EPSILON )
241 CV_CALL( cvScale( &mat, &mat, factor/sum, 0 ));
245 CvSparseMat* mat = (CvSparseMat*)hist->bins;
246 CvSparseMatIterator iterator;
250 for( node = cvInitSparseMatIterator( mat, &iterator );
251 node != 0; node = cvGetNextSparseNode( &iterator ))
253 sum += *(float*)CV_NODE_VAL(mat,node);
256 if( fabs(sum) < DBL_EPSILON )
258 scale = (float)(factor/sum);
260 for( node = cvInitSparseMatIterator( mat, &iterator );
261 node != 0; node = cvGetNextSparseNode( &iterator ))
263 *(float*)CV_NODE_VAL(mat,node) *= scale;
271 // Retrieves histogram global min, max and their positions
273 cvGetMinMaxHistValue( const CvHistogram* hist,
274 float *value_min, float* value_max,
275 int* idx_min, int* idx_max )
277 double minVal, maxVal;
279 CV_FUNCNAME( "cvGetMinMaxHistValue" );
283 int i, dims, size[CV_MAX_DIM];
285 if( !CV_IS_HIST(hist) )
286 CV_ERROR( CV_StsBadArg, "Invalid histogram header" );
288 dims = cvGetDims( hist->bins, size );
290 if( !CV_IS_SPARSE_HIST(hist) )
293 CvPoint minPt, maxPt;
295 CV_CALL( cvGetMat( hist->bins, &mat, 0, 1 ));
296 CV_CALL( cvMinMaxLoc( &mat, &minVal, &maxVal, &minPt, &maxPt ));
301 *idx_min = minPt.y + minPt.x;
303 *idx_max = maxPt.y + maxPt.x;
308 idx_min[0] = minPt.y, idx_min[1] = minPt.x;
310 idx_max[0] = maxPt.y, idx_max[1] = maxPt.x;
312 else if( idx_min || idx_max )
314 int imin = minPt.y*mat.cols + minPt.x;
315 int imax = maxPt.y*mat.cols + maxPt.x;
318 for( i = dims - 1; i >= 0; i-- )
322 int t = imin / size[i];
323 idx_min[i] = imin - t*size[i];
329 int t = imax / size[i];
330 idx_max[i] = imax - t*size[i];
338 CvSparseMat* mat = (CvSparseMat*)hist->bins;
339 CvSparseMatIterator iterator;
343 CvSparseNode* minNode = 0;
344 CvSparseNode* maxNode = 0;
345 const int *_idx_min = 0, *_idx_max = 0;
348 for( node = cvInitSparseMatIterator( mat, &iterator );
349 node != 0; node = cvGetNextSparseNode( &iterator ))
351 int value = *(int*)CV_NODE_VAL(mat,node);
352 value = CV_TOGGLE_FLT(value);
368 _idx_min = CV_NODE_IDX(mat,minNode);
369 _idx_max = CV_NODE_IDX(mat,maxNode);
370 m.i = CV_TOGGLE_FLT(minv); minVal = m.f;
371 m.i = CV_TOGGLE_FLT(maxv); maxVal = m.f;
378 for( i = 0; i < dims; i++ )
381 idx_min[i] = _idx_min ? _idx_min[i] : -1;
383 idx_max[i] = _idx_max ? _idx_max[i] : -1;
388 *value_min = (float)minVal;
391 *value_max = (float)maxVal;
397 // Compares two histograms using one of a few methods
399 cvCompareHist( const CvHistogram* hist1,
400 const CvHistogram* hist2,
405 CV_FUNCNAME( "cvCompareHist" );
410 int size1[CV_MAX_DIM], size2[CV_MAX_DIM], total = 1;
413 if( !CV_IS_HIST(hist1) || !CV_IS_HIST(hist2) )
414 CV_ERROR( CV_StsBadArg, "Invalid histogram header[s]" );
416 if( CV_IS_SPARSE_MAT(hist1->bins) != CV_IS_SPARSE_MAT(hist2->bins))
417 CV_ERROR(CV_StsUnmatchedFormats, "One of histograms is sparse and other is not");
419 CV_CALL( dims1 = cvGetDims( hist1->bins, size1 ));
420 CV_CALL( dims2 = cvGetDims( hist2->bins, size2 ));
423 CV_ERROR( CV_StsUnmatchedSizes,
424 "The histograms have different numbers of dimensions" );
426 for( i = 0; i < dims1; i++ )
428 if( size1[i] != size2[i] )
429 CV_ERROR( CV_StsUnmatchedSizes, "The histograms have different sizes" );
434 if( !CV_IS_SPARSE_MAT(hist1->bins))
436 union { float* fl; uchar* ptr; } v;
439 CV_CALL( cvGetRawData( hist1->bins, &v.ptr ));
441 CV_CALL( cvGetRawData( hist2->bins, &v.ptr ));
447 for( i = 0; i < total; i++ )
449 double a = ptr1[i] - ptr2[i];
450 double b = ptr1[i] + ptr2[i];
451 if( fabs(b) > DBL_EPSILON )
457 double s1 = 0, s11 = 0;
458 double s2 = 0, s22 = 0;
460 double num, denom2, scale = 1./total;
462 for( i = 0; i < total; i++ )
474 num = s12 - s1*s2*scale;
475 denom2 = (s11 - s1*s1*scale)*(s22 - s2*s2*scale);
476 result = fabs(denom2) > DBL_EPSILON ? num/sqrt(denom2) : 1;
479 case CV_COMP_INTERSECT:
480 for( i = 0; i < total; i++ )
490 case CV_COMP_BHATTACHARYYA:
492 double s1 = 0, s2 = 0;
493 for( i = 0; i < total; i++ )
502 s1 = fabs(s1) > FLT_EPSILON ? 1./sqrt(s1) : 1.;
503 result = 1. - result*s1;
504 result = sqrt(MAX(result,0.));
508 CV_ERROR( CV_StsBadArg, "Unknown comparison method" );
513 CvSparseMat* mat1 = (CvSparseMat*)(hist1->bins);
514 CvSparseMat* mat2 = (CvSparseMat*)(hist2->bins);
515 CvSparseMatIterator iterator;
516 CvSparseNode *node1, *node2;
518 if( mat1->heap->active_count > mat2->heap->active_count )
521 CV_SWAP( mat1, mat2, t );
527 for( node1 = cvInitSparseMatIterator( mat1, &iterator );
528 node1 != 0; node1 = cvGetNextSparseNode( &iterator ))
530 double v1 = *(float*)CV_NODE_VAL(mat1,node1);
531 uchar* node2_data = cvPtrND( mat2, CV_NODE_IDX(mat1,node1), 0, 0, &node1->hashval );
536 double v2 = *(float*)node2_data;
539 if( fabs(b) > DBL_EPSILON )
544 for( node2 = cvInitSparseMatIterator( mat2, &iterator );
545 node2 != 0; node2 = cvGetNextSparseNode( &iterator ))
547 double v2 = *(float*)CV_NODE_VAL(mat2,node2);
548 if( !cvPtrND( mat1, CV_NODE_IDX(mat2,node2), 0, 0, &node2->hashval ))
554 double s1 = 0, s11 = 0;
555 double s2 = 0, s22 = 0;
557 double num, denom2, scale = 1./total;
559 for( node1 = cvInitSparseMatIterator( mat1, &iterator );
560 node1 != 0; node1 = cvGetNextSparseNode( &iterator ))
562 double v1 = *(float*)CV_NODE_VAL(mat1,node1);
563 uchar* node2_data = cvPtrND( mat2, CV_NODE_IDX(mat1,node1),
564 0, 0, &node1->hashval );
567 double v2 = *(float*)node2_data;
574 for( node2 = cvInitSparseMatIterator( mat2, &iterator );
575 node2 != 0; node2 = cvGetNextSparseNode( &iterator ))
577 double v2 = *(float*)CV_NODE_VAL(mat2,node2);
582 num = s12 - s1*s2*scale;
583 denom2 = (s11 - s1*s1*scale)*(s22 - s2*s2*scale);
584 result = fabs(denom2) > DBL_EPSILON ? num/sqrt(denom2) : 1;
587 case CV_COMP_INTERSECT:
589 for( node1 = cvInitSparseMatIterator( mat1, &iterator );
590 node1 != 0; node1 = cvGetNextSparseNode( &iterator ))
592 float v1 = *(float*)CV_NODE_VAL(mat1,node1);
593 uchar* node2_data = cvPtrND( mat2, CV_NODE_IDX(mat1,node1),
594 0, 0, &node1->hashval );
597 float v2 = *(float*)node2_data;
606 case CV_COMP_BHATTACHARYYA:
608 double s1 = 0, s2 = 0;
610 for( node1 = cvInitSparseMatIterator( mat1, &iterator );
611 node1 != 0; node1 = cvGetNextSparseNode( &iterator ))
613 double v1 = *(float*)CV_NODE_VAL(mat1,node1);
614 uchar* node2_data = cvPtrND( mat2, CV_NODE_IDX(mat1,node1),
615 0, 0, &node1->hashval );
619 double v2 = *(float*)node2_data;
620 result += sqrt(v1 * v2);
624 for( node1 = cvInitSparseMatIterator( mat2, &iterator );
625 node1 != 0; node1 = cvGetNextSparseNode( &iterator ))
627 double v2 = *(float*)CV_NODE_VAL(mat2,node1);
632 s1 = fabs(s1) > FLT_EPSILON ? 1./sqrt(s1) : 1.;
633 result = 1. - result*s1;
634 result = sqrt(MAX(result,0.));
638 CV_ERROR( CV_StsBadArg, "Unknown comparison method" );
649 // copies one histogram to another
651 cvCopyHist( const CvHistogram* src, CvHistogram** _dst )
653 CV_FUNCNAME( "cvCopyHist" );
660 int size1[CV_MAX_DIM], size2[CV_MAX_DIM], total = 1;
661 float* ranges[CV_MAX_DIM];
666 CV_ERROR( CV_StsNullPtr, "Destination double pointer is NULL" );
670 if( !CV_IS_HIST(src) || (dst && !CV_IS_HIST(dst)) )
671 CV_ERROR( CV_StsBadArg, "Invalid histogram header[s]" );
673 is_sparse = CV_IS_SPARSE_MAT(src->bins);
674 CV_CALL( dims1 = cvGetDims( src->bins, size1 ));
675 for( i = 0; i < dims1; i++ )
678 if( dst && is_sparse == CV_IS_SPARSE_MAT(dst->bins))
680 CV_CALL( dims2 = cvGetDims( dst->bins, size2 ));
684 for( i = 0; i < dims1; i++ )
685 if( size1[i] != size2[i] )
694 cvReleaseHist( _dst );
695 CV_CALL( dst = cvCreateHist( dims1, size1,
696 !is_sparse ? CV_HIST_ARRAY : CV_HIST_SPARSE, 0, 0 ));
700 if( CV_HIST_HAS_RANGES( src ))
702 if( CV_IS_UNIFORM_HIST( src ))
704 for( i = 0; i < dims1; i++ )
705 ranges[i] = (float*)src->thresh[i];
709 thresh = src->thresh2;
710 CV_CALL( cvSetHistBinRanges( dst, thresh, CV_IS_UNIFORM_HIST(src)));
713 CV_CALL( cvCopy( src->bins, dst->bins ));
719 // Sets a value range for every histogram bin
721 cvSetHistBinRanges( CvHistogram* hist, float** ranges, int uniform )
723 CV_FUNCNAME( "cvSetHistBinRanges" );
727 int dims, size[CV_MAX_DIM], total = 0;
731 CV_ERROR( CV_StsNullPtr, "NULL ranges pointer" );
733 if( !CV_IS_HIST(hist) )
734 CV_ERROR( CV_StsBadArg, "Invalid histogram header" );
736 CV_CALL( dims = cvGetDims( hist->bins, size ));
737 for( i = 0; i < dims; i++ )
742 for( i = 0; i < dims; i++ )
745 CV_ERROR( CV_StsNullPtr, "One of <ranges> elements is NULL" );
746 hist->thresh[i][0] = ranges[i][0];
747 hist->thresh[i][1] = ranges[i][1];
750 hist->type |= CV_HIST_UNIFORM_FLAG + CV_HIST_RANGES_FLAG;
758 CV_CALL( hist->thresh2 = (float**)cvAlloc(
759 dims*sizeof(hist->thresh2[0])+
760 total*sizeof(hist->thresh2[0][0])));
762 dim_ranges = (float*)(hist->thresh2 + dims);
764 for( i = 0; i < dims; i++ )
766 float val0 = -FLT_MAX;
769 CV_ERROR( CV_StsNullPtr, "One of <ranges> elements is NULL" );
771 for( j = 0; j <= size[i]; j++ )
773 float val = ranges[i][j];
775 CV_ERROR(CV_StsOutOfRange, "Bin ranges should go in ascenting order");
776 val0 = dim_ranges[j] = val;
779 hist->thresh2[i] = dim_ranges;
780 dim_ranges += size[i] + 1;
783 hist->type |= CV_HIST_RANGES_FLAG;
784 hist->type &= ~CV_HIST_UNIFORM_FLAG;
791 #define ICV_HIST_DUMMY_IDX (INT_MIN/3)
794 icvCalcHistLookupTables8u( const CvHistogram* hist, int dims, int* size, int* tab )
796 const int lo = 0, hi = 256;
797 int is_sparse = CV_IS_SPARSE_HIST( hist );
798 int have_range = CV_HIST_HAS_RANGES(hist);
801 if( !have_range || CV_IS_UNIFORM_HIST(hist))
803 for( i = 0; i < dims; i++ )
805 double a = have_range ? hist->thresh[i][0] : 0;
806 double b = have_range ? hist->thresh[i][1] : 256;
808 double scale = sz/(b - a);
812 step = ((CvMatND*)(hist->bins))->dim[i].step/sizeof(float);
814 for( j = lo; j < hi; j++ )
816 int idx = cvFloor((j - a)*scale);
817 if( (unsigned)idx < (unsigned)sz )
820 idx = ICV_HIST_DUMMY_IDX;
822 tab[i*(hi - lo) + j - lo] = idx;
828 for( i = 0; i < dims; i++ )
830 double limit = hist->thresh2[i][0];
831 int idx = -1, write_idx = ICV_HIST_DUMMY_IDX, sz = size[i];
835 step = ((CvMatND*)(hist->bins))->dim[i].step/sizeof(float);
843 for( ; j < limit; j++ )
844 tab[i*(hi - lo) + j - lo] = write_idx;
846 if( (unsigned)(++idx) < (unsigned)sz )
848 limit = hist->thresh2[i][idx+1];
851 write_idx = idx*step;
856 tab[i*(hi - lo) + j - lo] = ICV_HIST_DUMMY_IDX;
867 /***************************** C A L C H I S T O G R A M *************************/
869 // Calculates histogram for one or more 8u arrays
870 static CvStatus CV_STDCALL
871 icvCalcHist_8u_C1R( uchar** img, int step, uchar* mask, int maskStep,
872 CvSize size, CvHistogram* hist )
875 int is_sparse = CV_IS_SPARSE_HIST(hist);
876 int dims, histsize[CV_MAX_DIM];
880 dims = cvGetDims( hist->bins, histsize );
882 tab = (int*)cvStackAlloc( dims*256*sizeof(int));
883 status = icvCalcHistLookupTables8u( hist, dims, histsize, tab );
891 int* bins = ((CvMatND*)(hist->bins))->data.i;
893 for( i = 0; i < dims; i++ )
894 total *= histsize[i];
896 if( dims <= 3 && total >= -ICV_HIST_DUMMY_IDX )
897 return CV_BADSIZE_ERR; // too big histogram
904 memset( tab1d, 0, sizeof(tab1d));
906 for( ; size.height--; img[0] += step )
911 for( x = 0; x <= size.width - 4; x += 4 )
926 for( ; x < size.width; x++ )
931 for( x = 0; x < size.width; x++ )
938 for( i = 0; i < 256; i++ )
942 bins[idx] += tab1d[i];
947 for( ; size.height--; img[0] += step, img[1] += step )
949 uchar* ptr0 = img[0];
950 uchar* ptr1 = img[1];
953 for( x = 0; x < size.width; x++ )
957 int idx = tab[v0] + tab[256+v1];
965 for( x = 0; x < size.width; x++ )
972 int idx = tab[v0] + tab[256+v1];
983 for( ; size.height--; img[0] += step, img[1] += step, img[2] += step )
985 uchar* ptr0 = img[0];
986 uchar* ptr1 = img[1];
987 uchar* ptr2 = img[2];
990 for( x = 0; x < size.width; x++ )
995 int idx = tab[v0] + tab[256+v1] + tab[512+v2];
1003 for( x = 0; x < size.width; x++ )
1010 int idx = tab[v0] + tab[256+v1] + tab[512+v2];
1021 for( ; size.height--; )
1025 for( x = 0; x < size.width; x++ )
1028 for( i = 0; i < dims; i++ )
1030 int idx = tab[i*256 + img[i][x]];
1041 for( x = 0; x < size.width; x++ )
1046 for( i = 0; i < dims; i++ )
1048 int idx = tab[i*256 + img[i][x]];
1060 for( i = 0; i < dims; i++ )
1067 CvSparseMat* mat = (CvSparseMat*)(hist->bins);
1068 int node_idx[CV_MAX_DIM];
1070 for( ; size.height--; )
1074 for( x = 0; x < size.width; x++ )
1076 for( i = 0; i < dims; i++ )
1078 int idx = tab[i*256 + img[i][x]];
1085 int* bin = (int*)cvPtrND( mat, node_idx, 0, 1 );
1092 for( x = 0; x < size.width; x++ )
1096 for( i = 0; i < dims; i++ )
1098 int idx = tab[i*256 + img[i][x]];
1105 int* bin = (int*)cvPtrND( mat, node_idx, 0, 1, 0 );
1113 for( i = 0; i < dims; i++ )
1122 // Calculates histogram for one or more 32f arrays
1123 static CvStatus CV_STDCALL
1124 icvCalcHist_32f_C1R( float** img, int step, uchar* mask, int maskStep,
1125 CvSize size, CvHistogram* hist )
1127 int is_sparse = CV_IS_SPARSE_HIST(hist);
1128 int uniform = CV_IS_UNIFORM_HIST(hist);
1129 int dims, histsize[CV_MAX_DIM];
1130 double uni_range[CV_MAX_DIM][2];
1133 dims = cvGetDims( hist->bins, histsize );
1134 step /= sizeof(img[0][0]);
1138 for( i = 0; i < dims; i++ )
1140 double t = histsize[i]/((double)hist->thresh[i][1] - hist->thresh[i][0]);
1141 uni_range[i][0] = t;
1142 uni_range[i][1] = -t*hist->thresh[i][0];
1148 CvMatND* mat = (CvMatND*)(hist->bins);
1149 int* bins = mat->data.i;
1157 double a = uni_range[0][0], b = uni_range[0][1];
1158 int sz = histsize[0];
1160 for( ; size.height--; img[0] += step )
1162 float* ptr = img[0];
1166 for( x = 0; x <= size.width - 4; x += 4 )
1168 int v0 = cvFloor(ptr[x]*a + b);
1169 int v1 = cvFloor(ptr[x+1]*a + b);
1171 if( (unsigned)v0 < (unsigned)sz )
1173 if( (unsigned)v1 < (unsigned)sz )
1176 v0 = cvFloor(ptr[x+2]*a + b);
1177 v1 = cvFloor(ptr[x+3]*a + b);
1179 if( (unsigned)v0 < (unsigned)sz )
1181 if( (unsigned)v1 < (unsigned)sz )
1185 for( ; x < size.width; x++ )
1187 int v0 = cvFloor(ptr[x]*a + b);
1188 if( (unsigned)v0 < (unsigned)sz )
1194 for( x = 0; x < size.width; x++ )
1197 int v0 = cvFloor(ptr[x]*a + b);
1198 if( (unsigned)v0 < (unsigned)sz )
1208 double a0 = uni_range[0][0], b0 = uni_range[0][1];
1209 double a1 = uni_range[1][0], b1 = uni_range[1][1];
1210 int sz0 = histsize[0], sz1 = histsize[1];
1211 int step0 = ((CvMatND*)(hist->bins))->dim[0].step/sizeof(float);
1213 for( ; size.height--; img[0] += step, img[1] += step )
1215 float* ptr0 = img[0];
1216 float* ptr1 = img[1];
1220 for( x = 0; x < size.width; x++ )
1222 int v0 = cvFloor( ptr0[x]*a0 + b0 );
1223 int v1 = cvFloor( ptr1[x]*a1 + b1 );
1225 if( (unsigned)v0 < (unsigned)sz0 &&
1226 (unsigned)v1 < (unsigned)sz1 )
1227 bins[v0*step0 + v1]++;
1232 for( x = 0; x < size.width; x++ )
1236 int v0 = cvFloor( ptr0[x]*a0 + b0 );
1237 int v1 = cvFloor( ptr1[x]*a1 + b1 );
1239 if( (unsigned)v0 < (unsigned)sz0 &&
1240 (unsigned)v1 < (unsigned)sz1 )
1241 bins[v0*step0 + v1]++;
1250 for( ; size.height--; )
1254 for( x = 0; x < size.width; x++ )
1257 for( i = 0; i < dims; i++ )
1259 int idx = cvFloor((double)img[i][x]*uni_range[i][0]
1261 if( (unsigned)idx >= (unsigned)histsize[i] )
1263 binptr += idx*(mat->dim[i].step/sizeof(float));
1271 for( x = 0; x < size.width; x++ )
1276 for( i = 0; i < dims; i++ )
1278 int idx = cvFloor((double)img[i][x]*uni_range[i][0]
1280 if( (unsigned)idx >= (unsigned)histsize[i] )
1282 binptr += idx*(mat->dim[i].step/sizeof(float));
1291 for( i = 0; i < dims; i++ )
1298 for( ; size.height--; )
1300 for( x = 0; x < size.width; x++ )
1302 if( !mask || mask[x] )
1305 for( i = 0; i < dims; i++ )
1307 float v = img[i][x];
1308 float* thresh = hist->thresh2[i];
1309 int idx = -1, sz = histsize[i];
1311 while( v >= thresh[idx+1] && ++idx < sz )
1314 if( (unsigned)idx >= (unsigned)sz )
1317 binptr += idx*(mat->dim[i].step/sizeof(float));
1324 for( i = 0; i < dims; i++ )
1333 CvSparseMat* mat = (CvSparseMat*)(hist->bins);
1334 int node_idx[CV_MAX_DIM];
1336 for( ; size.height--; )
1340 for( x = 0; x < size.width; x++ )
1342 if( !mask || mask[x] )
1344 for( i = 0; i < dims; i++ )
1346 int idx = cvFloor(img[i][x]*uni_range[i][0]
1348 if( (unsigned)idx >= (unsigned)histsize[i] )
1354 int* bin = (int*)cvPtrND( mat, node_idx, 0, 1, 0 );
1362 for( x = 0; x < size.width; x++ )
1364 if( !mask || mask[x] )
1366 for( i = 0; i < dims; i++ )
1368 float v = img[i][x];
1369 float* thresh = hist->thresh2[i];
1370 int idx = -1, sz = histsize[i];
1372 while( v >= thresh[idx+1] && ++idx < sz )
1375 if( (unsigned)idx >= (unsigned)sz )
1382 int* bin = (int*)cvPtrND( mat, node_idx, 0, 1, 0 );
1389 for( i = 0; i < dims; i++ )
1402 cvCalcArrHist( CvArr** img, CvHistogram* hist,
1403 int do_not_clear, const CvArr* mask )
1405 CV_FUNCNAME( "cvCalcHist" );
1409 uchar* ptr[CV_MAX_DIM];
1411 int maskstep = 0, step = 0;
1414 CvMat stub0, *mat0 = 0;
1418 if( !CV_IS_HIST(hist))
1419 CV_ERROR( CV_StsBadArg, "Bad histogram pointer" );
1422 CV_ERROR( CV_StsNullPtr, "Null double array pointer" );
1424 CV_CALL( dims = cvGetDims( hist->bins ));
1426 for( i = 0; i < dims; i++ )
1428 CvMat stub, *mat = (CvMat*)img[i];
1429 CV_CALL( mat = cvGetMat( mat, i == 0 ? &stub0 : &stub, 0, 1 ));
1431 if( CV_MAT_CN( mat->type ) != 1 )
1432 CV_ERROR( CV_BadNumChannels, "Only 1-channel arrays are allowed here" );
1441 if( !CV_ARE_SIZES_EQ( mat0, mat ))
1442 CV_ERROR( CV_StsUnmatchedSizes, "Not all the planes have equal sizes" );
1444 if( mat0->step != mat->step )
1445 CV_ERROR( CV_StsUnmatchedSizes, "Not all the planes have equal steps" );
1447 if( !CV_ARE_TYPES_EQ( mat0, mat ))
1448 CV_ERROR( CV_StsUnmatchedFormats, "Not all the planes have equal types" );
1451 cont_flag &= mat->type;
1452 ptr[i] = mat->data.ptr;
1457 CvMat stub, *mat = (CvMat*)mask;
1458 CV_CALL( mat = cvGetMat( mat, &stub, 0, 1 ));
1460 if( !CV_IS_MASK_ARR(mat))
1461 CV_ERROR( CV_StsBadMask, "Bad mask array" );
1463 if( !CV_ARE_SIZES_EQ( mat0, mat ))
1464 CV_ERROR( CV_StsUnmatchedSizes,
1465 "Mask size does not match to other arrays\' size" );
1466 maskptr = mat->data.ptr;
1467 maskstep = mat->step;
1468 cont_flag &= mat->type;
1471 size = cvGetMatSize(mat0);
1472 if( CV_IS_MAT_CONT( cont_flag ))
1474 size.width *= size.height;
1476 maskstep = step = CV_STUB_STEP;
1479 if( !CV_IS_SPARSE_HIST(hist))
1481 dense = *(CvMatND*)hist->bins;
1482 dense.type = (dense.type & ~CV_MAT_TYPE_MASK) | CV_32SC1;
1487 CV_CALL( cvZero( hist->bins ));
1489 else if( !CV_IS_SPARSE_HIST(hist))
1491 CV_CALL( cvConvert( (CvMatND*)hist->bins, &dense ));
1495 CvSparseMat* mat = (CvSparseMat*)(hist->bins);
1496 CvSparseMatIterator iterator;
1499 for( node = cvInitSparseMatIterator( mat, &iterator );
1500 node != 0; node = cvGetNextSparseNode( &iterator ))
1502 Cv32suf* val = (Cv32suf*)CV_NODE_VAL( mat, node );
1503 val->i = cvRound( val->f );
1507 if( CV_MAT_DEPTH(mat0->type) > CV_8S && !CV_HIST_HAS_RANGES(hist))
1508 CV_ERROR( CV_StsBadArg, "histogram ranges must be set (via cvSetHistBinRanges) "
1509 "before calling the function" );
1511 switch( CV_MAT_DEPTH(mat0->type) )
1514 IPPI_CALL( icvCalcHist_8u_C1R( ptr, step, maskptr, maskstep, size, hist ));
1518 union { uchar** ptr; float** fl; } v;
1520 IPPI_CALL( icvCalcHist_32f_C1R( v.fl, step, maskptr, maskstep, size, hist ));
1524 CV_ERROR( CV_StsUnsupportedFormat, "Unsupported array type" );
1527 if( !CV_IS_SPARSE_HIST(hist))
1529 CV_CALL( cvConvert( &dense, (CvMatND*)hist->bins ));
1533 CvSparseMat* mat = (CvSparseMat*)(hist->bins);
1534 CvSparseMatIterator iterator;
1537 for( node = cvInitSparseMatIterator( mat, &iterator );
1538 node != 0; node = cvGetNextSparseNode( &iterator ))
1540 Cv32suf* val = (Cv32suf*)CV_NODE_VAL( mat, node );
1541 val->f = (float)val->i;
1549 /***************************** B A C K P R O J E C T *****************************/
1551 // Calculates back project for one or more 8u arrays
1552 static CvStatus CV_STDCALL
1553 icvCalcBackProject_8u_C1R( uchar** img, int step, uchar* dst, int dstStep,
1554 CvSize size, const CvHistogram* hist )
1556 const int small_hist_size = 1<<12;
1558 int is_sparse = CV_IS_SPARSE_HIST(hist);
1559 int dims, histsize[CV_MAX_DIM];
1563 dims = cvGetDims( hist->bins, histsize );
1565 tab = (int*)cvStackAlloc( dims*256*sizeof(int));
1566 status = icvCalcHistLookupTables8u( hist, dims, histsize, tab );
1573 CvMatND* mat = (CvMatND*)(hist->bins);
1574 float* bins = mat->data.fl;
1577 for( i = 0; i < dims; i++ )
1578 total *= histsize[i];
1580 if( dims <= 3 && total >= -ICV_HIST_DUMMY_IDX )
1581 return CV_BADSIZE_ERR; // too big histogram
1583 if( dims > 1 && total <= small_hist_size && CV_IS_MAT_CONT(mat->type))
1585 buffer = (uchar*)cvAlloc(total);
1587 return CV_OUTOFMEM_ERR;
1588 for( i = 0; i < total; i++ )
1590 int v = cvRound(bins[i]);
1591 buffer[i] = CV_CAST_8U(v);
1600 for( i = 0; i < 256; i++ )
1605 int v = cvRound(bins[idx]);
1606 tab1d[i] = CV_CAST_8U(v);
1612 for( ; size.height--; img[0] += step, dst += dstStep )
1614 uchar* ptr = img[0];
1615 for( x = 0; x <= size.width - 4; x += 4 )
1617 uchar v0 = tab1d[ptr[x]];
1618 uchar v1 = tab1d[ptr[x+1]];
1623 v0 = tab1d[ptr[x+2]];
1624 v1 = tab1d[ptr[x+3]];
1630 for( ; x < size.width; x++ )
1631 dst[x] = tab1d[ptr[x]];
1636 for( ; size.height--; img[0] += step, img[1] += step, dst += dstStep )
1638 uchar* ptr0 = img[0];
1639 uchar* ptr1 = img[1];
1643 for( x = 0; x < size.width; x++ )
1647 int idx = tab[v0] + tab[256+v1];
1658 for( x = 0; x < size.width; x++ )
1662 int idx = tab[v0] + tab[256+v1];
1667 v = cvRound(bins[idx]);
1677 for( ; size.height--; img[0] += step, img[1] += step,
1678 img[2] += step, dst += dstStep )
1680 uchar* ptr0 = img[0];
1681 uchar* ptr1 = img[1];
1682 uchar* ptr2 = img[2];
1686 for( x = 0; x < size.width; x++ )
1691 int idx = tab[v0] + tab[256+v1] + tab[512+v2];
1702 for( x = 0; x < size.width; x++ )
1707 int idx = tab[v0] + tab[256+v1] + tab[512+v2];
1712 v = cvRound(bins[idx]);
1721 for( ; size.height--; dst += dstStep )
1725 for( x = 0; x < size.width; x++ )
1727 uchar* binptr = buffer;
1730 for( i = 0; i < dims; i++ )
1732 int idx = tab[i*256 + img[i][x]];
1746 for( x = 0; x < size.width; x++ )
1748 float* binptr = bins;
1751 for( i = 0; i < dims; i++ )
1753 int idx = tab[i*256 + img[i][x]];
1761 v = cvRound( binptr[0] );
1769 for( i = 0; i < dims; i++ )
1778 CvSparseMat* mat = (CvSparseMat*)(hist->bins);
1779 int node_idx[CV_MAX_DIM];
1781 for( ; size.height--; dst += dstStep )
1783 for( x = 0; x < size.width; x++ )
1787 for( i = 0; i < dims; i++ )
1789 int idx = tab[i*256 + img[i][x]];
1796 float* bin = (float*)cvPtrND( mat, node_idx, 0, 1, 0 );
1797 v = cvRound(bin[0]);
1804 for( i = 0; i < dims; i++ )
1813 // Calculates back project for one or more 32f arrays
1814 static CvStatus CV_STDCALL
1815 icvCalcBackProject_32f_C1R( float** img, int step, float* dst, int dstStep,
1816 CvSize size, const CvHistogram* hist )
1818 int is_sparse = CV_IS_SPARSE_HIST(hist);
1819 int uniform = CV_IS_UNIFORM_HIST(hist);
1820 int dims, histsize[CV_MAX_DIM];
1821 double uni_range[CV_MAX_DIM][2];
1824 dims = cvGetDims( hist->bins, histsize );
1825 step /= sizeof(img[0][0]);
1826 dstStep /= sizeof(dst[0]);
1830 for( i = 0; i < dims; i++ )
1832 double t = ((double)histsize[i])/
1833 ((double)hist->thresh[i][1] - hist->thresh[i][0]);
1834 uni_range[i][0] = t;
1835 uni_range[i][1] = -t*hist->thresh[i][0];
1841 CvMatND* mat = (CvMatND*)(hist->bins);
1842 float* bins = mat->data.fl;
1850 double a = uni_range[0][0], b = uni_range[0][1];
1851 int sz = histsize[0];
1853 for( ; size.height--; img[0] += step, dst += dstStep )
1855 float* ptr = img[0];
1857 for( x = 0; x <= size.width - 4; x += 4 )
1859 int v0 = cvFloor(ptr[x]*a + b);
1860 int v1 = cvFloor(ptr[x+1]*a + b);
1862 if( (unsigned)v0 < (unsigned)sz )
1867 if( (unsigned)v1 < (unsigned)sz )
1868 dst[x+1] = bins[v1];
1872 v0 = cvFloor(ptr[x+2]*a + b);
1873 v1 = cvFloor(ptr[x+3]*a + b);
1875 if( (unsigned)v0 < (unsigned)sz )
1876 dst[x+2] = bins[v0];
1880 if( (unsigned)v1 < (unsigned)sz )
1881 dst[x+3] = bins[v1];
1886 for( ; x < size.width; x++ )
1888 int v0 = cvFloor(ptr[x]*a + b);
1890 if( (unsigned)v0 < (unsigned)sz )
1900 double a0 = uni_range[0][0], b0 = uni_range[0][1];
1901 double a1 = uni_range[1][0], b1 = uni_range[1][1];
1902 int sz0 = histsize[0], sz1 = histsize[1];
1903 int step0 = ((CvMatND*)(hist->bins))->dim[0].step/sizeof(float);
1905 for( ; size.height--; img[0] += step, img[1] += step, dst += dstStep )
1907 float* ptr0 = img[0];
1908 float* ptr1 = img[1];
1910 for( x = 0; x < size.width; x++ )
1912 int v0 = cvFloor( ptr0[x]*a0 + b0 );
1913 int v1 = cvFloor( ptr1[x]*a1 + b1 );
1915 if( (unsigned)v0 < (unsigned)sz0 &&
1916 (unsigned)v1 < (unsigned)sz1 )
1917 dst[x] = bins[v0*step0 + v1];
1925 for( ; size.height--; dst += dstStep )
1927 for( x = 0; x < size.width; x++ )
1929 float* binptr = bins;
1931 for( i = 0; i < dims; i++ )
1933 int idx = cvFloor(img[i][x]*uni_range[i][0]
1935 if( (unsigned)idx >= (unsigned)histsize[i] )
1937 binptr += idx*(mat->dim[i].step/sizeof(float));
1946 for( i = 0; i < dims; i++ )
1952 for( ; size.height--; dst += dstStep )
1954 for( x = 0; x < size.width; x++ )
1956 float* binptr = bins;
1957 for( i = 0; i < dims; i++ )
1959 float v = img[i][x];
1960 float* thresh = hist->thresh2[i];
1961 int idx = -1, sz = histsize[i];
1963 while( v >= thresh[idx+1] && ++idx < sz )
1966 if( (unsigned)idx >= (unsigned)sz )
1969 binptr += idx*(mat->dim[i].step/sizeof(float));
1977 for( i = 0; i < dims; i++ )
1984 CvSparseMat* mat = (CvSparseMat*)(hist->bins);
1985 int node_idx[CV_MAX_DIM];
1987 for( ; size.height--; dst += dstStep )
1991 for( x = 0; x < size.width; x++ )
1993 for( i = 0; i < dims; i++ )
1995 int idx = cvFloor(img[i][x]*uni_range[i][0]
1997 if( (unsigned)idx >= (unsigned)histsize[i] )
2003 float* bin = (float*)cvPtrND( mat, node_idx, 0, 1, 0 );
2012 for( x = 0; x < size.width; x++ )
2014 for( i = 0; i < dims; i++ )
2016 float v = img[i][x];
2017 float* thresh = hist->thresh2[i];
2018 int idx = -1, sz = histsize[i];
2020 while( v >= thresh[idx+1] && ++idx < sz )
2023 if( (unsigned)idx >= (unsigned)sz )
2030 float* bin = (float*)cvPtrND( mat, node_idx, 0, 1, 0 );
2038 for( i = 0; i < dims; i++ )
2048 cvCalcArrBackProject( CvArr** img, CvArr* dst, const CvHistogram* hist )
2050 CV_FUNCNAME( "cvCalcArrBackProject" );
2054 uchar* ptr[CV_MAX_DIM];
2056 int dststep = 0, step = 0;
2059 CvMat stub0, *mat0 = 0;
2062 if( !CV_IS_HIST(hist))
2063 CV_ERROR( CV_StsBadArg, "Bad histogram pointer" );
2066 CV_ERROR( CV_StsNullPtr, "Null double array pointer" );
2068 CV_CALL( dims = cvGetDims( hist->bins ));
2070 for( i = 0; i <= dims; i++ )
2072 CvMat stub, *mat = (CvMat*)(i < dims ? img[i] : dst);
2073 CV_CALL( mat = cvGetMat( mat, i == 0 ? &stub0 : &stub, 0, 1 ));
2075 if( CV_MAT_CN( mat->type ) != 1 )
2076 CV_ERROR( CV_BadNumChannels, "Only 1-channel arrays are allowed here" );
2085 if( !CV_ARE_SIZES_EQ( mat0, mat ))
2086 CV_ERROR( CV_StsUnmatchedSizes, "Not all the planes have equal sizes" );
2088 if( mat0->step != mat->step )
2089 CV_ERROR( CV_StsUnmatchedSizes, "Not all the planes have equal steps" );
2091 if( !CV_ARE_TYPES_EQ( mat0, mat ))
2092 CV_ERROR( CV_StsUnmatchedFormats, "Not all the planes have equal types" );
2095 cont_flag &= mat->type;
2097 ptr[i] = mat->data.ptr;
2100 dstptr = mat->data.ptr;
2101 dststep = mat->step;
2105 size = cvGetMatSize(mat0);
2106 if( CV_IS_MAT_CONT( cont_flag ))
2108 size.width *= size.height;
2110 dststep = step = CV_STUB_STEP;
2113 if( CV_MAT_DEPTH(mat0->type) > CV_8S && !CV_HIST_HAS_RANGES(hist))
2114 CV_ERROR( CV_StsBadArg, "histogram ranges must be set (via cvSetHistBinRanges) "
2115 "before calling the function" );
2117 switch( CV_MAT_DEPTH(mat0->type) )
2120 IPPI_CALL( icvCalcBackProject_8u_C1R( ptr, step, dstptr, dststep, size, hist ));
2124 union { uchar** ptr; float** fl; } v;
2126 IPPI_CALL( icvCalcBackProject_32f_C1R( v.fl, step,
2127 (float*)dstptr, dststep, size, hist ));
2131 CV_ERROR( CV_StsUnsupportedFormat, "Unsupported array type" );
2138 ////////////////////// B A C K P R O J E C T P A T C H /////////////////////////
2141 cvCalcArrBackProjectPatch( CvArr** arr, CvArr* dst, CvSize patch_size, CvHistogram* hist,
2142 int method, double norm_factor )
2144 CvHistogram* model = 0;
2146 CV_FUNCNAME( "cvCalcArrBackProjectPatch" );
2150 IplImage imgstub[CV_MAX_DIM], *img[CV_MAX_DIM];
2152 CvMat dststub, *dstmat;
2157 if( !CV_IS_HIST(hist))
2158 CV_ERROR( CV_StsBadArg, "Bad histogram pointer" );
2161 CV_ERROR( CV_StsNullPtr, "Null double array pointer" );
2163 if( norm_factor <= 0 )
2164 CV_ERROR( CV_StsOutOfRange,
2165 "Bad normalization factor (set it to 1.0 if unsure)" );
2167 if( patch_size.width <= 0 || patch_size.height <= 0 )
2168 CV_ERROR( CV_StsBadSize, "The patch width and height must be positive" );
2170 CV_CALL( dims = cvGetDims( hist->bins ));
2171 CV_CALL( cvCopyHist( hist, &model ));
2172 CV_CALL( cvNormalizeHist( hist, norm_factor ));
2174 for( i = 0; i < dims; i++ )
2177 CV_CALL( mat = cvGetMat( arr[i], &stub, 0, 0 ));
2178 CV_CALL( img[i] = cvGetImage( mat, &imgstub[i] ));
2182 CV_CALL( dstmat = cvGetMat( dst, &dststub, 0, 0 ));
2183 if( CV_MAT_TYPE( dstmat->type ) != CV_32FC1 )
2184 CV_ERROR( CV_StsUnsupportedFormat, "Resultant image must have 32fC1 type" );
2186 if( dstmat->cols != img[0]->width - patch_size.width + 1 ||
2187 dstmat->rows != img[0]->height - patch_size.height + 1 )
2188 CV_ERROR( CV_StsUnmatchedSizes,
2189 "The output map must be (W-w+1 x H-h+1), "
2190 "where the input images are (W x H) each and the patch is (w x h)" );
2192 size = cvGetMatSize(dstmat);
2194 roi.width = patch_size.width;
2195 roi.height = patch_size.height;
2197 for( y = 0; y < size.height; y++ )
2199 for( x = 0; x < size.width; x++ )
2206 CV_CALL( cvCalcHist( img, model ));
2208 CV_CALL( cvNormalizeHist( model, norm_factor ));
2209 CV_CALL( result = cvCompareHist( model, hist, method ));
2210 CV_MAT_ELEM( *dstmat, float, y, x ) = (float)result;
2216 cvReleaseHist( &model );
2220 // Calculates Bayes probabilistic histograms
2222 cvCalcBayesianProb( CvHistogram** src, int count, CvHistogram** dst )
2224 CV_FUNCNAME( "cvCalcBayesianProb" );
2231 CV_ERROR( CV_StsNullPtr, "NULL histogram array pointer" );
2234 CV_ERROR( CV_StsOutOfRange, "Too small number of histograms" );
2236 for( i = 0; i < count; i++ )
2238 if( !CV_IS_HIST(src[i]) || !CV_IS_HIST(dst[i]) )
2239 CV_ERROR( CV_StsBadArg, "Invalid histogram header" );
2241 if( !CV_IS_MATND(src[i]->bins) || !CV_IS_MATND(dst[i]->bins) )
2242 CV_ERROR( CV_StsBadArg, "The function supports dense histograms only" );
2245 cvZero( dst[0]->bins );
2246 // dst[0] = src[0] + ... + src[count-1]
2247 for( i = 0; i < count; i++ )
2248 CV_CALL( cvAdd( src[i]->bins, dst[0]->bins, dst[0]->bins ));
2250 CV_CALL( cvDiv( 0, dst[0]->bins, dst[0]->bins ));
2252 // dst[i] = src[i]*(1/dst[0])
2253 for( i = count - 1; i >= 0; i-- )
2254 CV_CALL( cvMul( src[i]->bins, dst[0]->bins, dst[i]->bins ));
2261 cvCalcProbDensity( const CvHistogram* hist, const CvHistogram* hist_mask,
2262 CvHistogram* hist_dens, double scale )
2264 CV_FUNCNAME( "cvCalcProbDensity" );
2269 CV_ERROR( CV_StsOutOfRange, "scale must be positive" );
2271 if( !CV_IS_HIST(hist) || !CV_IS_HIST(hist_mask) || !CV_IS_HIST(hist_dens) )
2272 CV_ERROR( CV_StsBadArg, "Invalid histogram pointer[s]" );
2275 CvArr* arrs[] = { hist->bins, hist_mask->bins, hist_dens->bins };
2277 CvNArrayIterator iterator;
2279 CV_CALL( cvInitNArrayIterator( 3, arrs, 0, stubs, &iterator ));
2281 if( CV_MAT_TYPE(iterator.hdr[0]->type) != CV_32FC1 )
2282 CV_ERROR( CV_StsUnsupportedFormat, "All histograms must have 32fC1 type" );
2286 const float* srcdata = (const float*)(iterator.ptr[0]);
2287 const float* maskdata = (const float*)(iterator.ptr[1]);
2288 float* dstdata = (float*)(iterator.ptr[2]);
2291 for( i = 0; i < iterator.size.width; i++ )
2293 float s = srcdata[i];
2294 float m = maskdata[i];
2295 if( s > FLT_EPSILON )
2297 dstdata[i] = (float)(m*scale/s);
2299 dstdata[i] = (float)scale;
2301 dstdata[i] = (float)0;
2304 while( cvNextNArraySlice( &iterator ));
2311 CV_IMPL void cvEqualizeHist( const CvArr* src, CvArr* dst )
2313 CvHistogram* hist = 0;
2316 CV_FUNCNAME( "cvEqualizeHist" );
2320 int i, hist_sz = 256;
2327 CV_CALL( type = cvGetElemType( src ));
2328 if( type != CV_8UC1 )
2329 CV_ERROR( CV_StsUnsupportedFormat, "Only 8uC1 images are supported" );
2331 CV_CALL( hist = cvCreateHist( 1, &hist_sz, CV_HIST_ARRAY ));
2332 CV_CALL( lut = cvCreateMat( 1, 256, CV_8UC1 ));
2333 CV_CALL( cvCalcArrHist( (CvArr**)&src, hist ));
2334 CV_CALL( img_sz = cvGetSize( src ));
2335 scale = 255.f/(img_sz.width*img_sz.height);
2336 h = (float*)cvPtr1D( hist->bins, 0 );
2338 for( i = 0; i < hist_sz; i++ )
2340 sum += cvRound(h[i]);
2341 lut->data.ptr[i] = (uchar)cvRound(sum*scale);
2344 lut->data.ptr[0] = 0;
2345 CV_CALL( cvLUT( src, dst, lut ));
2349 cvReleaseHist(&hist);
2353 /* Implementation of RTTI and Generic Functions for CvHistogram */
2354 #define CV_TYPE_NAME_HIST "opencv-hist"
2356 static int icvIsHist( const void * ptr ){
2357 return CV_IS_HIST( ((CvHistogram*)ptr) );
2360 static CvHistogram * icvCloneHist( const CvHistogram * src ){
2361 CvHistogram * dst=NULL;
2362 cvCopyHist(src, &dst);
2366 static void *icvReadHist( CvFileStorage * fs, CvFileNode * node ){
2367 CvHistogram * h = 0;
2369 int have_ranges = 0;
2371 CV_FUNCNAME("icvReadHist");
2374 CV_CALL( h = (CvHistogram *) cvAlloc( sizeof(CvHistogram) ));
2376 is_uniform = cvReadIntByName( fs, node, "is_uniform", 0 );
2377 have_ranges = cvReadIntByName( fs, node, "have_ranges", 0);
2378 h->type = CV_HIST_MAGIC_VAL |
2379 (is_uniform ? CV_HIST_UNIFORM_FLAG : 0) |
2380 (have_ranges ? CV_HIST_RANGES_FLAG : 0);
2383 // read histogram bins
2384 CvMatND * mat = (CvMatND *) cvReadByName( fs, node, "mat" );
2385 int sizes[CV_MAX_DIM];
2387 if(!CV_IS_MATND(mat)){
2388 CV_ERROR( CV_StsError, "Expected CvMatND");
2390 for(i=0; i<mat->dims; i++){
2391 sizes[i] = mat->dim[i].size;
2394 cvInitMatNDHeader( &(h->mat), mat->dims, sizes, mat->type, mat->data.ptr );
2395 h->bins = &(h->mat);
2397 // take ownership of refcount pointer as well
2398 h->mat.refcount = mat->refcount;
2400 // increase refcount so freeing temp header doesn't free data
2401 cvIncRefData( mat );
2403 // free temporary header
2404 cvReleaseMatND( &mat );
2407 h->bins = cvReadByName( fs, node, "bins" );
2408 if(!CV_IS_SPARSE_MAT(h->bins)){
2409 CV_ERROR( CV_StsError, "Unknown Histogram type");
2417 int size[CV_MAX_DIM];
2420 CvFileNode * thresh_node;
2422 CV_CALL( dims = cvGetDims( h->bins, size ));
2423 for( i = 0; i < dims; i++ ){
2427 thresh_node = cvGetFileNodeByName( fs, node, "thresh" );
2429 CV_ERROR( CV_StsError, "'thresh' node is missing");
2431 cvStartReadRawData( fs, thresh_node, &reader );
2434 for(i=0; i<dims; i++){
2435 cvReadRawDataSlice( fs, &reader, 2, h->thresh[i], "f" );
2441 CV_CALL( h->thresh2 = (float**)cvAlloc(
2442 dims*sizeof(h->thresh2[0])+
2443 total*sizeof(h->thresh2[0][0])));
2444 dim_ranges = (float*)(h->thresh2 + dims);
2445 for(i=0; i < dims; i++){
2446 h->thresh2[i] = dim_ranges;
2447 cvReadRawDataSlice( fs, &reader, size[i]+1, dim_ranges, "f" );
2448 dim_ranges += size[i] + 1;
2459 static void icvWriteHist( CvFileStorage* fs, const char* name, const void* struct_ptr,
2460 CvAttrList /*attributes*/ ){
2461 const CvHistogram * hist = (const CvHistogram *) struct_ptr;
2462 int sizes[CV_MAX_DIM];
2465 int is_uniform, have_ranges;
2467 CV_FUNCNAME("icvWriteHist");
2470 cvStartWriteStruct( fs, name, CV_NODE_MAP, CV_TYPE_NAME_HIST );
2472 is_uniform = (CV_IS_UNIFORM_HIST(hist) ? 1 : 0);
2473 have_ranges = (hist->type & CV_HIST_RANGES_FLAG ? 1 : 0);
2475 cvWriteInt( fs, "is_uniform", is_uniform );
2476 cvWriteInt( fs, "have_ranges", have_ranges );
2477 if(CV_IS_UNIFORM_HIST(hist)){
2478 cvWrite( fs, "mat", &(hist->mat) );
2480 else if(CV_IS_SPARSE_HIST(hist)){
2481 cvWrite( fs, "bins", hist->bins );
2484 CV_ERROR( CV_StsError, "Unknown Histogram Type" );
2489 dims = cvGetDims( hist->bins, sizes );
2490 cvStartWriteStruct( fs, "thresh", CV_NODE_SEQ + CV_NODE_FLOW );
2492 for(i=0; i<dims; i++){
2493 cvWriteRawData( fs, hist->thresh[i], 2, "f" );
2497 for(i=0; i<dims; i++){
2498 cvWriteRawData( fs, hist->thresh2[i], sizes[i]+1, "f" );
2501 cvEndWriteStruct( fs );
2504 cvEndWriteStruct( fs );
2509 CvType hist_type( CV_TYPE_NAME_HIST, icvIsHist, (CvReleaseFunc)cvReleaseHist,
2510 icvReadHist, icvWriteHist, (CvCloneFunc)icvCloneHist );