2009-12-14 2 views
22

У меня есть набор K случайно выбранных пикселей в 2D-изображении. Для каждого другого пикселя в изображении мне нужно выяснить, какой пиксель в множестве K ближе всего к нему (используя стандартную меру расстояния sqrt (dx^2 + dy^2)). Я знаю, что для каждого пикселя может быть несколько решений. Очевидно, это может быть сделано грубой силой против каждого пикселя в наборе, но я бы предпочел избежать этого, поскольку он неэффективен. Любые другие хорошие предложения?Ближайшая точка к заданной точке

Cheers.

ответ

31

Не забывайте, что вам не нужно беспокоиться о квадратном корне.

Если вы просто хотите найти ближайший (а не фактическое расстояние), просто используйте dx^2 + dy^2, что даст вам квадрат расстояния к каждому пункту, что так же полезно.

Если у вас нет структуры данных, обертывающей этот список пикселей вверх, вам нужно просто протестировать их все.

Если у вас есть определенная гибкость, есть множество хороших способов сокращения рабочей нагрузки. Сделайте Quadtree или сохраните отсортированный список пикселей (отсортированный по x и отсортированный по y), чтобы быстрее сократить ваш поиск.

+0

хорошее мнение! для больших наборов данных это значительно сократило бы время выполнения. –

+1

Поскольку вы имеете дело с пикселями, это также означает, что вы можете перейти к целочисленным математикам, что является еще одним огромным бонусом скорости. –

+9

@rikh. Даже если вам нужно расстояние, вы всегда можете сделать «sqrt», как только вы узнаете, какая точка ближайший. –

5

Это называется поиском ближайшего соседа. Дональд Кнут назвал это проблемой почтового отделения.

Существует ряд решений: линейный поиск, чувствительность к местоположению, файлы векторных приближений и разбиение пространства.

Путь к ним должен помочь.

1

В зависимости от того, насколько плотно это изображение заполнено пикселями, вам может быть лучше просто искать внешний вид вашего пикселя происхождения.

Я запрограммировал что-то подобное для эмуляции графического терминала. То, что я закончил, это программирование шаблона поиска в форме прямоугольной спирали, которая выросла из центральной точки, и я позволил ей расти, пока она не ударила. Это было достаточно быстро для этой цели, даже на старом процессоре.

+0

Для одной точки мой алгоритм «достаточно хорош». Для всей группы Вороной звучит как победитель. Я бы отменил свой ответ, за исключением того, что некоторые будущие читатели могли иметь одноточечное требование. –

4

Другая подсказка: расстояние всегда больше или равна каждой разности координат, и всегда меньше или равна их сумме, т.е.

d >= dx, d >= dy, d <= dx + dy. 

Это может помочь вам делать сортировку более эффективно.

5

, что вы пытаетесь сделать, это построить voronoi diagram это может быть сделано в O (N журнал N), используя plane sweep

7

Строительство Voronoi Diagrams является филиалом Computational Geometry. Конструкция Delaunay Triangulations включает в себя аналогичные соображения. Возможно, вы сможете адаптировать одно из следующих Delaunay algorithms в соответствии с вашими потребностями.

  • алгоритмы Раскладные
  • Инкрементальный
  • разделяй и властвуй
  • Sweepline
6

Поместите очки в KD дерево, после этого очень быстро найти ближайшего соседа.См. Статью this о википедии.

14

Должен согласиться с jk и Ewan с составлением Voronoi Diagram. Это разделит пространство в многоугольниках. Каждая точка в K будет иметь многоугольник, описывающий все точки, которые ближе всего к нему. Теперь, когда вы получаете запрос точки, вам нужно найти, в каком полигоне она лежит. Эта проблема называется Point Location и может быть решена путем построения Trapezoidal Map.

jk уже связан с созданием Voronoi Diagram с использованием Fortune's algorithm, который принимает вычислительные шаги O (n log n) и затраты O (n) пространства. This website показывает вам, как сделать трапециевидную карту и как ее запросить. Вы также можете найти некоторые оценки там:
Ожидаемое время создания: O (N журнал N)
Ожидаемое пространство сложность: O (п)

Но самое главное, ожидаемое время запроса: O (журнал N). Это (теоретически) лучше, чем O (√ n) kD-дерева.

Мой источник (кроме ссылок выше): Computational Geometry: algorithms and applications, главы шесть и семь.

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

Смежные вопросы