Автор статьи: Рустем Галиев

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

Всем привет. Сегодня поговорим про обнаружение границ с использованием градиентов.
Мы рассмотрим, как найти границы между двумя объектами или двумя частями объекта на изображении с помощью OpenCV. Очень важно найти очертания фигур, чтобы в конечном итоге создать сложную программу, например программу для распознавания лиц.

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

Из реквизита нам нужен python, openCV и вот такая картинка Моны Лизы:

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

Основываясь на такой интуиции, OpenCV находит градиент изображения с помощью различных методов, таких как градиенты Собеля, Шарра и Лапласа. Градиент показывает интенсивность скорости изменения значений пикселей при перемещении по изображению. Градиент высокий на краях и острых точках. Давайте создадим файл python, с которым мы будем работать:

touch edge_detection.py

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

Давайте воспользуемся градиентным фильтром Собеля, который находит градиент Собеля для каждого пикселя:

import numpy as np
import cv2
img_o=cv2.imread('mona_lisa.jpg',0)
cv2.imwrite('mona_lisa.jpg',img_o)
img = cv2.bilateralFilter(img_o,9,25,25)

Для вызова функции Собеля и сохранения изображения градиента для просмотра:

sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5)
sobel_sum=sobelx/2+sobely/2
cv2.imwrite('gradient.jpg',sobel_sum)


Выполним:

python edge_detection.py

Взглянем на gradient.jpg, чтобы просмотреть изображение градиента.

Используя функцию Собеля, мы рассчитали изменения по осям X и Y. Затем объединили изменения, чтобы получить градиентное изображение для портрета Моны Лизы.

Лапласианский градиентный фильтр

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

Однако он дает более четкие результаты, чем фильтр Собеля:

laplacian = cv2.Laplacian(img,cv2.CV_64F)
cv2.imwrite('laplace_gradient.jpg',laplacian)


Выполним

python edge_detection.py

Посмотрим на laplace_gradient.jpg, посмотрим изображение градиента Лапласа.

Если мы найдем изображение лапласианского градиента для зашумленного изображения Моны Лизы, увидим, насколько лапласовский градиент чувствителен к шуму:

img_o2=cv2.imread('noise_mona_lisa.jpg',0)
img2 = cv2.bilateralFilter(img_o2,9,25,25)
laplacian2 = cv2.Laplacian(img2,cv2.CV_64F)
cv2.imwrite('noisy_laplacian.jpg',laplacian2)

Выполним: python edge_detection.py

Результат выполнения: noisy_laplacian.jpg

Теперь мы переходим к обнаружению границ Кэнни. Из-за уязвимости градиента Лапласа к шуму, функция обнаружения краев Кэнни использует градиент Собеля.

Он подавляет пиксели в градиентном изображении, которые не являются локально максимальными по отношению к соседним пикселям. Таким образом, наше изображение градиента Собеля очищается, и выделяются только крайние пиксели, которые локально максимальны по отношению к соседним пикселям:

edges = cv2.Canny(img,100,200)
cv2.imwrite('canny.jpg',edges)

Выполняем python edge_detection.py

Результат canny.jpg



Хотите стать специалистом по компьютерному зрению и глубокому обучению? Сделайте свои первые шаги, а если вы уже опытный специалист, то узнайте как перейти с PyTorch 1.x на 2.0 на открытом уроке онлайн-курса «Компьютерное зрение». На занятии обсудим что нового принес фреймворк PyTorch 2.0 в сферу компьютерного зрения и глубокого обучения.

Комментарии (3)


  1. SomeAnonimCoder
    29.06.2023 06:00
    +1

    А сейчас я вам покажу как вызвать в питоне функции, дока на которые есть в инете. Чем они отличаются друг от друга? Как они работают? - А зачем вам это, суть статьи же не в том чтобы что-то понять, а в том чтобы набрать рейтинга


  1. iig
    29.06.2023 06:00
    -1

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

    touch edge_detection.py

    Самый странный способ создавать питоновские скрипты ;) Под windows тоже работает?

    Ну да, функция чего-то вернула. И что с этим градиентом массивом пикселей делать то?


  1. slupoke
    29.06.2023 06:00

    Рассмотрим градиентные фильтры Собеля и Лапласа

    А где сами фильтры то?

    Он подавляет пиксели в градиентном изображении, которые не являются локально максимальными по отношению к соседним пикселям. Таким образом, наше изображение градиента Собеля очищается, и выделяются только крайние пиксели, которые локально максимальны по отношению к соседним пикселям:

    edges = cv2.Canny(img,100,200)
    cv2.imwrite('canny.jpg',edges)

    Очень информативно.