标签:
一、概述
直方图广泛应用于很多计算机视觉应用中。通过标记帧与帧之间显著的边缘和颜色的统计变化,直方图被用来检测视频中场景的变换。直方图是计算机视觉中最经典的工具之一。
直方图就是对数据进行统计,将统计值组织到一系列事先定义好的bin中。bin中的数值是从数据中计算出的特征的统计量,这些数据可以是诸如梯度、方向、色彩或任何其他特征。直方图获得的是数据分析的统计图。通常直方图的维数要低于原始数据。
二、直方图的基本数据结构
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;
直方图的很多内部数据都被存储于CvMatND结构中。
三、直方图相关的函数
1. 创建直方图
CvHistogram* cvCreateHist( int dims, int* sizes, int type, float** ranges=NULL, int uniform=1 );
dims
直方图维数的数目
sizes
直方图维数尺寸的数组
type
直方图的表示格式: CV_HIST_ARRAY 意味着直方图数据表示为多维密集数组 CvMatND; CV_HIST_TREE 意味着直方图数据表示为多维稀疏数组 CvSparseMat.
ranges
图中方块范围的数组. 它的内容取决于参数 uniform 的值。这个范围的用处是确定何时计算直方图或决定反向映射(backprojected ),每个方块对应于输入图像的哪个/哪组值。
uniform
归一化标识。 如果不为0,则ranges[i](0<=i<cDims,译者注:cDims为直方图的维数,对于灰度图为1,彩色图为3)是包含两个元素的范围数组,包括直方图第i维的上界和下界。在第i维上的整个区域 [lower,upper]被分割成 dims[i] 个相等的块(译者注:dims[i]表示直方图第i维的块数),这些块用来确定输入象素的第 i 个值(译者注:对于彩色图像,i确定R, G,或者B)的对应的块;如果为0,则ranges[i]是包含dims[i]+1个元素的范围数组,包括lower0,
upper0, lower1, upper1 == lower2, ..., upperdims[i]-1, 其中lowerj 和upperj分别是直方图第i维上第 j 个方块的上下界(针对输入象素的第 i 个值)。任何情况下,输入值如果超出了一个直方块所指定的范围外,都不会被 cvCalcHist 计数,而且会被函数 cvCalcBackProject 置零。
函数 cvCreateHist 创建一个指定尺寸的直方图,并且返回创建的直方图的指针。 如果数组的 ranges 是 0, 则直方块的范围必须由函数 cvSetHistBinRanges 稍后指定。虽然 cvCalcHist 和 cvCalcBackProject 可以处理 8-比特图像而无需设置任何直方块的范围,但它们都被假设等分 0..255 之间的空间。
2. 清除直方图
void cvClearHist( CvHistogram* hist );
参数说明
hist 直方图.
函数 cvClearHist 当直方图是稠密数组时将所有直方块设置为 0,当直方图是稀疏数组时,除去所有的直方块。
3. 释放直方图结构
void cvReleaseHist( CvHistogram** hist );
参数说明
hist 被释放的直方图结构的双指针.
函数 cvReleaseHist 释放直方图 (头和数据). 指向直方图的指针被函数所清空。如果 *hist 指针已经为 NULL, 则函数不做任何事情。
4. 从数组中创建直方图
CvHistogram* cvMakeHistHeaderForArray( int dims, int* sizes, CvHistogram* hist,
float* data, float** ranges=NULL, int uniform=1 );
参数说明:
dims 直方图维数.
sizes 直方图维数尺寸的数组
hist 为函数所初始化的直方图头
data 用来存储直方块的数组
ranges 直方块范围,见 cvCreateHist.
uniform 归一化标识,见 cvCreateHist.
函数 cvMakeHistHeaderForArray 初始化直方图,其中头和直方块为用户所分配。以后不需要调用 cvReleaseHist 只有稠密直方图可以采用这种方法,函数返回 hist.
5. 归一化直方图
void cvNormalizeHist( CvHistogram* hist, double factor );
参数说明:
hist 直方图的指针.
factor 归一化因子
函数 cvNormalizeHist 通过缩放来归一化直方块,使得所有块的和等于 factor.
6. 对直方图取阈值
void cvThreshHist( CvHistogram* hist, double threshold );
参数说明:
hist 直方图的指针.
threshold 阈值大小
函数 cvThreshHist 清除那些小于指定阈值得直方块
7. 拷贝直方图
void cvCopyHist( const CvHistogram* src, CvHistogram** dst );
参数说明:
src 输入的直方图
dst 输出的直方图指针
函数 cvCopyHist 对直方图作拷贝。如果第二个直方图指针 *dst 是 NULL, 则创建一个与 src 同样大小的直方图。否则,两个直方图必须大小和类型一致。然后函数将输入的直方块的值复制到输出的直方图中,并且设置取值范围与 src 的一致。
8. 获取最大最小直方图
void cvGetMinMaxHistValue( const CvHistogram* hist, float* min_value, float* max_value,
int* min_idx=NULL, int* max_idx=NULL );
参数说明:
hist 直方图
min_value 直方图最小值的指针
max_value 直方图最大值的指针
min_idx 数组中最小坐标的指针
max_idx 数组中最大坐标的指针
函数 cvGetMinMaxHistValue 发现最大和最小直方块以及它们的位置。任何输出变量都是可选的。在具有同样值几个极值中,返回具有最小下标索引(以字母排列顺序定)的那一个。
9. 比较两个稠密直方图
double cvCompareHist( const CvHistogram* hist1, const CvHistogram* hist2,
int method );
参数说明:
hist1 第一个稠密直方图
hist2 第二个稠密直方图
method 比较方法,采用其中之一:
函数 cvCompareHist 采用下面指定的方法比较两个稠密直方图(H1 表示第一个,H2表示第二个):
对于相关(Correlation),数值越大则越匹配。完全匹配的数值为1,完全不匹配是-1,值为0则表示无关联。
对于卡方,低分比高分匹配的匹配程度高。完全匹配的值为0,完全不匹配为无无限值。
对于直方图相交,高分表示好匹配,而低分则表示坏匹配。如果两个直方图都被归一化到1,则完全匹配是1,完全不匹配是0。
对于距离匹配,低分数表示好匹配,而高分数表示坏匹配。完全匹配是0,完全不匹配是1。
四种匹配方式中,在快速但不怎么精确匹配的情况下,inersection方法的效果好。而在慢速但较精确的情况下,用 chi-square 或 Bhattacharyya 方法的效果好。EMD方法给出最直观的匹配,但更慢一些。
10. 两个加权点集之间计算最小工作距离
float cvCalcEMD2( const CvArr* signature1, const CvArr* signature2, int distance_type,
CvDistanceFunction distance_func=NULL, const CvArr* cost_matrix=NULL,
CvArr* flow=NULL, float* lower_bound=NULL, void* userdata=NULL );
typedef float (*CvDistanceFunction)(const float* f1, const float* f2, void* userdata);
signature1
第一个签名,大小为 size1×(dims+1) 的浮点数矩阵,每一行依次存储点的权重和点的坐标。矩阵允许只有一列(即仅有权重),如果使用用户自定义的代价矩阵。
signature2
第二个签名,与 signature1 的格式一样size2×(dims+1),尽管行数可以不同(列数要相同)。当一个额外的虚拟点加入 signature1 或 signature2 中的时候,权重也可不同。
distance_type
使用的准则, CV_DIST_L1, CV_DIST_L2, 和 CV_DIST_C 分别为标准的准则。 CV_DIST_USER 意味着使用用户自定义函数 distance_func 或预先计算好的代价矩阵 cost_matrix 。
distance_func
用户自定义的距离函数。用两个点的坐标计算两点之间的距离。
cost_matrix
自定义大小为 size1×size2 的代价矩阵。 cost_matrix 和 distance_func 两者至少有一个必须为 NULL. 而且,如果使用代价函数,下边界无法计算,因为它需要准则函数。
flow
产生的大小为 size1×size2 流矩阵(flow matrix): flowij 是从 signature1 的第 i 个点到 signature2 的第 j 个点的流(flow)。
lower_bound
可选的输入/输出参数:两个签名之间的距离下边界,是两个质心之间的距离。如果使用自定义代价矩阵,点集的所有权重不等,或者有签名只包含权重(即该签名矩阵只有单独一列),则下边界也许不会计算。用户必须初始化 *lower_bound.
如果质心之间的距离大于获等于 *lower_bound (这意味着签名之间足够远), 函数则不计算 EMD. 任何情况下,函数返回时 *lower_bound 都被设置为计算出来的质心距离。因此如果用户想同时计算质心距离和T EMD, *lower_bound 应该被设置为 0.
userdata
传输到自定义距离函数的可选数据指针
函数 cvCalcEMD2 计算两个加权点集之间的移动距离或距离下界。所描述的其中一个应用就是图像提取得多维直方图比较。 EMD 是一个使用某种单纯形算法(simplex algorithm)来解决的交通问题。其计算复杂度在最坏情况下是指数形式的,但是平均而言它的速度相当快。对实的准则,下边界的计算可以更快(使用线性时间算法),且它可用来粗略确定两个点集是否足够远以至无法联系到同一个目标上。
11. 计算反向投影
void cvCalcBackProject( IplImage** image, CvArr* back_project, const CvHistogram* hist );
image
输入图像 (也可以传递 CvMat** ).
back_project
反向投影图像,与输入图像具有同样类型.
hist
直方图
函数 cvCalcBackProject 计算直方图的反向投影. 对于所有输入的单通道图像同一位置的象素数组,该函数根据相应的象素数组(RGB),放置其对应的直方块的值到输出图像中。用统计学术语,输出图像象素点的值是观测数组在某个分布(直方图)下的概率。 例如,为了发现图像中的红色目标,可以这么做: 对红色物体计算色调直方图,假设图像仅仅包含该物体。则直方图有可能有极值,对应着红颜色。 对将要搜索目标的输入图像,使用直方图计算其色调平面的反向投影,然后对图像做阈值操作。 在产生的图像中发现连通部分,然后使用某种附加准则选择正确的部分,比如最大的连同部分。
这是 Camshift 彩色目标跟踪器中的一个逼进算法,除了第三步,CAMSHIFT 算法使用了上一次目标位置来定位反向投影中的目标。
标签:
原文地址:http://blog.csdn.net/tiemaxiaosu/article/details/51016102