对​O​p​e​n​C​V​直​方​图​的​数​据​结​构​C​v​H​i​s​t​o​g​r​a​m​的​理​解...

本文深入探讨了OpenCV中CvHistogram数据结构的细节,包括type、bins、thresh及thresh2等成员变量的功能与用途,解释了一维和二维直方图的概念,并提供了实例帮助读者更好地理解。

前几天被OpenCV的直方图的数据结构CvHistogram弄得很纠结。上网一搜,也没什么相关的资料。现在有点头绪了,就写点东西,让后面的人好走一些吧。

 

先来看看CvHistogram的定义:

typedef struct CvHistogram

{

    int     type;

    CvArr*  bins;

    float   thresh[CV_MAX_DIM][2];  /* For uniform histograms.                      */

    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定义的人都知道,其实是typedef void CvArr;并非派生关系。      对于OPenCV函数内部,得到的是一个void指针,这时就有必要确切的知道得到的到底是一个什么类型(是CvMat指针还是IplImage指针,还是CvMatND指针)。这样type的作用就体现了。

 

第二个 成员bins。一个CvArr(即void)指针。大家可以先把其理解成一个快捷方式。其等于mat成员的data成员。等一下再说这个成员。

 

第三个成员是thresh。是一个二维数组。而且第二维是2.设想一下,这个函数是求图像的分布像素值(像素灰度值)分布情况。而不同的人,对不同的灰度值感兴趣。这时,OpenCV就必须能够让用户自行指定一个灰度值的范围。这就需要一个上界和下界来指定一个范围。这就是第二维的大小是2的原因。在讲第一维前,先来说说直方图的维数。一开始我对什么“一维直方图”、“二维直方图”不是很明。不知道怎么样才算是二维的。后面找到了一张二维直方图才明白。《学习OpenCV》、网上都有很多一维的直方图。我也在这里给出一个一维的直方图:

 

一维直方图

 

最重要的还是二维的直方图。

 

二维直方图,其中第一维是16.第二维为8.大家可以在图中看到最左边的8条红柱(当然第一条是白色的)。其红的程度不同。对于其他颜色也是分成了8中不同的程度。一共有16种。

下面的是图片的网址,还有代码。

http://www.opencv.org.cn/index.php/%E5%9B%BE%E5%83%8F%E9%A2%9C%E8%89%B2%E5%88%86%E5%B8%83%E7%9B%B4%E6%96%B9%E5%9B%BE

 

现在,大家对直方图的维数,应该有一点认识了。现在来说说thresh成员。正是因为直方图可以有多维的,所以,必须得用thresh来指明各维的上下界。所以这个thresh成员是一个二维的指针。

 

现在到了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位。

 

 

 

其实,要想出较好的理解这个结构,最好还是自己敲代码,写一个能执行的例子出来。看看结果。然后,在调试的情况下,进入OpenCV的函数内部看看。

转载于:https://www.cnblogs.com/retrieval/p/3734508.html

### 最大似然估计 (Maximum Likelihood Estimation) 最大似然估计是一种常用的参估计法,在统计学和机器学习领域具有广泛的应用。其核心思想是通过最大化似然函来找到最有可能生成观测据的模型参。 #### 似然函定义 假设有一个概率分布 \( P(x|\theta) \),其中 \( x \) 是观察到的据样本,\( \theta \) 表示未知参向量。对于独立同分布的样本集合 \( X = \{x_1, x_2, ..., x_n\} \),联合概率可以表示为: \[ L(\theta|X) = \prod_{i=1}^{n} P(x_i | \theta) \] 为了简化计算,通常取对形式得到对似然函: \[ \log(L(\theta|X)) = \sum_{i=1}^{n} \log(P(x_i | \theta)) \][^1] 目标是最优化这个对似然函以求得最优参 \( \hat{\theta} \): \[ \hat{\theta}_{MLE} = \arg\max_\theta \sum_{i=1}^{n} \log(P(x_i | \theta)) \][^1] #### 应用于高斯混合模型中的EM算法 在复杂模型如高斯混合模型(Gaussian Mixture Model, GMM)中,接使用最大似然估计可能遇到局部极值问题或者难以的情况。此时可以通过期望最大化(Expectation-Maximization, EM)算法迭代逼近全局最优。具体过程分为E步(E-step)和M步(M-step),分别完成隐变量的概率推断以及参更新操作。 #### 在深度学习中的应用实例 除了传统统计建模外,最大似然原则也被引入现代神经网络架设计之中。例如,在基于OFDM技术的光通信系统里,研究者提出了利用深度学习框架决LED非线性失真的新案。该论文探讨了一种模型驱动的法,采用端到端训练式最小化重建误差的同时也间接实现了某种意义上的最大似然准则[^2]。 ```python import numpy as np def log_likelihood(theta, data_points): """ 计算给定参下的对似然值 参: theta -- 当前待评估的参集 data_points -- 据集中所有的样本点 返回: 对应于当前参设置的日志可能性总和 """ prob_sum = sum(np.log(probability_density_function(point, theta)) for point in data_points) return prob_sum # 假设 probability_density_function 已经被正确定义好 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值