Что делает функция cv2.Canny()?
Функция cv2.Canny() из библиотеки OpenCV реализует алгоритм обнаружения границ, разработанный Джоном Кэнни (John F. Canny) в 1986 году. Этот алгоритм считается одним из самых точных и надёжных методов детектирования краёв на изображениях, благодаря своей способности точно выделять границы при минимальном уровне ложных срабатываний и высокой устойчивости к шуму.
Назначение функции
cv2.Canny() принимает изображение и возвращает бинарную карту, где белыми пикселями (значение 255) обозначаются края (границы), а все остальные пиксели — чёрные (значение 0). Алгоритм работает с градациями серого, поэтому перед вызовом cv2.Canny() цветное изображение нужно преобразовать в grayscale.
Сигнатура функции
edges = cv2.Canny(image, threshold1, threshold2)
Параметры:
-
image — входное изображение (в оттенках серого).
-
threshold1 — нижний порог для гистерезиса.
-
threshold2 — верхний порог для гистерезиса.
Этапы алгоритма Кэнни
Алгоритм состоит из пяти ключевых шагов:
1. Применение фильтра Гаусса
Сначала изображение сглаживается с помощью гауссового размытия, чтобы уменьшить влияние шума.
blurred = cv2.GaussianBlur(gray, (5, 5), 1.4)
2. Вычисление градиента (Sobel)
Рассчитывается горизонтальный и вертикальный градиент яркости изображения с помощью операторов Собеля. Из этих градиентов вычисляется:
-
величина градиента (интенсивность перехода),
-
угол направления границы (ориентация).
Gx = Sobel_x(image)
Gy = Sobel_y(image)
magnitude = sqrt(Gx² + Gy²)
theta = arctangent(Gy / Gx)
3. Подавление немаксимумов (Non-maximum Suppression)
На этом шаге из результата удаляются все пиксели, которые не являются локальными максимумами в направлении градиента. Это делает границы "тонкими" — только 1 пиксель в ширину. Подавляются боковые размазанные границы.
4. Двойная пороговая фильтрация
Используются два порога:
-
threshold2 — высокий порог: пиксели с градиентом выше него считаются "сильными" границами.
-
threshold1 — низкий порог: пиксели между двумя порогами считаются "слабыми".
Пиксели ниже threshold1 отбрасываются. Слабые пиксели сохраняются только в том случае, если они соединены с сильными.
5. Отслеживание по гистерезису
Это ключевое отличие алгоритма Кэнни. Границы "растягиваются" за счёт соединения слабых пикселей с сильными, если они лежат в одном направлении и рядом.
Таким образом, Canny устраняет:
-
одиночные шумовые границы (они не дотягивают до порогов),
-
усиливает и объединяет настоящие границы объектов.
Пример использования
import cv2
image = cv2.imread('image.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
\# Применение детектора Кэнни
edges = cv2.Canny(gray, 100, 200)
cv2.imshow('Edges', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
Подбор порогов
-
Верхний порог должен быть в 2–3 раза выше нижнего.
-
Если threshold1 и threshold2 заданы слишком близко, результат будет "рваным".
-
Слишком высокие пороги дадут лишь самые яркие границы, пропуская тонкие детали.
-
Слишком низкие пороги дадут много ложных срабатываний.
Можно использовать cv2.Canny() в сочетании с автоматической оценкой порогов по гистограмме или cv2.mean()/cv2.medianBlur() для адаптивного выбора значений.
Сравнение с другими детекторами
Метод | Устойчивость к шуму | Точность границ | Локализация | Скорость |
---|---|---|---|---|
Оператор Собеля | Средняя | Низкая | Средняя | Высокая |
--- | --- | --- | --- | --- |
Laplacian | Низкая | Средняя | Средняя | Высокая |
--- | --- | --- | --- | --- |
Canny | Высокая | Очень высокая | Высокая | Средняя |
--- | --- | --- | --- | --- |
Применение в практике
-
Обнаружение контуров объектов — извлечение форм для распознавания.
-
Предварительная обработка перед выделением контуров (cv2.findContours).
-
Сканирование и обработка документов — обнаружение краёв страниц и текста.
-
Видеоанализ — отслеживание движения по границам объектов.
-
Распознавание знаков, лиц, предметов — выделение и анализ ключевых границ.
Комбинации с другими функциями OpenCV
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 1.4)
edges = cv2.Canny(blurred, 50, 150)
\# Поиск контуров после Canny
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
Возможные проблемы
-
Требует ручной настройки порогов.
-
Не работает на изображениях с низкой контрастностью без предварительной коррекции.
-
Может пропускать тонкие или размытые границы, если они не проходят порог.
Функция cv2.Canny() — мощный и гибкий инструмент выделения границ. Она сочетает точную математическую обработку с практической устойчивостью к шуму, что делает её популярным выбором в задачах компьютерного зрения и обработки изображений.