最快的距离变换算法


21

我正在寻找距离转换最快的可用算法。

根据此站点http://homepages.inf.ed.ac.uk/rbf/HIPR2/distance.htm,它描述了:

使用聪明的算法仅需两遍就可以更有效地计算距离变换(例如Rosenfeld和Pfaltz 1968)。

到处搜寻,我发现:“ Rosenfeld,A和Pfaltz,J.L。1968。数字图片上的距离函数。模式识别,1,33-61。”

但是我相信我们应该有一个比1968年更好,更快的算法吗?实际上,我找不到1968年的消息来源,因此非常感谢您的帮助。


很抱歉再次启动此线程,但是我也尝试使用Python实现GDT。def of_column(dataInput):输出=零(dataInput.shape)n = len(dataInput)k = 0 v =零((n,))z =零((n + 1,))v [0] = 0 z对于范围(1,n)中的q,[0] = -inf z [1] = + inf s = 0:而True:s =((((dataInput [q] + q * q)-(dataInput [v [k ]] + v [k] * v [k]))/(2.0 * q-2.0 * v [k]))如果s <= z [k]:k-= 1否则:打破k + = 1 v [对于范围(n)中的q,k] = qz [k] = sz [k + 1] = + inf k = 0:而z [k + 1] <q:k + = 1 output [q] =((q -v [k])*(q-v [k])+ dataInput [v [k]])返回输出但是,Offeri
mkli90 2016年

请问一个新问题。不要发布问题作为答案。
MBaz

欢迎使用信号处理SE。您可以使用右上角的“提问”来提问。
jojek

Answers:


14

Pedro F. Felzenszwalb和Daniel P. Huttenlocher已发布了距离转换的实现。您不能将其用于体积图像,但是也许可以扩展它以支持3d数据。我只是将其用作黑匣子。


您是否知道这是否在OpenCV中实现?
Matt M.

是的,对某些价值观maskSizedistanceType。请参阅:opencv.willowgarage.com/documentation/cpp/...
bjoernz

到目前为止,是否有任何体积图像(例如kinect深度图像)的实现?
zhangxaochen

9

本文讨论了所有现代精确距离变换:

“ 2D欧式距离变换:比较调查”,ACM计算调查,第40卷,第1期,2008年2月, http://www.lems.brown.edu/~rfabbri/stuff/fabbri-EDT-survey-ACMCSurvFeb2008.pdf

该论文引用了Meijster等人的技术。等 作为最快的通用目标,进行精确转换。此处详细介绍了此技术:

A. Meijster,JBTM Roerdink和WH Hesselink的“用于计算线性时间距离变换的通用算法”。 http://fab.cba.mit.edu/classes/S62.12/docs/Meijster_distance.pdf

我的开源效果库中使用了Meijster算法:https//github.com/vinniefalco/LayerEffects

我希望这可以帮助别人。


了解在您的库中可以找到特定代码的位置很有用。
akaltar

6

这是根据Felzenszwald&Huttenlocher的论文的一维平方欧几里德距离变换的C#代码:

private static void DistanceTransform(double[] dataInput, ref double[] dataOutput)
{
    int n = dataInput.Length;

    int k = 0;
    int[] v = new int[n];
    double[] z = new double[n + 1];

    v[0] = 0;
    z[0] = Double.NegativeInfinity;
    z[1] = Double.PositiveInfinity;

    double s;

    for (int q = 1; q < n; q++)
    {
        while (true)
        {
            s = (((dataInput[q] + q * q) - (dataInput[v[k]] + v[k] * v[k])) / (2.0 * q - 2.0 * v[k]));

            if (s <= z[k])
            {
                k--;
            }
            else
            {
                break;
            }
        }

        k++;

        v[k] = q;
        z[k] = s;
        z[k + 1] = Double.PositiveInfinity;
    }

    k = 0;

    for (int q = 0; q < n; q++)
    {
        while (z[k + 1] < q)
        {
            k++;
        }

        dataOutput[q] = ((q - v[k]) * (q - v[k]) + dataInput[v[k]]);
    }
}

通过将其首先应用于图像列然后应用于行(当然反之亦然),可以轻松地将其用于二进制和灰度图像。

转换确实非常快。

这是源图像和输出图像:

在此处输入图片说明

在此处输入图片说明

黑色像素的值为0,白色像素的值较大(必须大于图像中最大的平方距离,但不能大于无穷远),以便变换返回与黑色像素的距离,而白色像素则被忽略。

要获得真正的欧几里德距离变换,只需从输出图像中获取每个像素的平方根即可。


有趣。Libor距离变换的常见用法是什么?
Spacey 2012年

1
我认为常见的用途是查找路径,分割,几何尺寸(质心)和效果(斜角效果)。我需要进行距离转换以进行全景图像拼接-以找到几何上最佳的混合蒙版。这涉及到对每幅图像的行驶距离变换,然后根据权重计算混合蒙版。
Libor

1
距离变换可用于匹配[edge]图像,一种技术是“倒角匹配”(umiacs.umd.edu/~mingyliu/papers/liu_cvpr2010.pdf)。DT还可以用于查找中间轴(骨骼)并执行其他任务,例如提到的Libor。
Rethunk 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.