cvCalEMD2函数的一点解释

本文详细介绍了Earth Mover's Distance (EMD)的概念及其在解决光线变化引起的图像匹配问题中的应用。通过实例展示了如何使用OpenCV中的cvCalcEMD2函数计算两个直方图之间的EMD值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前段时间cwj649956781说他不理解cvCalEMD2函数作用,因为时间关系,到现在才回复,实在是抱歉!

1.What is EMD?

所谓的EMD实际上就是Earth Mover's Distance的缩写也就是陆地移动距离

2.EMD有何用?

1)原因:

因为光线变化能够导致图像的颜色值漂移,虽然没有改变颜色直方图的形状,但是却改变了颜色值的位置,会导致匹配失败。

2)结果:

所以我们就需要利用EMD来解决这个问题。利用直方图的距离测量来代替直方图的匹配策略,这样仍然可以像直方图对比一样对比两个直方图的距离

3)EMD实质:

实际上就是度量怎么样将一个直方图的形状转换到另一个直方图的形状,包括移动直方图的部分或者全部到一个新的位置,可以在任何维度的直方图上进行度量。


3.如何计算EMD?

opencv中给出了这样的函数,如下所示:

函数:

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

);

1)参数解释:

函数中又许多默认参数了,因此可以简化为

float cvCalcEMD2(

    const CvArr* signature1,

    const CvArr* signature2,

    int          distance_type

);

其中distance_type为距离类型

可以是曼哈顿距离(CV_DIST_L1)

欧氏距离((CV_DIST_L2);

其中signature数组为浮点型

每行包括直方图的bin(形象点说也就是有多少个棍子)以及坐标。

2)关于如何生成signature?

learning opencv中给出了一个例子

给定两个直方图hist1和hist2

如何转换他们为signature?接下来我们借助代码来说明问题。

CvMat* sig1,sig2;

int numrows = h_bins*s_bins;

//用于存放signature的矩阵,注意类型为浮点型

sig1 = cvCreateMat(numrows, 3, CV_32FC1); //1 count + 2 coords = 3

sig2 = cvCreateMat(numrows, 3, CV_32FC1); //sigs are of type float.


for( int h = 0; h < h_bins; h++ ) {

    for( int s = 0; s < s_bins; s++ ) {

        float bin_val = cvQueryHistValue_2D( hist1, h, s );

        cvSet2D(sig1,h*s_bins + s,0,cvScalar(bin_val)); //bin value

        cvSet2D(sig1,h*s_bins + s,1,cvScalar(h));       //Coord 1

        cvSet2D(sig1,h*s_bins + s,2,cvScalar(s));       //Coord 2

        bin_val = cvQueryHistValue_2D( hist2, h, s );

        cvSet2D(sig2,h*s_bins + s,0,cvScalar(bin_val)); //bin value

        cvSet2D(sig2,h*s_bins + s,1,cvScalar(h));       //Coord 1

        cvSet2D(sig2,h*s_bins + s,2,cvScalar(s));       //Coord 2

    }

}

3)计算EMD:

搞定完了signature,接下来就可以计算了

float emd = cvCalcEMD2(sig1,sig2,CV_DIST_L2);

printf(“%f; ”,emd);

所得到的就是距离度量EMD了

4.思考:

实际上EMD这个东西是在光线变化导致的不能匹配的情况下,仍然能够计算出两个直方图之间的关联性,当然是通过emd这个值来度量的。从而达到在光线改变的情况下匹配的效果。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值