Сегодня мы узнаем, как обнаружить линии и круги на изображении с помощью техники, называемой преобразованием Hough.
Что такое пространство Хаф?
Прежде чем мы начнем применять Hough Transfure к изображениям, нам нужно понять, что такое пространство Хаф, и мы узнаем это на пути примера.
Параметр пространство
Когда мы работаем с изображениями, мы можем представить, что изображение является 2D -матрицей над некоторыми координатами x и y, под которым строка можно описать как y + б
Параметр Пространство
Но в пространстве параметров, которое мы будем называть пространством Hough, я могу представлять ту же самую линию, что и m
против b
Вместо этого, таким образом, характеристика линии на пространстве изображения будет одной точкой в положении M-B
в пространстве Хаф.
Hough Space
Но у нас есть проблема, хотя с y + b
, мы не можем представлять вертикальную линию, так как наклон бесконечен. Таким образом, нам нужен лучший способ параметризации, полярные координаты (Rho и Theta).
Хаф
- RHO: описывает расстояние линии от начала
- Тета: описывает угол от горизонтального
Полярные координаты линии
Одно очень важное наблюдение – это то, что происходит, когда мы берем несколько точек вокруг линии, и мы превращаемся в наше пространство Хаф.
Точки и линейное соотношение в пространстве Хаф
Одна точка на пространстве изображений переводится на кривую на пространстве Хаф, с той особенностью, которая указывает на линию на пространстве изображения, будет представлена несколькими кривыми с помощью одной точки отсчета.
И это будет наша цель, найдя точки, где группа кривых пересекается.
Что такое преобразование Хаф?
Преобразование Hough – это метод извлечения признаков для обнаружения простых форм, таких как круги, линии и т. Д. На изображении.
«Простая» характеристика получается с помощью представления формы с точки зрения параметров. «Простая» форма будет представлена только несколькими параметрами, например, линия может быть представлена его наклоном и перехватом, или кружком, который может быть представлен X, Y и Radius.
В нашем примере линии преобразование Хаф будет отвечать за обработку точек на изображении и вычисление значений в пространстве Хаф.
Алгоритм осуществления трансформации и впоследствии поиска пересекающихся кривых немного сложно, и, таким образом, из объема этого поста. Однако мы рассмотрим реализацию этого алгоритма, который является частью OpenCV библиотека.
Обнаружение линий с использованием OpenCV
В OpenCV обнаружение линии с использованием преобразования Hough реализуется в функциях Houghlines
и Houghlinesp
(Вероятностное преобразование Хаф). Мы сосредоточимся на последнем.
Функция ожидает следующих параметров:
Изображение
: 8-битное, одноканальное двоичное исходное изображение. Изображение может быть изменено функцией.строки
: Выходной вектор линий. Каждая строка представлена вектором с 4 элементами (x_1, Y_1, X_2, Y_2), где (x_1, Y_1) и (x_2, Y_2) являются конечными точками каждого обнаруженного сегмента строки.Rho
: Разрешение расстояния аккумулятора в пикселях.Тета
: Угольное разрешение аккумулятора в радианах.порог
: Пороговый параметр аккумулятора. Только эти строки возвращаются, чтобы получить достаточно голосовMinlineLength
: Минимальная длина линии. Линейные сегменты короче, чем те, что отвергаются.maxlinegap
: Максимальный допустимый разрыв между точками на той же строке, чтобы связать их.
Слишком сложно? с примером проще:
# Read image img = cv2.imread('lanes.jpg', cv2.IMREAD_COLOR) # Convert the image to gray-scale gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Find the edges in the image using canny detector edges = cv2.Canny(gray, 50, 200) # Detect points that form a line lines = cv2.HoughLinesP(edges, 1, np.pi/180, max_slider, minLineLength=10, maxLineGap=250) # Draw lines on the image for line in lines: x1, y1, x2, y2 = line[0] cv2.line(img, (x1, y1), (x2, y2), (255, 0, 0), 3) # Show result cv2.imshow("Result Image", img)
И вот результат:
Пример обнаружения строки
Очень важно, чтобы мы фактически использовали только изображение только по краю в качестве параметра для преобразования Хаф, в противном случае алгоритм не будет работать, как предполагалось.
Обнаружение кругов с использованием OpenCV
Процесс идет так же, как и для строк, за исключением того, что на этот раз мы будем использовать другую функцию от библиотеки OpenCV. Мы будем использовать сейчас Houghcircles
, который принимает следующие параметры:
Изображение
: 8-битное, одноканальное, серого входного изображения.Круги
: Выходной вектор найденных кругов. Каждый вектор кодируется как 3-элементный вектор с плавающей запятой (x, y, радиус).Circle_storage
: В функции C это хранилище памяти, которая будет содержать выходную последовательность найденных кругов.Метод
: Метод обнаружения для использования. В настоящее время единственным реализованным методом является cv_hough_gradient, который в основном 21HTDP
: Обратное соотношение разрешения аккумулятора к разрешению изображения. Например, если аккумулятор имеет то же разрешение, что и входное изображение. Если аккумулятор имеет половину большой ширины и высоты.Mindist
: Минимальное расстояние между центрами обнаруженных кругов. Если параметр слишком мал, в дополнение к истинному можно обнаружить несколько соседних кругов. Если он слишком большой, некоторые круги могут быть пропущены.Param1
: Первый метод-специфический параметр. В случае CV_HOUGH_GRAGEIent это более высокий порог из двух, передаваемых к хэпни () детектору края (нижний нижний – в два раза меньше).Param2
: Второй метод, специфичный параметр. В случае CV_HOUGH_GRAGEIent, это порог аккумулятора для центров кружков на стадии обнаружения. Чем меньше это, тем больше ложных кругов может быть обнаружено. Круги, соответствующие большим значениям аккумулятора, будут возвращены первыми.Minradius
: Минимальный радиус круга.Maxradius
: Максимальный радиус круга.
Помните, что параметры должны быть разными, так как мы не можем описать круг с той же параметризацией, которую мы использовали для строк, и вместо этого нам нужно использовать уравнение, подобное (x - x0) ^^ 2 + (y - ^^ 2
.
И коду:
# Read image as gray-scale img = cv2.imread('circles.png', cv2.IMREAD_COLOR) # Convert to gray-scale gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Blur the image to reduce noise img_blur = cv2.medianBlur(gray, 5) # Apply hough transform on the image circles = cv2.HoughCircles(img_blur, cv2.HOUGH_GRADIENT, 1, img.shape[0]/64, param1=200, param2=10, minRadius=5, maxRadius=30) # Draw detected circles if circles is not None: circles = np.uint16(np.around(circles)) for i in circles[0, :]: # Draw outer circle cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2) # Draw inner circle cv2.circle(img, (i[0], i[1]), 2, (0, 0, 255), 3)
Обратите внимание, что по сравнению с предыдущим примером, мы не применяем здесь какую -либо функцию обнаружения краев. Это потому, что функция Houghcircles
имеет встроенное обнаружение.
И результат:
Пример обнаружения круга
Вывод
Hough Transform-отличный метод обнаружения простых форм в изображениях и имеет несколько применений, начиная от медицинских приложений, таких как рентгеновский анализ, CT и MRI-анализ, до автомобилей с самостоятельным управлением. Если вы заинтересованы в том, чтобы узнать больше о пространстве Hough, я рекомендую вам фактически запустить код, попробуйте разные конфигурации самостоятельно, и вы проверяете Документация OpenCV Для получения дополнительной информации.
Спасибо за чтение!
Оригинал: “https://dev.to/livecodestream/understanding-implementing-shape-detection-using-hough-transform-with-opencv-python-n61”