您的位置:首页 > 理论基础 > 数据结构算法

OpenCV的直方图的数据结构CvHistogram理解

2012-12-28 11:13 267 查看
CvHistogram的定义:

typedef
structCvHistogram
{
int type;
CvArr* bins;
float thresh[CV_MAX_DIM][2]; /* For uniformhistograms. */
float**thresh2; /* For non-uniform histograms. */
CvMatND mat; /*Embedded matrix header for array histograms. */
}
CvHistogram;

type:数据结构类型,用来区分各个类型的。比如:CvMat、CvMatND、IplImage(图像结构中,其用nSize成员代替)。OpenCV很多函数的原型都用到了一个CvArr*类型。这个类型说明可以接受一个CvMat或者IplImage类型的指针。这是我们对它的最初理解。其实,看过CvArr定义的人都知道,其实是typedefvoid
CvArr;并非派生关系。 对于OPenCV函数内部,得到的是一个void指针,这时就有必要确切的知道得到的到底是一个什么类型(是CvMat指针还是IplImage指针,还是CvMatND指针)。这样type的作用就体现了。

bins:一个CvArr(即void)指针,可以先把其理解成一个快捷方式。其等于mat成员的data成员。

thresh:一个二维数组。而且第二维是2,这个函数是求图像的分布像素值(像素灰度值)分布情况。而不同的人,对不同的灰度值感兴趣。这时,OpenCV就必须能够让用户自行指定一个灰度值的范围。这就需要一个上界和下界来指定一个范围。这就是第二维的大小是2的原因。
thresh2:先一下这个问题:直方图的bin的个数和各个bin的大小 是怎么确定的?bin的个数是通过cvCreateHist函数的参数来设定的。而各个bin的大小就有两种情况了。1:每个bin都一样大。2:每个bin的大小不一样大。对于每个bin一样大的话,bin的大小是比较容易解决的。相信大家都想到了,平均即可,因为有了上下界和bin的个数。而对于种情况就要用到thresh2这个成员了。要是不将每一个bin的大小设为一样的话,那么就得由用户自己设定每一个bin的大小(就是设定每一个bin的上下界)。当然要是多维的直方图,那么就要为每一维的所有bin都设定上下界。这就需要一个二维数组来存储这样的数据。从CvHistogram这个结构体可以看到thresh2成员是一个二维指针。这就是thresh2的来由了。

mat:用来存数据,前面的bins指针其实是等于mat成员的data的。所以,只在mat里存放数据。

cvCalcHist函数对图像进行操作后,得到了每一个bin的大小,并存放到mat的data成员指向的内存中。至于bings成员。请看下面的代码
if( type ==CV_HIST_ARRAY )
{
hist->bins = cvInitMatNDHeader(&hist->mat, dims, sizes,
CV_HIST_DEFAULT_TYPE );
cvCreateData( hist->bins );
}
else
if( type == CV_HIST_SPARSE )
hist->bins = cvCreateSparseMat(dims, sizes, CV_HIST_DEFAULT_TYPE );
所以,bins成员的值和mat里的data成员的值一样。之所以说是快捷方式,应该可以通过它可以快速得到存放直方图信息的地址。
mat成员还有一个dim的结构体。这个结构体的size成员用来存储直方图中各维的bin的个数。而该结构体的step成员是从本维本数据跳到下本维的下一个数据的字节数。比如说,对于前面那个二维直方图的例子。其dim[0].step = 32;而dim[1].step = 4.对于第二维来说,之所以是4.是因为每一个bin都是用float类型存储的。所以跳4.就像一个float数组。下标为2的地址和下标为3的地址就是相差4(字节)。而第一维是32.是因为有第二维有8个bin,每个bin为4位。所以要跳过8*4=32位。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: