Найшвидший алгоритм дистанційної трансформації


21

Я шукаю найшвидший доступний алгоритм дистанційного перетворення.

За даними цього сайту http://homepages.inf.ed.ac.uk/rbf/HIPR2/distance.htm , він описує:

Перетворення відстані можна обчислити набагато ефективніше, використовуючи розумні алгоритми лише за два проходи (наприклад, Розенфельд і Пфальц 1968).

Шукаючи навколо, я виявив: "Розенфельд, А і Пфальц, Дж. Л. 1968. Функції відстані на цифрових картинках. Розпізнавання візерунків, 1, 33-61."

Але я вважаю, що у нас повинен бути кращий і швидший алгоритм, ніж у 1968 році? Насправді я не зміг знайти джерело з 1968 року, тому будь-яка допомога високо цінується.


Вибачте за те, що я знову налагодив цю тему, але я намагаюся також реалізувати GDT, але використовую Python. def of_column (dataInput): вихід = нулі (dataInput.shape) n = len (dataInput) k = 0 v = нулі ((n,)) z = нулі ((n + 1,)) v [0] = 0 z [0] = -inf z [1] = + inf s = 0 для q в діапазоні (1, n): в той час як 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 else: break k + = 1 v [ k] = qz [k] = sz [k + 1] = + inf k = 0 для q в діапазоні (n): тоді як z [k + 1] <q: k + = 1 вихід [q] = ((q - v [k]) * (q - v [k]) + dataInput [v [k]]) повернути вихід Однак при offeri
mkli90

Будь ласка, задайте нове запитання. Не публікуйте запитання як відповіді.
MBaz

Ласкаво просимо до обробки сигналів SE. Ви можете задати питання, використовуючи "Задати питання" у верхньому правому куті.
jojek

Відповіді:


14

Педро Ф. Фельценсвальб та Даніель П. Гуттенлохер опублікували свою реалізацію для дистанційної трансформації . Ви не можете використовувати його для об'ємних зображень, але, можливо, ви можете розширити його для підтримки 3d-даних. Я використовував це лише як чорний ящик.


Чи знаєте ви, чи реалізовано це у OpenCV?
Метт М.

Так, для певних значень maskSizeта distanceType. Дивіться: opencv.willowgarage.com/documentation/cpp/…
bjoernz

Чи є якісь реалізації для об'ємних зображень (наприклад, зображення глибини кинекта) до цих пір?
zhangxaochen

9

У цьому документі розглядаються всі сучасні точні перетворення відстані:

"2D евклідові дистанційні перетворення: порівняльне опитування", обчислювальні дослідження обліку ACM, том 40, випуск 1, лютий 2008 р. Http://www.lems.brown.edu/~rfabbri/stuff/fabbri-EDT-survey-ACMCSurvFeb2008.pdf

У роботі цитується техніка від Meijster, et. ін. як найшвидше загальне призначення, точне перетворення. Ця методика детально описана тут:

"Загальний алгоритм обчислення дистанційних перетворень у лінійному часі", А. Мейстер, JBTM Roerdink та WH Гесселінк. http://fab.cba.mit.edu/classes/S62.12/docs/Meijster_distance.pdf

Алгоритм Meijster використовується в моїй бібліотеці ефектів з відкритим кодом: https://github.com/vinniefalco/LayerEffects

Я сподіваюся, що це комусь допоможе.


Було б корисно знати, де у вашій бібліотеці ми можемо знайти конкретний код.
акалтар

6

Ось код C # для 1D-евклідового перетворення в квадраті за даними статті Felzenszwald & Huttenlocher :

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, а білі мають деяке велике значення (повинні бути більшими за найбільшу можливу відстань у квадраті на зображеннях, але не нескінченність), щоб перетворення повертало відстань від чорних пікселів, а білі були неміцними.

Щоб отримати справжню евклідову трансформацію відстані, просто візьміть квадратний корінь кожного пікселя з вихідного зображення.


Цікаво. Яке загальне використання перетворення відстані, Лібор?
Спейсі

1
Я думаю, що загальне використання полягає у пошуку шляхів, сегментації, геометричних вимірювань (центр маси) та ефектів (ефект скосу). Мені знадобилося перетворення відстані для панорамного зшивання зображення - щоб знайти геометрично оптимальну суміш масок. Це включало перетворення дистанції бігу на кожному зображенні, а потім обчислення суміші маски з ваг.
Libor

1
Трансформацію відстані можна використовувати для узгодження [крайових] зображень, одна техніка - "узгодження фаски" ( umiacs.umd.edu/~mingyliu/papers/liu_cvpr2010.pdf ). DT також може бути використаний для пошуку медіальної осі (скелета) та для виконання інших завдань, таких як згаданий Лібор.
Rethunk
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.