Соедините точки - соедините линию между точками контура - PullRequest
4 голосов
/ 16 августа 2010

У меня серое изображение размером 64x64.Я нашел точки контура по простому алгоритму:

  • найти самое яркое пятно (Пример: 100)
  • разделить на 2 (100/2 = 50)
  • определить полосу вокруг результата (50-5 = 45 до 50 + 5 = 55)
  • отметить все точки, которые имеют значение в полосе (от 45 до 55)

Теперь возникает вопрос, как мне определить порядок соединения точек?

(все ссылки будут приняты, ссылки, мысли и т. Д.)

Ответы [ 6 ]

4 голосов
/ 16 августа 2010

Ваш алгоритм позволяет всему изображению, за исключением одного пикселя, быть "контуром". Я не уверен, что это именно то, что вы хотите; обычно контуром является граница между двумя разными областями. Проблема с вашим методом заключается в том, что вы можете получить огромные капли пикселей, у которых нет особенно очевидного порядка обхода. Если у вас есть контур толщиной в один пиксель, то порядок обхода гораздо более очевиден: по часовой стрелке или против часовой стрелки.

Рассмотрим следующее изображение.

........
..%%%%..
.%%%%...
...%%%%.
....%...
........

Здесь я пометил все «темное» (возможно, <50) как <code>% и все светлое как .. Теперь вы можете выбрать любой пиксель, который находится на границе между двумя областями (я выберу темную сторону; вы также можете нарисовать контур на светлой стороне или, немного потрудившись, непосредственно между светлой и темной сторонами. ) * +1010 *

........
..%%%%..
.*%%%...
...%%%%.
....%...
........

Теперь вы пытаетесь путешествовать по внешнему краю темной области, по одному пикселю за раз. Сначала вы смотрите в направлении чего-то яркого (например, прямо влево). Затем вы вращаетесь вокруг - скажем, против часовой стрелки - пока не достигнете темного пикселя.

........
..%%%%..
1*5%%...
234%%%%.
....%...
........

Как только вы попали в позицию 5, вы видите, что темно. Таким образом, вы помечаете его как часть контура, а затем пытаетесь найти следующий фрагмент на контуре, проводя вокруг, начиная с пикселя, с которого вы только что пришли

........
..%%%%..
.0*%%...
.123%%%.
....%...
........

Здесь 0 - это то, откуда вы пришли - и вы туда не вернетесь - и затем вы пробуете пиксели 1 и 2 (оба света, что не очень хорошо), пока вы не нажмете на пиксель 3, что темно.

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

........
..@@@@..
.@@%@...
...@%@@.
....@...
........

(У вас должен быть этот критерий «два в ряд» или если у вас темная область шириной в один пиксель, вы пройдете по ней вверх, но затем не сможете вернуться по ней.)

На данный момент вы покрыли одну всю границу. Но могут быть и другие. Продолжайте искать темные пиксели рядом со светлыми, пока вы не нарисуете контур поверх всех из них. Теперь вы преобразовали свое двухуровневое изображение (темные и яркие пиксели) в набор контуров.

Если контуры заканчиваются слишком шумно, сначала подумайте о размытии изображения. Это сгладит контуры. (В качестве альтернативы вы можете сначала найти контуры, а затем усреднить координаты с помощью движущегося окна.)

1 голос
/ 24 декабря 2010

Я также попытался создать алгоритм, который соединит точки контура в гладкую кривую.См. Мой проект с открытым исходным кодом http://outliner.codeplex.com. Идея та же, что предложена FUZxxl, но я не понимаю его беспокойство по поводу сложности: время обработки пропорционально общей длине всех штрихов контура.

1 голос
/ 16 августа 2010

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

Например, рассмотрим набор из 5 точек, состоящий из углов квадрата и его центра.Эти точки могут быть соединены, чтобы сформировать квадрат с одной стороной, "вмятиной" в центр.Но с какой стороны?Единственного ответа нет.

Другие фигуры могут быть намного сложнее, без очевидного способа соединения точек.

Если вам разрешено уменьшить набор точек до выпуклая оболочка , тогда было бы намного проще.

0 голосов
/ 05 ноября 2010

См. Также Flood fill и прекрасный апплет под SO mapping-a-branching-tile-path .

0 голосов
/ 16 августа 2010

Может быть попробовать:

  1. Начните с
  2. Найти ближайшую точку b
  3. Соедините с B
  4. и т. Д.

Вероятно, не очень хорошо, так как сложность - это что-то вроде O (n²). Вы можете упростить это, глядя только на точки в начале, как советует aioobe. Этот алгоритм хорош, если точки находятся на расстоянии 2-3 пикселя друг от друга, но могут создавать очень странные сетки.

0 голосов
/ 16 августа 2010

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

Как насчет того, чтобы перейти к самой яркой точке.Перейдите к точке яркости, скажем, 360 точек вокруг этой точки на расстоянии, скажем, 5 пикселей.Продолжайте оттуда, но убедитесь, что вы не вернетесь туда, откуда пришли :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...