거리 변환을위한 가장 빠른 알고리즘


21

거리 변환에 가장 빠른 알고리즘을 찾고 있습니다.

이 사이트 http://homepages.inf.ed.ac.uk/rbf/HIPR2/distance.htm 에 따르면 다음을 설명합니다.

거리 변환은 단 두 번의 패스 (예 : Rosenfeld 및 Pfaltz 1968)에서 영리한 알고리즘을 사용하여 훨씬 더 효율적으로 계산 될 수 있습니다.

"Rosenfeld, A and Pfaltz, J L. 1968. Digital Pictures의 거리 기능. 패턴 인식, 1, 33-61."

그러나 나는 우리가 이미 1968 년보다 더 좋고 더 빠른 알고리즘을 가져야한다고 생각합니까? 사실, 나는 1968 년부터 그 출처를 찾을 수 없었으므로 어떤 도움이라도 대단히 감사합니다.


이 스레드를 다시 가져 와서 죄송하지만 GDT도 구현하려고하지만 Python을 사용하고 있습니다. def of_column (dataInput) : 출력 = 0 (dataInput.shape) n = len (dataInput) k = 0 v = 0 ((n,)) z = 0 ((n + 1,)) v [0] = 0 z [0] = -inf z [1] = + inf s = 0 범위 (1, n)에서 q의 경우 : 참 : s = ((((dataInput [q] + q * q)-(dataInput [v [k ]] + v [k] * v [k])) / (2.0 * q-2.0 * v [k])) s <= z [k] : k-= 1 기타 : break k + = 1 v [ 범위 (n)에서 q의 경우 k] = qz [k] = sz [k + 1] = + inf k = 0 : z [k + 1] <q : k + = 1 출력 [q] = ((q -v [k]) * (q-v [k]) + dataInput [v [k]]) 출력 반환 그러나
offeri

새로운 질문을하십시오. 답변으로 질문을 게시하지 마십시오.
MBaz

Signal Processing SE에 오신 것을 환영합니다. 오른쪽 상단의 "질문과 대답"을 사용하여 질문 할 수 있습니다.
jojek

답변:


14

Pedro F. Felzenszwalb와 Daniel P. Huttenlocher가 거리 변환을 위한 구현을 발표했습니다 . 볼륨 이미지에는 사용할 수 없지만 3D 데이터를 지원하도록 확장 할 수 있습니다. 나는 블랙 박스로만 사용했습니다.


이것이 OpenCV에서 구현되는지 알고 있습니까?
Matt M.

예, 특정의 값 maskSizedistanceType. 참조 : opencv.willowgarage.com/documentation/cpp/…
bjoernz

지금까지 체적 이미지 (예 : 키 넥트 깊이 이미지)에 대한 구현이 있습니까?
zhangxaochen

9

이 백서에서는 모든 최신 정확한 거리 변환에 대해 설명합니다.

"2D 유클리드 거리 변환 : 비교 측량", ACM 컴퓨팅 측량, Vol 40, 2008 년 2 월 1 일 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의 논문 에 따르면 1D 제곱 유클리드 거리 변환을위한 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

1
경로, 세분화, 기하학적 측정 (질량 중심) 및 효과 (경사 효과)를 찾는 데 공통적 인 용도가 있다고 생각합니다. 기하학적으로 최적 인 블렌딩 마스크를 찾기 위해 파노라마 이미지 스티칭을위한 거리 변환이 필요했습니다. 여기에는 각 이미지에서 거리 변환을 실행 한 다음 가중치에서 블렌딩 마스크를 계산하는 것이 포함되었습니다.
Libor

1
거리 변환은 [모서리] 이미지 매칭에 사용될 수 있으며, 하나의 기술은 "챔퍼 매칭"( umiacs.umd.edu/~mingyliu/papers/liu_cvpr2010.pdf )입니다. DT는 또한 중간 축 (골격)을 찾고 Libor와 같은 다른 작업을 수행하는 데 사용될 수 있습니다.
Rethunk
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.