直方图与匹配

一、概述

       直方图广泛应用于很多计算机视觉应用中。通过标记帧与帧之间显著的边缘和颜色的统计变化,直方图被用来检测视频中场景的变换。直方图是计算机视觉中最经典的工具之一。

       直方图就是对数据进行统计,将统计值组织到一系列事先定义好的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   比较方法,采用其中之一:

  • CV_COMP_CORREL
  • CV_COMP_CHISQR
  • CV_COMP_INTERSECT
  • CV_COMP_BHATTACHARYYA

  函数 cvCompareHist 采用下面指定的方法比较两个稠密直方图(H1 表示第一个,H2表示第二个):

  • 相关Correlation (method=CV_COMP_CORREL):

     

     

    对于相关(Correlation),数值越大则越匹配。完全匹配的数值为1,完全不匹配是-1,值为0则表示无关联。

  • 卡方Chi-square(method=CV_COMP_CHISQR):

     

                  

    对于卡方,低分比高分匹配的匹配程度高。完全匹配的值为0,完全不匹配为无无限值。

  • 交叉 (method=CV_COMP_INTERSECT):

               

    对于直方图相交,高分表示好匹配,而低分则表示坏匹配。如果两个直方图都被归一化到1,则完全匹配是1,完全不匹配是0。

     

  • Bhattacharyya 距离 (method=CV_COMP_BHATTACHARYYA):

                 

    对于距离匹配,低分数表示好匹配,而高分数表示坏匹配。完全匹配是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 算法使用了上一次目标位置来定位反向投影中的目标。

     

     

     

     

     

     

     


     

     

     

     

     



     

     

     

     

     

     

     

     

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值