Как найти 4 точки рядом с пересечением двух линий
предположим, у меня есть некоторые растровые данные (в черном), над которыми некоторые линии были нарисованы вручную в векторном формате (в зеленом). Линии примерно повторяют форму растровых данных. В некоторых местах линии пересекаются.
Итак, что я пытаюсь сделать, зная положение пересечения зеленых линий, как я могу найти положение A, B, C и D?
см. ниже некоторые примеры:
Я не уверен, как подойти к этой проблеме учитывая случайное расположение линий, и иногда они даже не находятся внутри черной формы. Однако, я думаю, должен быть какой-то способ. Есть предложения?
7 ответов
самый простой подход, который я могу придумать, это:
- изображение, чтобы удалить "зеленую линию". Простым подходом было бы использовать какое-то утончение, которое заполняет цвет фона соседних пикселей.
теперь у вас должно быть изображение, которое состоит только из черных (широких) линий и белого фона.
фильтруйте изображение снова, используя алгоритм обнаружения угла, например Гаррис детектор. Это даст вам четыре угла.
Примечания:
в зависимости от входных данных вы можете получить более четырех углов. В любом случае неплохо проверить, что четыре угла, которые вы извлекли, действительно являются возможными углами пересечения.
опять же, это довольно грубый подход, но если входные данные такие же чистые, как на ваших примерах изображений, и расстояние между зелеными линиями и черные линии не слишком большие, я думаю, это может сработать.
Я полагаю, вы знаете, как получить координаты (x,y)
пересечения (зеленой) векторной линии, поэтому я оставлю эту часть.
начиная с пикселя, ближайшего к (x,y)
, постепенно маршировать наружу в квадратной спирали (или какой-либо другой шаблон поиска по своему вкусу) от пикселя к пикселю. На каждом шаге проверьте, находитесь ли вы на черном пикселе с одним и только одним белым Мур сосед. Если да, то место, где черный пиксель и его белый сосед соприкасаются (вероятно, общий угол) - одна из ваших точек (назовите ее A). Продолжайте идти, пока не найдете еще три (B,C, D). Это будут четыре такие точки, ближайшие к зеленому пересечению , которые будут отлично работать в четырех примерах, показанных в вашем вопросе.
однако этот алгоритм потерпит неудачу, если зеленое пересечение находится на полпути между двумя черными пересечениями; в этом случае он будет смешивать точки с обоих черных пересечений. Если вас это беспокоит, то как только вы нашли точку а, повторно инициируете свою походную спираль, на этот раз с центром на А, и маршируете, пока не найдете В, С, D. Это, по сути, "щелкнет" к ближайшему черному пересечению.
вы можете добавить больше ума, чтобы избежать поиска в одной и той же области дважды; повторно инициировать или перефокусировать шаблон поиска, как только вы нашли B и еще раз, как только вы нашли C и т. д... Зависит от того, насколько вы хотите/должны получить.
строки.
кстати, это как-то связано с дорогами?
Итак, выключите зеленые линии. После этого возьмите небольшой квадрат, как и любой из 4 из вышеперечисленных, пока вы не пройдете через все из них, и ищите те, которые имеют максимум черного/белого соотношение пикселей. Это должны быть те, у кого"перекресток". Сопоставляя эти черные пиксели, граничащие с белыми пикселями, вы должны иметь границы дороги/поля. После этого определить эти точки будет непросто.
Как я уже сказал, предположение. Интересная проблема-интересно, что придумают знающие парни.
сначала вам нужно извлечь ребра из исходного изображения, чтобы получить полигоны, которые описывают черно-белую границу.
затем вы перебираете точки ребер тезисов и вычисляете точечное расстояние до точки пересечения двух зеленых линий. Четыре наименьших расстояния приходят от точек, которые вы ищете.
вы получили ответ на ваш вопрос ? Или я что-то не так понял ?
Если вы хотите только 4 угла, вам не нужно зеленая линия: просто возьмите границы от извлечения края, сгладьте затем с помощью фильтра Савицкого-Голея и вычислите точечную кривизну. Просто извлеките точки с максимальной кривизной.
вам нужна векторизация бинарного растра. Наш университетский проект был прав по теме -Corners Toolbox позволяет обрабатывать двоичные изображения в сжатом виде (Не путайте название - "сжатый" здесь означает, что двоичное изображение сначала преобразуется в связанные списки так называемых углов).
1) преобразование изображения в углы (см. Главу 4 приведенной выше ссылки). Затем вы можете использовать линейную интерполяцию угловых точек (глава 5.5) - вы бы измените наш алгоритм, чтобы увидеть большие изменения наклона (~ 90 градусов) в больших частях линий.
2) вам не нужна зеленая линия. Вы можете использовать алгоритм скелетирования, чтобы найти скелет черной части (см. главу 5.4) и интерполировать этот скелет линиями (см. главу 5.5 приведенной выше ссылки).
Если вы заинтересованы в проекте, я могу спросить коллег, можем ли мы предоставить исходный код.
самый простой способ-скелетизация. Сначала отделите зеленое и черно-белое изображение. Запустите алгоритм скелета (довольно простая морфологическая операция, также в OpenCV) на обоих изображениях и определите точки пересечения (можно сделать с помощью простого 8-соседнего подсчета пикселей в скелетных изображениях: то есть для каждого черного пикселя подсчитайте, сколько пикселей связано горизонтально, вертикально или диагонально, и если это значение >= 4, это пересечение). Теперь сделайте ближайший сосед матч для этих скелетонизированных точек, и вы сделали.
вы должны быть в состоянии найти точку, где зеленые линии пересекаются, а также среднюю точку, где черные линии пересекаются процессом эрозии (сжимаются до точек). Затем используйте алгоритм ближайшей пары точек, чтобы найти, какие черные линии пересекаются с пересечением зеленой линии.
затем вы можете выполнить поиск вдали от точки пересечения черных линий. Вам понадобится приоритетная очередь, которая будет обрабатывать точки в соответствии с их расстоянием от точка пересечения черных линий, ближайшая первая. Поместите четыре смежные точки на пересечение черных линий в очереди. Для каждой точки в очереди вы захотите проверить, является ли она белым пикселем (мы хотим их), проверить, что она не посещалась раньше (пропустить в этом случае), а затем добавить четыре соседних пикселя в очередь. Первые четыре белых пикселя должны быть теми, которые вы хотите (при условии, что у вас был хороший метод скелетирования/сжатия для поиска пересечения), но вы должны действительно возьмите белые пиксели, пока не получите первые четыре найденных, которые не соседствуют друг с другом.