Как стать автором
Обновить
998.75
OTUS
Цифровые навыки от ведущих экспертов

Преобразование Хафа

Уровень сложностиПростой
Время на прочтение3 мин
Количество просмотров5.5K
Автор статьи: Рустем Галиев

IBM Senior DevOps Engineer & Integration Architect. Официальный DevOps ментор и коуч в IBM

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

Преобразование Хафа — это алгоритм, используемый для поиска геометрических фигур на изображении. На основе искомой формы выбирается определенное количество параметров. Эти параметры необходимы для определения формы. Скажем, для прямой линии y=mx+c у нас есть два параметра. Мы также можем написать линию в форме полярных координат, где два параметра — ро и тета.

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

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

Давайте создадим файл Python, с которым мы будем работать:

touch hough_transform.py

Посмотрим на преобразование Хафа для прямой линии. Для импорта библиотек и входного изображения:

import numpy as np
import cv2
img = cv2.imread('sudoku.jpg')
filtered= cv2.bilateralFilter(img,9,75,75)


Изображение, которое мы импортируем

Вызовем детектор границ Canny и функции HoughLines:

edges = cv2.Canny(filtered,50,200,apertureSize = 3)
lines = cv2.HoughLines(edges,1,np.pi/180,200)

Для вывода найденных строк, если они есть:

for i in range(len(lines[:,0,0])):
	for rho,theta in lines[i]:
    	a = np.cos(theta)
    	b = np.sin(theta)
    	x0 = a*rho
    	y0 = b*rho
    	x1 = int(x0 + 1000*(-b))
    	y1 = int(y0 + 1000*(a))
    	x2 = int(x0 - 1000*(-b))
    	y2 = int(y0 - 1000*(a))
    	cv2.line(img,(x1,y1),(x2,y2),(255,0,0),2)
cv2.imwrite('hough.jpg',img)

Запустим код

python hough_transform.py

Мы получили файл hough.jpg, давайте взглянем на него

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

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

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

Давайте посмотрим на вероятностное преобразование Хафа для нахождения прямых линий:

img = cv2.imread('sudoku.jpg')
filtered= cv2.bilateralFilter(img,9,75,75)
edges = cv2.Canny(filtered,50,200,apertureSize = 3)

Для определения параметров HoughLinesP и вызова HoughLinesP мы используем следующие строки кода:

MinLineLength = 100
MaxLineGap = 10
lines = cv2.HoughLinesP(edges,1,np.pi/180,100,MinLineLength,MaxLineGap)

Для вывода найденных строк, если они есть:

for i in range(len(lines[:,0,0])):
    for x1,y1,x2,y2 in lines[i]:
        cv2.line(img,(x1,y1),(x2,y2),(255,0,0),2)

cv2.imwrite('probab_hough.jpg',img)

Запустим: python hough_transform.py

У нас появится файл probab_hough.jpg

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

Функция HoughCircles в OpenCV имеет множество параметров, поэтому было бы целесообразно обратиться к значениям параметров из документации OpenCV.

Преобразование Хафа для кругов с использованием HoughCircles:

col_img= cv2.imread('circles.jpg')
img = cv2.imread('circles.jpg',0)
filtered= cv2.bilateralFilter(img,9,75,75)

Изображение, которое мы импортируем

Для вызова функции HoughCircles:

circles = cv2.HoughCircles(filtered,cv2.HOUGH_GRADIENT,1,20,param1=55,param2=40,minRadius=0,maxRadius=0)
circles = np.uint16(np.around(circles))

Для вывода найденных кругов:

for i in circles[0,:]:
    cv2.circle(col_img,(i[0],i[1]),i[2],(0,255,0),2)
    #draws the circumference of the circle
    cv2.circle(col_img,(i[0],i[1]),2,(0,0,255),3)
    #draws the centre of the circle

cv2.imwrite('hough_circles.jpg',col_img)

Запустим код: python hough_transform.py 

И получим hough_circles.jpg:

Заключение

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

В завершение расскажу пару слов об открытом уроке, посвященном диффузионным моделям, который пройдет 12 июля. На нем вы узнаете:

  • По каким принципам строится любая диффузионная модель и как устроена популярная генеративная модель Stable Diffusion;

  • Какие задачи можно решать с помощью модели Stable Diffusion.

Записаться на урок можно на странице курса «Компьютерное зрение».

Теги:
Хабы:
Всего голосов 23: ↑15 и ↓8+7
Комментарии4

Публикации

Информация

Сайт
otus.ru
Дата регистрации
Дата основания
Численность
101–200 человек
Местоположение
Россия
Представитель
OTUS