直方图CvHistogram多维直方图 typedef struct CvHistogram { int header_size; /* 头尺寸 */ CvHistType type; /* 直方图类型 */ int flags; /* 直方图标识 */ int c_dims; /* 直方图维数 */ int dims[CV_HIST_MAX_DIM]; /* 每一维的尺寸 */ int mdims[CV_HIST_MAX_DIM]; /* 快速访问元素的系数 */ /* &m[a,b,c] = m + a*mdims[0] + b*mdims[1] + c*mdims[2] */ float* thresh[CV_HIST_MAX_DIM]; /* 每一维的直方块边界数组 */ float* array; /* 所有的直方图数据,扩展为单行 */ struct CvNode* root; /* 存储直方块的平衡树的根结点 */ CvSet* set; /* 内存存储仓的指针 (对平衡树而言) */ int* chdims[CV_HIST_MAX_DIM]; /* 快速计算的缓存 */ } CvHistogram; CreateHist创建直方图 CvHistogram* cvCreateHist( int dims, int* sizes, int type, float** ranges=NULL, int uniform=1 );
函数 cvCreateHist 创建一个指定尺寸的直方图,并且返回创建的直方图的指针。 如果数组的 SetHistBinRanges设置直方块的区间 void cvSetHistBinRanges( CvHistogram* hist, float** ranges, int uniform=1 );
函数 cvSetHistBinRanges 是一个独立的函数,完成直方块的区间设置。更多详细的关于参数 ReleaseHist释放直方图结构 void cvReleaseHist( CvHistogram** hist );
函数 cvReleaseHist 释放直方图 (头和数据). 指向直方图的指针被函数所清空。如果 ClearHist清除直方图 void cvClearHist( CvHistogram* hist );
函数 cvClearHist 当直方图是稠密数组时将所有直方块设置为 0,当直方图是稀疏数组时,除去所有的直方块。 MakeHistHeaderForArray从数组中创建直方图 CvHistogram* cvMakeHistHeaderForArray( int dims, int* sizes, CvHistogram* hist, float* data, float** ranges=NULL, int uniform=1 );
函数 cvMakeHistHeaderForArray 初始化直方图,其中头和直方块为用户所分配。以后不需要调用 cvReleaseHist 只有稠密直方图可以采用这种方法,函数返回 QueryHistValue_1D查询直方块的值 #define cvQueryHistValue_1D( hist, idx0 ) / cvGetReal1D( (hist)->bins, (idx0) ) #define cvQueryHistValue_2D( hist, idx0, idx1 ) / cvGetReal2D( (hist)->bins, (idx0), (idx1) ) #define cvQueryHistValue_3D( hist, idx0, idx1, idx2 ) / cvGetReal3D( (hist)->bins, (idx0), (idx1), (idx2) ) #define cvQueryHistValue_nD( hist, idx ) / cvGetRealND( (hist)->bins, (idx) )
宏 cvQueryHistValue_*D 返回 1D, 2D, 3D 或 N-D 直方图的指定直方块的值。对稀疏直方图,如果方块在直方图中不存在,函数返回 0, 而且不创建新的直方块。 GetHistValue_1D返回直方块的指针 #define cvGetHistValue_1D( hist, idx0 ) / ((float*)(cvPtr1D( (hist)->bins, (idx0), 0 )) #define cvGetHistValue_2D( hist, idx0, idx1 ) / ((float*)(cvPtr2D( (hist)->bins, (idx0), (idx1), 0 )) #define cvGetHistValue_3D( hist, idx0, idx1, idx2 ) / ((float*)(cvPtr3D( (hist)->bins, (idx0), (idx1), (idx2), 0 )) #define cvGetHistValue_nD( hist, idx ) / ((float*)(cvPtrND( (hist)->bins, (idx), 0 ))
宏 cvGetHistValue_*D 返回 1D, 2D, 3D 或 N-D 直方图的指定直方块的指针。对稀疏直方图,函数创建一个新的直方块,且设置其为 0,除非它已经存在。 GetMinMaxHistValue发现最大和最小直方块 void cvGetMinMaxHistValue( const CvHistogram* hist, float* min_value, float* max_value, int* min_idx=NULL, int* max_idx=NULL );
函数 cvGetMinMaxHistValue 发现最大和最小直方块以及它们的位置。任何输出变量都是可选的。在具有同样值几个极值中,返回具有最小下标索引(以字母排列顺序定)的那一个。 NormalizeHist归一化直方图 void cvNormalizeHist( CvHistogram* hist, double factor );
函数 cvNormalizeHist 通过缩放来归一化直方块,使得所有块的和等于 ThreshHist对直方图取阈值 void cvThreshHist( CvHistogram* hist, double threshold );
函数 cvThreshHist 清除那些小于指定阈值得直方块 CompareHist比较两个稠密直方图 double cvCompareHist( const CvHistogram* hist1, const CvHistogram* hist2, int method );
函数 cvCompareHist 采用下面指定的方法比较两个稠密直方图( 相关 (method=CV_COMP_CORREL): d(H1,H2)=sumI(H'1(I)•H'2(I))/sqrt(sumI[H'1(I)2]•sumI[H'2(I)2]) 其中 H'k(I)=Hk(I)-1/N•sumJHk(J) (N=number of histogram bins) Chi-square(method=CV_COMP_CHISQR): d(H1,H2)=sumI[(H1(I)-H2(I))/(H1(I)+H2(I))] 交叉 (method=CV_COMP_INTERSECT): d(H1,H2)=sumImax(H1(I),H2(I)) 函数返回 为了比较稀疏直方图或更一般的加权稀疏点集(译者注:直方图匹配是图像检索中的常用方法),考虑使用函数 cvCalcEMD 。 CopyHist拷贝直方图 void cvCopyHist( const CvHistogram* src, CvHistogram** dst );
函数 cvCopyHist 对直方图作拷贝。如果第二个直方图指针 CalcHist计算图像image(s) 的直方图 void cvCalcHist( IplImage** image, CvHistogram* hist, int accumulate=0, const CvArr* mask=NULL );
函数 cvCalcHist 计算单通道或多通道图像的直方图。 用来增加直方块的数组元素可从相应输入图像的同样位置提取。 Sample. 计算和显示彩色图像的 2D 色调-饱和度图像#include <cv.h> #include <highgui.h> int main( int argc, char** argv ) { IplImage* src; if( argc == 2 && (src=cvLoadImage(argv[1], 1))!= 0) { IplImage* h_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* s_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* v_plane = cvCreateImage( cvGetSize(src), 8, 1 ); IplImage* planes[] = { h_plane, s_plane }; IplImage* hsv = cvCreateImage( cvGetSize(src), 8, 3 ); int h_bins = 30, s_bins = 32; int hist_size[] = {h_bins, s_bins}; float h_ranges[] = { 0, 180 }; /* hue varies from 0 (~0°red) to 180 (~360°red again) */ float s_ranges[] = { 0, 255 }; /* saturation varies from 0 (black-gray-white) to 255 (pure spectrum color) */ float* ranges[] = { h_ranges, s_ranges }; int scale = 10; IplImage* hist_img = cvCreateImage( cvSize(h_bins*scale,s_bins*scale), 8, 3 ); CvHistogram* hist; float max_value = 0; int h, s; cvCvtColor( src, hsv, CV_BGR2HSV ); cvCvtPixToPlane( hsv, h_plane, s_plane, v_plane, 0 ); hist = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1 ); cvCalcHist( planes, hist, 0, 0 ); cvGetMinMaxHistValue( hist, 0, &max_value, 0, 0 ); cvZero( hist_img ); for( h = 0; h < h_bins; h++ ) { for( s = 0; s < s_bins; s++ ) { float bin_val = cvQueryHistValue_2D( hist, h, s ); int intensity = cvRound(bin_val*255/max_value); cvRectangle( hist_img, cvPoint( h*scale, s*scale ), cvPoint( (h+1)*scale - 1, (s+1)*scale - 1), CV_RGB(intensity,intensity,intensity), /* graw a grayscale histogram. if you have idea how to do it nicer let us know */ CV_FILLED ); } } cvNamedWindow( "Source", 1 ); cvShowImage( "Source", src ); cvNamedWindow( "H-S Histogram", 1 ); cvShowImage( "H-S Histogram", hist_img ); cvWaitKey(0); } } CalcBackProject计算反向投影 void cvCalcBackProject( IplImage** image, CvArr* back_project, const CvHistogram* hist );
函数 cvCalcBackProject 直方图的反向投影. 对于所有输入的单通道图像同一位置的象素数组,该函数根据相应的象素数组(RGB),放置其对应的直方块的值到输出图像中。用统计学术语,输出图像象素点的值是观测数组在某个分布(直方图)下的的概率。 例如,为了发现图像中的红色目标,可以这么做:
CalcBackProjectPatch用直方图比较来定位图像中的模板 void cvCalcBackProjectPatch( IplImage** image, CvArr* dst, CvSize patch_size, CvHistogram* hist, int method, float factor );
函数 cvCalcBackProjectPatch 通过输入图像补丁的直方图和给定直方图的比较,来计算反向投影。提取图像在 ROI 中每一个位置的某种测量结果产生了数组 在选择的 ROI 中,每一个新的图像被测量并且转换为一个图像数组。在以锚点为“补丁”中心的图像 Back Project Calculation by PatchesCalcProbDensity两个直方图相除 void cvCalcProbDensity( const CvHistogram* hist1, const CvHistogram* hist2, CvHistogram* dst_hist, double scale=255 );
函数 cvCalcProbDensity 从两个直方图中计算目标概率密度: dist_hist(I)=0 if hist1(I)==0 scale if hist1(I)!=0 && hist2(I)>hist1(I) hist2(I)*scale/hist1(I) if hist1(I)!=0 && hist2(I)<=hist1(I) 所以输出的直方块小于尺度因子。 |