04 декабря 2016

Поиск кругов с помощью OpenCV 3.1.0 в Visual Studio 2015 на С++

Для поиска кругов на изображении в OpenCV используется функция HoughCircles. В этой статье рассмотрен синтаксис и пример применения этой функции.

Прежде чем приступить к изучению этой функции необходимо создать и настроить проект в Visual Studio. Подробную инструкцию по установке и настройке OpenCV для Visual Studio 2015 вы можете найти здесь.

Функция HoughCircles находит круги на черно-белом изображении, используя преобразование Хафа [Подробнее на Википедии].

Теория

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

В нашем случае поиска окружностей радиуса R мы можем считать, что имеем дело с двухпараметрическим семейством кривых
(x-x_{0})^{2}+(y-y_{0})^{2}=R^{2}
и производить поиск максимума аккумуляторной функции A(x,y) в пространстве параметров (x,y). Заметим, что пространство параметров в этом случае практически совпадает с исходным (x,y). Поскольку все центров возможных окружностей радиуса R, проходящих через заданную точку, образует окружность радиуса R с центром в этой точке, функция отклика в преобразовании Хафа для поиска окружностей известного размера представляет собой окружность такого же размера с центром в голосующей точке. Максимум аккумулятора соответствует положению центра окружности на изображении.

Рассмотрим алгоритм обнаружения окружностей заданного радиуса на grayscale изображениях (градации серого), использующий оценку ориентации нормали в голосующих контурных точках. 
Первым шагом является обнаружение пикселей края, окружающих периметр объекта. Например, может использоваться оператор Собела [Википедия], дающий оценку амплитуды и направления градиента. Голосующими контурными точками считаются точки с большим модулем градиента. Для каждого обнаруженного краевого пикселя используется оценка положения и ориентации контура с целью оценки центра кругового объекта радиуса R путем движения на расстояние R от краевого пикселя в направлении нормали к контуру (то есть в направлении вектора-градиента). При повторении этой операции для каждого краевого пикселя, будет найдено множество положений предполагаемых точек центра, которое усредняется для нахождения координат центра.

Принцип обнаружения окружности неизвестного радиуса на полутоновом изображении методом голосования

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

Синтаксис

Как было сказано, функция HoughCircles возвращает окружности, найденные на черно-белом изображении.
Для приложений на C++ синтаксис функции имеет следующий вид:

void HoughCircles(InputArray image, OutputArray circles, int method, double dp, double minDist, double param1=100, double param2=100, int minRadius=0, int maxRadius=0 )

Где параметры обозначают:
  • image – исходное 8-битное, одноканальное изображение в градациях серого.
  • circles – Массив найденных окружностей. Каждый вектор представляет из себя 3-х элементный массив чисел с плавающей точкой (x, y, радиус) .
  • method – Используемый метод нахождения окружностей. На данный момент реализован только метод CV_HOUGH_GRADIENT.
  • dp – Обратное отношение разрешения аккумулятора к разрешению изображения. Например, если dp= 1, то аккумулятор имеет то же разрешение, что и исходное изображение. Если dp = 2, аккумулятор имеет вдвое меньшую ширину и высоту.
  • minDist – Минимальное расстояние между центрами искомых окружностей. Если значение параметра слишком мало, то возможно нахождение нескольких кругов при одном истинном. Если оно слишком велико, некоторые круги могут быть пропущены.
  • param1 – Первый параметр метода. В случае CV_HOUGH_GRADIENT, это более верхний порог из двух для оператора Canny() (детектор края), нижний порог в два раза меньше.
  • param2 – Второй параметр для метода. В случае использования CV_HOUGH_GRADIENT, это пороговое значение аккумулятора для центров окружностей. Чем меньше это значение, тем больше вероятность обнаружения ложных кругов. Круги, соответствующие большим значениям аккумулятора, будут возвращены в первую очередь.
  • minRadius – Минимальный радиус окружности.
  • maxRadius – Максимальный радиус окружности.

Пример


Список литературы