Как я могу найти альфа-форму (вогнутый корпус) двумерного облака точек? - PullRequest
19 голосов
/ 26 июля 2011

Я ищу реализацию, которая вычисляет альфа-фигуры в двух измерениях.Я бегу Ubuntu.Я бы предпочел утилиту командной строки для этой задачи, но она также подойдет для библиотеки Python.

В Google я нашел много реализаций, которые вычисляют альфа-фигуры.Но никто из них не выводит то, что я хочу.В качестве входных данных у меня есть список двухмерных точек (например, одна пара с плавающей точкой на строку в текстовом файле).В качестве вывода я хочу получить другой список двумерных точек с той же шкалой .

Я попытался установить последние привязки Python cgal , но они не поддерживаютсячерез некоторое время и больше не компилируется на Ubuntu 11.04 (я тоже пробовал на Ubuntu 10.04 и не повезло). Clustr , проект, разработанный на flickr Аароном Страупом Коупом, также не будет компилироваться в Ubuntu 11.04 (возможно, потому что он также связан с более старыми библиотеками CGAL).

Я также пробовал этореализация от Кена Кларксона в лаборатории Bell.Он выводит почти то, что я хочу, вывод, кажется, в другом масштабе, и он превращается с плавающей точкой в ​​целые числа.

Я также пробовал привязки Python Дионис .Они скомпилированы, но когда я снабдил функцию fill_alpha2D_complex(points, f) списком точек, результат оказался не таким, как я ожидал.Это был не список двумерных точек, а скорее «диаграмма постоянства». Я не знаю, что это значит.

Кто-нибудь знает простое решение этой проблемы?

ОБНОВЛЕНИЕ: Я хочу распечатать точки, связанные с формой альфа, где она находится на грани того, чтобы больше не быть подключенной.Я думаю, что это означает «дать мне точки, связанные с наименьшим альфа-значением, чтобы фигура была связана».

ОБНОВЛЕНИЕ Теперь я узнал, как получить то, что я хочу от Реализация Кена Кларксона и (более или менее то, что я хочу) из реализации Диониса .Реализация Кларксона работала правильно, она просто выводила индексы точек, а не сами точки (та же история с Дионисом), и мне нужно было правильно настроить некоторые необязательные флаги.Оболочка, которую я написал, ниже.Это решение идеально, потому что оно создает альфа-форму, которая соединена и не содержит отверстий.Альфа устанавливается автоматически.Дионис, с другой стороны, не обнаруживает автоматически эти значения альфа.Кроме того, можно настроить реализацию Clarkson для вывода ps-изображения фигуры (с флагом -afps).Чтобы код Кларксона компилировался с не древней версией GCC, вам нужно выполнить шаг, обозначенный здесь .Следующий код можно использовать как библиотеку или как отдельную оболочку:

#!/usr/bin/python -O

import sys, os
import subprocess
import tempfile

hull_path = "./hull.exe"

def get_alpha_shape(points):
    # Write points to tempfile
    tmpfile = tempfile.NamedTemporaryFile(delete=False)
    for point in points:
        tmpfile.write("%0.7f %0.7f\n" % point)
    tmpfile.close()

    # Run hull
    command = "%s -A -m1000000 -oN < %s" % (hull_path, tmpfile.name)
    print >> sys.stderr, "Running command: %s" % command
    retcode = subprocess.call(command, shell=True)
    if retcode != 0:
        print >> sys.stderr, "Warning: bad retcode returned by hull.  Retcode value:" % retcode
    os.remove(tmpfile.name)

    # Parse results
    results_file = open("hout-alf")
    results_file.next() # skip header
    results_indices = [[int(i) for i in line.rstrip().split()] for line in results_file]
#    print "results length = %d" % len(results_indices)
    results_file.close()
    os.remove(results_file.name)

    return [(points[i], points[j]) for i,j in results_indices]

if __name__ == "__main__":
    points = [tuple([float(i) for i in line.rstrip().split()]) for line in sys.stdin]
    for point_i, point_j in get_alpha_shape(points):
        sys.stdout.write("%0.7f,%0.7f\t%0.7f,%0.7f\n" % (point_i[0], point_i[1], point_j[0], point_j[1]))
    sys.exit(0)

1 Ответ

3 голосов
/ 26 июля 2011

Я нашел это в документах Диониса, которые могут дать вам альфа-форму:

complex = Filtration()
fill_alpha2D_complex(points, complex)
alphashape = [s for s in complex if s.data[0] <= .5]

Тогда я считаю, что вам нужно сделать что-то вроде:

for simplex in alphashape:
    print [v for v in simplex.vertices]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...