📄 cvhistogram.cpp
字号:
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// Intel License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of Intel Corporation may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "_cv.h"
/* Creates new histogram */
CvHistogram *
cvCreateHist( int dims, int *sizes, CvHistType type, float** ranges, int uniform )
{
CvHistogram *hist = 0;
CV_FUNCNAME( "cvCreateHist" );
__BEGIN__;
if( (unsigned)dims > CV_MAX_DIM )
CV_ERROR( CV_BadOrder, "Number of dimensions is out of range" );
if( !sizes )
CV_ERROR( CV_HeaderIsNull, "Null <sizes> pointer" );
CV_CALL( hist = (CvHistogram *)cvAlloc( sizeof( CvHistogram )));
hist->type = CV_HIST_MAGIC_VAL;
hist->thresh2 = 0;
hist->bins = 0;
if( type == CV_HIST_ARRAY )
{
CV_CALL( hist->bins = cvInitMatNDHeader( &hist->mat, dims, sizes,
CV_HIST_DEFAULT_TYPE ));
CV_CALL( cvCreateData( hist->bins ));
}
else if( type == CV_HIST_SPARSE )
{
CV_CALL( hist->bins = cvCreateSparseMat( dims, sizes, CV_HIST_DEFAULT_TYPE ));
}
else
{
CV_ERROR( CV_StsBadArg, "Invalid histogram type" );
}
if( ranges )
CV_CALL( cvSetHistBinRanges( hist, ranges, uniform ));
__END__;
if( cvGetErrStatus() < 0 )
cvReleaseHist( &hist );
return hist;
}
/* Creates histogram wrapping header for given array */
CV_IMPL CvHistogram*
cvMakeHistHeaderForArray( int dims, int *sizes, CvHistogram *hist,
float *data, float **ranges, int uniform )
{
CvHistogram* result = 0;
CV_FUNCNAME( "cvMakeHistHeaderForArray" );
__BEGIN__;
if( !hist )
CV_ERROR( CV_StsNullPtr, "Null histogram header pointer" );
if( !data )
CV_ERROR( CV_StsNullPtr, "Null data pointer" );
hist->thresh2 = 0;
hist->type = CV_HIST_MAGIC_VAL;
CV_CALL( hist->bins = cvInitMatNDHeader( &hist->mat, dims, sizes,
CV_HIST_DEFAULT_TYPE, data ));
if( ranges )
{
if( !uniform )
CV_ERROR( CV_StsBadArg, "Only uniform bin ranges can be used here "
"(to avoid memory allocation)" );
CV_CALL( cvSetHistBinRanges( hist, ranges, uniform ));
}
result = hist;
__END__;
if( cvGetErrStatus() < 0 && hist )
{
hist->type = 0;
hist->bins = 0;
}
return result;
}
CV_IMPL void
cvReleaseHist( CvHistogram **hist )
{
CV_FUNCNAME( "cvReleaseHist" );
__BEGIN__;
if( !hist )
CV_ERROR( CV_StsNullPtr, "" );
if( *hist )
{
CvHistogram* temp = *hist;
if( !CV_IS_HIST(temp))
CV_ERROR( CV_StsBadArg, "Invalid histogram header" );
*hist = 0;
if( CV_IS_SPARSE_HIST( temp ))
cvRelease( &temp->bins );
else
{
cvReleaseData( temp->bins );
temp->bins = 0;
}
if( temp->thresh2 )
cvFree( &temp->thresh2 );
cvFree( &temp );
}
__END__;
}
CV_IMPL void
cvClearHist( CvHistogram *hist )
{
CV_FUNCNAME( "cvClearHist" );
__BEGIN__;
if( !CV_IS_HIST(hist) )
CV_ERROR( CV_StsBadArg, "Invalid histogram header" );
cvZero( hist->bins );
__END__;
}
// Clears histogram bins that are below than threshold
CV_IMPL void
cvThreshHist( CvHistogram* hist, double thresh )
{
CV_FUNCNAME( "cvThreshHist" );
__BEGIN__;
if( !CV_IS_HIST(hist) )
CV_ERROR( CV_StsBadArg, "Invalid histogram header" );
if( !CV_IS_SPARSE_MAT(hist->bins) )
{
CvMat mat;
CV_CALL( cvGetMat( hist->bins, &mat, 0, 1 ));
CV_CALL( cvThreshold( &mat, &mat, thresh, 0, CV_THRESH_TOZERO ));
}
else
{
CvSparseMat* mat = (CvSparseMat*)hist->bins;
CvSparseMatIterator iterator;
CvSparseNode *node;
for( node = cvInitSparseMatIterator( mat, &iterator );
node != 0; node = cvGetNextSparseNode( &iterator ))
{
float* val = (float*)CV_NODE_VAL( mat, node );
if( *val <= thresh )
*val = 0;
}
}
__END__;
}
// Normalizes histogram (make sum of the histogram bins == factor)
CV_IMPL void
cvNormalizeHist( CvHistogram* hist, double factor )
{
double sum = 0;
CV_FUNCNAME( "cvNormalizeHist" );
__BEGIN__;
if( !CV_IS_HIST(hist) )
CV_ERROR( CV_StsBadArg, "Invalid histogram header" );
if( !CV_IS_SPARSE_HIST(hist) )
{
CvMat mat;
CV_CALL( cvGetMat( hist->bins, &mat, 0, 1 ));
CV_CALL( sum = cvSum( &mat ).val[0] );
if( fabs(sum) < DBL_EPSILON )
sum = 1;
CV_CALL( cvScale( &mat, &mat, factor/sum, 0 ));
}
else
{
CvSparseMat* mat = (CvSparseMat*)hist->bins;
CvSparseMatIterator iterator;
CvSparseNode *node;
float scale;
for( node = cvInitSparseMatIterator( mat, &iterator );
node != 0; node = cvGetNextSparseNode( &iterator ))
{
sum += *(float*)CV_NODE_VAL(mat,node);
}
if( fabs(sum) < DBL_EPSILON )
sum = 1;
scale = (float)(factor/sum);
for( node = cvInitSparseMatIterator( mat, &iterator );
node != 0; node = cvGetNextSparseNode( &iterator ))
{
*(float*)CV_NODE_VAL(mat,node) *= scale;
}
}
__END__;
}
// Retrieves histogram global min, max and their positions
CV_IMPL void
cvGetMinMaxHistValue( const CvHistogram* hist,
float *value_min, float* value_max,
int* idx_min, int* idx_max )
{
double minVal, maxVal;
CV_FUNCNAME( "cvGetMinMaxHistValue" );
__BEGIN__;
int i, dims, size[CV_MAX_DIM];
if( !CV_IS_HIST(hist) )
CV_ERROR( CV_StsBadArg, "Invalid histogram header" );
dims = cvGetDims( hist->bins, size );
if( !CV_IS_SPARSE_HIST(hist) )
{
CvMat mat;
CvPoint minPt, maxPt;
CV_CALL( cvGetMat( hist->bins, &mat, 0, 1 ));
CV_CALL( cvMinMaxLoc( &mat, &minVal, &maxVal, &minPt, &maxPt ));
if( dims == 1 )
{
if( idx_min )
*idx_min = minPt.y + minPt.x;
if( idx_max )
*idx_max = maxPt.y + maxPt.x;
}
else if( dims == 2 )
{
if( idx_min )
idx_min[0] = minPt.y, idx_min[1] = minPt.x;
if( idx_max )
idx_max[0] = maxPt.y, idx_max[1] = maxPt.x;
}
else if( idx_min || idx_max )
{
int imin = minPt.y*mat.cols + minPt.x;
int imax = maxPt.y*mat.cols + maxPt.x;
int i;
for( i = dims - 1; i >= 0; i-- )
{
if( idx_min )
{
int t = imin / size[i];
idx_min[i] = imin - t*size[i];
imin = t;
}
if( idx_max )
{
int t = imax / size[i];
idx_max[i] = imax - t*size[i];
imax = t;
}
}
}
}
else
{
CvSparseMat* mat = (CvSparseMat*)hist->bins;
CvSparseMatIterator iterator;
CvSparseNode *node;
int minv = INT_MAX;
int maxv = INT_MIN;
CvSparseNode* minNode = 0;
CvSparseNode* maxNode = 0;
const int *_idx_min = 0, *_idx_max = 0;
Cv32suf m;
for( node = cvInitSparseMatIterator( mat, &iterator );
node != 0; node = cvGetNextSparseNode( &iterator ))
{
int value = *(int*)CV_NODE_VAL(mat,node);
value = CV_TOGGLE_FLT(value);
if( value < minv )
{
minv = value;
minNode = node;
}
if( value > maxv )
{
maxv = value;
maxNode = node;
}
}
if( minNode )
{
_idx_min = CV_NODE_IDX(mat,minNode);
_idx_max = CV_NODE_IDX(mat,maxNode);
m.i = CV_TOGGLE_FLT(minv); minVal = m.f;
m.i = CV_TOGGLE_FLT(maxv); maxVal = m.f;
}
else
{
minVal = maxVal = 0;
}
for( i = 0; i < dims; i++ )
{
if( idx_min )
idx_min[i] = _idx_min ? _idx_min[i] : -1;
if( idx_max )
idx_max[i] = _idx_max ? _idx_max[i] : -1;
}
}
if( value_min )
*value_min = (float)minVal;
if( value_max )
*value_max = (float)maxVal;
__END__;
}
// Compares two histograms using one of a few methods
CV_IMPL double
cvCompareHist( const CvHistogram* hist1,
const CvHistogram* hist2,
int method )
{
double _result = -1;
CV_FUNCNAME( "cvCompareHist" );
__BEGIN__;
int i, dims1, dims2;
int size1[CV_MAX_DIM], size2[CV_MAX_DIM], total = 1;
double result = 0;
if( !CV_IS_HIST(hist1) || !CV_IS_HIST(hist2) )
CV_ERROR( CV_StsBadArg, "Invalid histogram header[s]" );
if( CV_IS_SPARSE_MAT(hist1->bins) != CV_IS_SPARSE_MAT(hist2->bins))
CV_ERROR(CV_StsUnmatchedFormats, "One of histograms is sparse and other is not");
CV_CALL( dims1 = cvGetDims( hist1->bins, size1 ));
CV_CALL( dims2 = cvGetDims( hist2->bins, size2 ));
if( dims1 != dims2 )
CV_ERROR( CV_StsUnmatchedSizes,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -