距離変換の最速アルゴリズム


21

距離変換に利用可能な最速のアルゴリズムを探しています。

このサイトhttp://homepages.inf.ed.ac.uk/rbf/HIPR2/distance.htmによると、次のように説明しています。

距離変換は、2つのパス(例、RosenfeldとPfaltz 1968)で巧妙なアルゴリズムを使用して、はるかに効率的に計算できます。

あちこち検索して、「Rosenfeld、A and Pfaltz、J L. 1968. Digital Picturesの距離関数。パターン認識、1、33-61」を見つけました。

しかし、すでに1968年のアルゴリズムよりも優れた高速なアルゴリズムが必要だと思います。実際、1968年のソースを見つけることができなかったので、助けていただければ幸いです。


このスレッドを再度作成して申し訳ありませんが、GDTも実装しようとしていますが、Pythonを使用しています。def of_column(dataInput):output = zeros(dataInput.shape)n = len(dataInput)k = 0 v = zeros((n、))z = zeros((n + 1、))v [0] = 0 z [0] = -inf z [1] = + inf s = 0(範囲(1、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-= 1 else:break k + = 1 v [ k] = qz [k] = sz [k + 1] = + inf k = 0(範囲(n)のqの場合:z [k + 1] <q:k + = 1 output [q] =((q -v [k])*(q-v [k])+ dataInput [v [k]])出力を返すただし、offi
mkli90

新しい質問をしてください。質問を回答として投稿しないでください。
MBaz

Signal Processing SEへようこそ。右上隅の「質問をする」を使用して質問をすることができます。
jojek

回答:


14

Pedro F. FelzenszwalbとDaniel P. Huttenlocherは、距離変換の実装を公開しました。ボリューメトリックイメージには使用できませんが、3Dデータをサポートするために拡張できる場合があります。ブラックボックスとしてのみ使用しました。


これがOpenCVで実装されているかどうか知っていますか?
マットM.

はい、特定の値のためmaskSizedistanceType。参照:opencv.willowgarage.com/documentation/cpp/...を
bjoernz

これまで、体積画像(kinect深度画像など)の実装はありますか?
-zhangxaochen

9

このペーパーでは、現代の正確な距離変換のすべてについて説明します。

「2Dユークリッド距離変換:比較調査」、ACM Computing Surveys、Vol 40、Issue 1、2008年2月 http://www.lems.brown.edu/~rfabbri/stuff/fabbri-EDT-survey-ACMCSurvFeb2008.pdf

この論文は、Meijsterらの技術を引用しています。al。最速の汎用、正確な変換として。この手法の詳細は次のとおりです。

「線形時間で距離変換を計算するための一般的なアルゴリズム」、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の論文による1次元の2乗ユークリッド距離変換の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で、白の値はある程度大きい(画像内で可能な限り最大の2乗距離よりも大きくする必要がありますが、無限ではありません)。

真のユークリッド距離変換を取得するには、出力画像から各ピクセルの平方根を取得するだけです。


面白い。距離変換Liborの一般的な使用法は何ですか?
スペイシー

1
一般的な用途は、パス、セグメンテーション、幾何学的測定(重心)および効果(ベベル効果)を見つけることです。パノラマ画像のステッチに距離変換が必要でした-幾何学的に最適なブレンディングマスクを見つけるために。これには、各画像での距離変換の実行と、重みからのブレンドマスクの計算が含まれます。
-Libor

1
距離変換は、[エッジ]画像のマッチングに使用できます。1つの手法は「面取りマッチング」(umiacs.umd.edu/~mingyliu/papers/liu_cvpr2010.pdf)です。DTを使用して、内側軸(スケルトン)を見つけたり、前述のLiborなどの他のタスクを実行したりすることもできます。
リサンク
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.