Обнаружение края / угол

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

В настоящее время я беру крайние точки черного края и вычисляю угол с помощью функции atan2, но из-за наложения псевдонимов в зависимости от выбранной точки угол может иметь некоторую степень вариации. Есть ли надежный программируемый способ выбора точек для расчета угла?

Пример изображения:

Wonky Checker доска

Например, угол инструмента Gimp Measure при 3,12 °,

Gimp Измерительный инструмент

1

Решение

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

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

Я попытался предоставить простую сводку по поиску преимуществ в этом старом посте SO:
Какая связь между краями изображения и градиентом?

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

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

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

  1. Выполните несколько итераций эрозии черных пикселей, чтобы отделить черные ящики друг от друга.
  2. Запустите алгоритм связанных компонентов (алгоритм поиска BLOB-объектов), чтобы найти размытые черные квадраты.
  3. Определите центральную (x, y) точку каждого размытого квадрата, а также (x, y) конечные точки, определяющие большую и меньшую оси.
  4. Сохраните данные для каждого квадрата в структуре, которая имеет общую площадь в пикселях, центральную точку (x, y), точки (x, y) большой и малой осей и т. Д.
  5. При необходимости удалите все слишком маленькие компоненты (капли). Например, вы хотите исключить все шумовые капли «соль и перец». Вы также можете временно игнорировать квадраты шахматной доски, обрезанные по краям изображения — мы можем вернуться к ним позже.

Затем вы переберите свой список больших двоичных объектов и выполните следующие действия для каждого большого двоичного объекта:

  1. Определите направление примерно перпендикулярно краям шахматного квадрата. То, как вы это сделаете, частично зависит от того, какие данные вы рассчитываете при запуске алгоритма подключенных компонентов. В библиотеке обработки изображений общего назначения стандартный алгоритм связанных компонентов будет определять десятки свойств и измерений для каждого отдельного большого двоичного объекта: площадь, округлость, направление большой оси, направление вспомогательной оси, конечные точки большой и вспомогательной оси и т. Д. прямоугольных фигур, может быть достаточно рассчитать самые верхние, самые левые, самые правые и самые нижние точки, так как они будут определять четыре угла.
  2. Создайте сканирование краев в направлении, перпендикулярном краям. Это должно быть выполнено на оригинальный, неизмененный образ. Обычно это предполагает, что у вас реализована билинейная интерполяция, чтобы найти значения градаций серого для точек субпикселя (x, y), таких как (100.35, 25.72), так как линии сканирования не будут попадать точно на целые пиксели.
  3. Используйте технику нахождения краевой точки субпикселя. В общем случае вы будете выполнять подгонку кривой к краевым точкам в направлении сканирования, а затем найдете реальную (x, y) точку с максимальным градиентом. Это крайний момент.
  4. Сохраните все подпиксельные граничные точки в списке / массиве / коллекции.
  5. Генерация линии соответствует краевым точкам. Они могут использовать Hough, RANSAC, метод наименьших квадратов или другие методы.
  6. Из линейных уравнений для каждого из четырех подходов линии рассчитайте угол наклона линии.

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

  • Морфология изображения (например, разрушать, расширять, закрывать, открывать, …)
  • Операции ядра для реализации морфологии
  • Пороговое значение для бинаризации изображения — метод Оцу стоит проверить
  • Алгоритм связанных компонентов (поиск BLOB-объектов или функция контуров OpenCV)
  • Структура данных для BLOB-объектов
  • Расчет моментов для данных BLOB-объектов
  • Билинейная интерполяция для поиска значений субпикселя (x, y)
  • Метод линейного сканирования лучей для определения (x, y) значений серого вдоль определенного направления (которое также будет опираться на билинейную интерполяцию)
  • Техника подбора кривой и средство для определения самой крутой касательной для нахождения краевых точек
  • Надежная техника посадки линий: Hough, RANSAC и / или наименьших квадратов
  • Структура данных для линейного уравнения, связанных функций

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

  1. Простая основанная на ядре методика поиска краевых точек (лапласиан на сглаженном по Гауссу изображении)
  2. Прямая линия, подходящая к краям
  3. Выберите две подгонки строк с наибольшим количеством голосов, которые должны быть одним набором линий горизонтальной черты и другим набором линий вертикальной черты

Есть и другие методы, которые менее точны, но проще в реализации:

  1. Используйте основанный на ядре оператор поиска углов
  2. Найти углы между угловыми точками.

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

3

Другие решения

Могу я спросить, какую библиотеку C ++ вы используете для написания этого кода?

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

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

Как только это будет сделано, вы можете использовать алгоритм поиска пути, чтобы найти какое-либо ребро, подойдет любое ребро. Если вы найдете более или менее прямой путь, вы можете использовать крайние точки, как вы делаете сейчас, чтобы определить угол. Поскольку поворот шахматной доски имеет значение только в пределах 90 градусов, ваш угол должен быть по модулю 90 градусов или пи на 2 радиана.

0

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

Найти угол для каждого, а затем интерполировать между двумя углами.

0

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

  1. Найдите угол наклона каждого квадрата. У вас есть как минимум 9 квадратов на изображении, по 4 линии в каждом квадрате, что дает вам 36 углов (18 будет примерно при 3 °, а 18 будет ~ 93 °). Снимите 90 градусов, и вы получите 36 различных измерений угла. Сортируйте их и возьмите среднее значение среднего 30 (без учета 3 меньших и 3 более высоких измерений). Это даст вам точный результат
  2. Второе решение, найдите крайнюю левую точку самого левого квадрата и крайнюю правую точку самого правого квадрата. Теперь посчитайте угол между ними. Результат будет намного более точным, потому что точки находятся далеко.
  3. Третий алгоритм, который даст вам точные результаты, потому что он не включает в себя поиск каких-либо точек и не требует пороговых значений. Просто сгладьте изображение, рассчитайте градиенты по осям X и Y (gx,gy), рассчитать угол наклона градиента в каждом пикселе atan(gy,gx) и составить гистограмму углов. У вас будет 2 значительных пика около 3 и 93 градусов. Просто найдите вершины путем поиска максимума в гистограмме. Это будет работать, даже если у вас много шума на изображении, даже с сглаживанием и артефактами jpg, и даже если у вас есть другие рисунки на изображении. Но помните, вы должны сильно сгладить изображение, прежде чем вычислять производные.
0
По вопросам рекламы [email protected]