对OpenCV直方图的数据结构CvHistogram的理解
前几天被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种。
下面的是图片的网址,还有代码。
现在,大家对直方图的维数,应该有一点认识了。现在来说说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的函数内部看看。
对OpenCV直方图的数据结构CvHistogram的理解的更多相关文章
- [EmguCV|WinForm] 使用EmguCV內建直方圖工具繪製直方圖(Histogram)-直方圖(Histogram)系列 (1)
https://dotblogs.com.tw/v6610688/archive/2013/12/20/emgucv_draw_histogram_histogrambox_histogramview ...
- 内存泄露调试之 visual leak detector 工具【转】
本文参考此文:http://kangzj.net/visual-leak-detector-download/ 另外一种检查内存泄露的工具:visual leak detector 简称 vl ...
- 灰度直方算法 C++
#include <string> #include "20140318计算类的面积.cpp" //////////////////////////////////// ...
- Oracle11g自带的SQL developer无法打开解决
在安装完Oracle Database 11g Release 2数据库,想试一下Oracle自带的SQL Developer工具,在操作系统菜单的所有程序中找到SQL Developer如下所示,并 ...
- matplotlib学习日记(四)-绘制直方统计图形
(一)柱状图-应用在定性数据的可视化场景或者离散型数据,条形图和柱状图相似,只不过是函数barh import matplotlib as mpl import matplotlib.pyplot a ...
- R语言与医学统计图形-【14】ggplot2几何对象之直方密度图
ggplot2绘图系统--几何对象之直方图.密度图 1.直方图 参数. geom_histogram(mapping = , data = , stat = 'bin', #统计变换,概率密度为den ...
- 图像特征提取三大法宝:HOG特征,LBP特征,Haar特征(转载)
(一)HOG特征 1.HOG特征: 方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子.它通过计算和 ...
- 图像特征提取三大法宝:HOG特征,LBP特征,Haar特征
(一)HOG特征 1.HOG特征: 方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子.它通过计算和 ...
- MPEG-7 视觉描述符
本文节选自<基于MPEG-7与内容的图像检索技术的研究>. MPEG-7 标准中视觉描述工具包括基本结构和描述符.本文主要介绍各描述符. (1)颜色描述符 MPEG-7 主要定义了七种颜色 ...
随机推荐
- CE 进程同步-事件
事件(event)分为有名的和无名的,使用有名事件的时候,在不同进程中创建的同名事件,其实就是同一个,这样就可以在不同的进程中使用了.两个进程里面都要创建事件,事件名要一致. //进程1 HANDLE ...
- Serializable unordered set
Serializable unordered set 可序列化哈希set #include <boost/algorithm/string/predicate.hpp> #include ...
- golang下的grpc
facebook的thrift也是开源rpc库,性能高出grpc一倍以上,grpc发展的较晚,期待以后有长足的进步.简单来说thrift = grpc + protobuf gRPC基于HTTP/2标 ...
- oracle中TO_CHAR与TO_DATE
TO_CHAR 是把日期或数字转换为字符串TO_DATE 是把字符串转换为数据库中得日期类型转换函数 TO_DATE格式(以时间:2016-07-25 11:45:25为例) Year: yy t ...
- Selenium2入门(二)WebDriver
前文Selenium2入门(一)说到Selenium是Web 应用程序测试框架,那么如果对一个简单的web应用需求:打开浏览器,登录百度首页,输入“欧洲杯”关键词,点击搜索按钮 这一系列操作,能否用S ...
- 15、java中的内部类介绍
内部类顾名思义就是定义在类中的类,下面做一个简单介绍: 内部类的访问规则:1,内部类可以直接访问外部类中的成员,包括私有. 之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式 ...
- 获取广告标识符ifad
#import <AdSupport/ASIdentifierManager.h> NSString *adId =[[[ASIdentifierManager sharedManager ...
- 功能强大的web打印控件lodop的使用
打印是很多web系统都需要的功能,最近找到一款功能强大,使用简单,价格便宜的web打印工具Lodop,免费也能用,不过有水印,也不贵商业开发建议购买. 废话不多说,拿来就用,从简单的打印开始. 1.下 ...
- Linux 忘记root密码 的解决办法
以单用户维护模式登录 先将系统重启, 在读秒时按下任意键进入菜单界面,再仔细看菜单下的说明,按下e就能进入grub的编辑模式,如下 将光标移动到kernel那行, 再次按e进入kernel的编辑界面中 ...
- IComparable<T> Vs. IComparer<T> System.Comparison<T>
Well they are not quite the same thing as IComparer<T> is implemented on a type that is capabl ...