Новости и статьи об искусственном интеллекте и нейросетях. Мы собираем и обрабатываем самую актуальную информацию из мира AI. О проекте

Статьи

Обнаружение особенностей: Лаплас и Гаусс

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

13 ноября 2025 г.
12 мин
1

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

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

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

Края расположены в зонах значительного изменения интенсивности пикселей. В этом примере края можно обнаружить у границы самолета и облаков.
Края расположены в зонах значительного изменения интенсивности пикселей. В этом примере края можно обнаружить у границы самолета и облаков.

Иными словами, края выявляются по пикам минимума/максимума первой производной функции интенсивности, которая отображается на изображении в центре.

Вторая производная изображения

Вернемся к приведенному примеру и подумаем, что произойдет при вычислении второй производной. Ответ представлен на правом графике ниже. В этом случае пики минимума/максимума первой производной соответствуют нулям второй производной.

Значения интенсивности вдоль оси X (изображение слева). Первая производная (изображение в центре): локальные экстремумы указывают на край. Вторая производная (изображение справа): область пересечения нуля указывает на край. Изображение адаптировано автором. Источник: Laplace Operator (OpenCV documentation).
Значения интенсивности вдоль оси X (изображение слева).
Первая производная (изображение в центре): локальные экстремумы указывают на край.
Вторая производная (изображение справа): область пересечения нуля указывает на край.
Изображение адаптировано автором. Источник: Laplace Operator (OpenCV documentation).

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

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

Определение

Оператор Лапласа формально задается следующей формулой:

Формула Лапласа
Формула Лапласа

Как видно, оператор Лапласа представляет собой сумму вторых производных по направлениям x и y.

Оператор Лапласа не дает сведений о направлении края.

Дискретное приближение

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

Предположим, что для участка изображения ниже требуется рассчитать значение Лапласа для пикселя I₂₂. Вычислим производную по направлению оси X.

В этом примере требуется приближение Лапласа для центрального пикселя I₂₂
В этом примере требуется приближение Лапласа для центрального пикселя I₂₂

Для этого дважды применим формулу производной из предыдущей статьи, выбрав значения Δx: -1 и 1. Получим:

  • Для Δx = -1: dI / dx = I₂₃ – I₂₂
  • Для Δx = 1: dI / dx = I₂₂ – I₂₁

Для расчета первой производной мы вычисляем разность между соседними пикселями. Аналогично можно поступить со второй производной, которую неформально можно рассматривать как разность разностей.

Таким образом, возьмем две разности, только что рассчитанные, и найдем их разность. Более формально, это эквивалентно применению стандартной формулы производной с Δx = -1. Итог:

  • d2I / dx = (I₂₃ – I₂₂) – (I₂₂ – I₂₁) = I₂₃ – 2I₂₂ + I₂₁

Отлично! Мы вычислили вторую производную по направлению X. Аналогичная процедура для второй производной по направлению Y даст выражение:

  • d2I / dy = (I₃₂ – I₂₂) – (I₂₂ – I₁₂) = I₃₂ – 2I₂₂ + I₁₂

Наконец, остается сложить обе производные. Результат:

  • d2I / dx + d2I / dy = I₁₂ + I₂₁ + I₂₃ + I₃₂ – 4I₂₂

Весь процесс вычисления Лапласа можно визуализировать на диаграмме ниже:

Получение формулы для расчета Лапласа в дискретном случае
Получение формулы для расчета Лапласа в дискретном случае

На основе полученного результата можно сформировать свертный ядро 3×3 для оператора Лапласа:

Ядро Лапласа
Ядро Лапласа

Интересный факт: сумма элементов этого ядра равна 0, что означает, если входное изображение постоянно, то применение фильтра даст матрицу с нулевыми элементами. Это логичный исход, поскольку изменений интенсивности нет.

В отличие от ядер Собеля и Шарра, ядро Лапласа фиксирует изменения интенсивности в обоих направлениях. Достаточно применить ядро 3×3 к любому изображению, и оператор Лапласа выдаст скалярные значения, отражающие изменения интенсивности.

Напоминание: для операторов Собеля и Шарра ядра применялись отдельно по осям X и Y, после чего вычислялись их модули.

Обнаружение диагональных краев

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

Поэтому ядро выше обычно немного модифицируют для учета диагонального направления. Один из распространенных вариантов — использование следующего ядра:

Альтернатива ядру Лапласа, симметричная по горизонтали, вертикали и диагонали
Альтернатива ядру Лапласа, симметричная по горизонтали, вертикали и диагонали.

Изотропность

Матрица Лапласа симметрична, что делает ее изотропной. Изотропность — это свойство, при котором ядро инвариантно к повороту, то есть результат применения изотропного фильтра к изображению и его повернутой версии совпадает.

Шум

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

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

Если шум присутствует, ситуация может выглядеть как на диаграмме ниже.

Учитывая наличие шума на входном изображении (слева), значения интенсивности вдоль оси X вызывают колебания, затрудняющие анализ первой производной (справа) и, соответственно, второй.
Учитывая наличие шума на входном изображении (слева), значения интенсивности вдоль оси X вызывают колебания, затрудняющие анализ первой производной (справа) и, соответственно, второй.

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

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

Гауссов фильтр

Гауссов фильтр — это способ подавления шума на изображении, позволяющий применять оператор Лапласа или другой инструмент обнаружения краев без ограничений.

Формально распределение Гаусса задается формулой ниже (где μ = 0):

Формула Гаусса. μ — среднее (в нашем случае μ = 0), σ — стандартное отклонение, которое настраивается для конкретной задачи.
Формула Гаусса. μ — среднее (в нашем случае μ = 0), σ — стандартное отклонение, которое настраивается для конкретной задачи.

Функция Гаусса g(x) изображена на верхнем правом графике ниже:

Верхний левый: функция интенсивности. Верхний правый: функция Гаусса. Нижний левый: произведение интенсивности и функций Гаусса. Нижний правый: производная произведения.
Верхний левый: функция интенсивности.
Верхний правый: функция Гаусса.
Нижний левый: произведение интенсивности и функций Гаусса.
Нижний правый: производная произведения.

Умножение функции интенсивности I(x) на гауссову g(x) приводит к общему сглаживанию интенсивности, что упрощает анализ. Пример показан на нижнем левом диаграмме.

Благодаря гладкой форме функции можно вычислить первую производную, точки экстремумов которой укажут на края (нижний правый диаграмма).

Производная Гаусса

Вычисление первой производной изображения — линейная операция, поэтому вычисления можно разложить следующим образом:

Вместо расчета производной произведения можно предварительно вычислить производную Гаусса и умножить ее на функцию интенсивности; результат будет тем же, но с меньшими вычислениями.
Вместо расчета производной произведения можно предварительно вычислить производную Гаусса и умножить ее на функцию интенсивности; результат будет тем же, но с меньшими вычислениями.

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

Лапласиан Гаусса

Аналогичный прием применим ко второй производной, о которой говорилось в начале статьи для обнаружения краев. В итоге вторую производную Гаусса вычисляют заранее и умножают на функцию интенсивности. Результат на нижнем правом графике:

Верхний левый: функция интенсивности. Верхний правый: функция Гаусса. Нижний левый: вторая производная функции Гаусса (известна как перевернутый мексиканский сомбреро). Нижний правый: произведение второй производной Гаусса и функции интенсивности.
Верхний левый: функция интенсивности.
Верхний правый: функция Гаусса.
Нижний левый: вторая производная функции Гаусса (известна как перевернутый мексиканский сомбреро).
Нижний правый: произведение второй производной Гаусса и функции интенсивности.

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

Вторая производная Гаусса (нижнее левое изображение) часто называется перевернутым «мексиканским сомбреро» из-за высокой схожести формы с шляпой сомбреро.

OpenCV

После изучения теории обнаружения краев с помощью вторых производных изображения пора рассмотреть, как реализовать фильтры Лапласа в OpenCV.

Лапласиан Гаусса

Сначала импортируем необходимые библиотеки и загрузим входное изображение:

import cv2
import numpy as np
import matplotlib.pyplot as plt

Будем использовать пример изображения с несколькими монетами:

Входное изображение
Входное изображение

Прочитаем изображение:

image = cv2.imread('data/input/coins.png')
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

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

Как обсуждалось ранее, перед применением оператора Лапласа сначала используем гауссов фильтр:

image = cv2.GaussianBlur(image, (7, 7), 0)
  • Второй параметр (7, 7) обозначает размер ядра.
  • Третий параметр определяет стандартное отклонение σ из формулы Гаусса выше. Здесь оно установлено в 0, что позволяет OpenCV автоматически выбрать σ на основе размера ядра.

Теперь можно применить фильтр Лапласа:

laplacian_signed = cv2.Laplacian(image, cv2.CV_16S, ksize=3)

Здесь тип выхода указан как cv2.CV_16S, эквивалентный типу short с диапазоном значений [-32768, 32767]. Это необходимо, поскольку фильтр Лапласа может генерировать значения за пределами стандартного интервала пикселей [0, 255]. Без этого значения вывода обрезались бы до [0, 255], и информация потерялась бы.

OpenCV предоставляет удобную функцию для преобразования сырого вывода Лапласа (или других результатов) в стандартный диапазон [0, 255]:

laplacian_absolute = cv2.convertScaleAbs(laplacian_signed)

Переменная laplacian_absolute имеет ту же форму, что и laplacian_signed, но с значениями, обрезанными до [0, 255]. Преобразование выполняется функцией cv2.convertScaleAbs() таким образом, чтобы сохранить информацию о пересечениях нуля:

  • Значения с абсолютной величиной больше 255 обрезаются до 255.
  • Для значений от -255 до 255 берется абсолютное значение.
Функция cv2.convertScaleAbs() отображает значения пикселей в интервал [0, 255].
Функция cv2.convertScaleAbs() отображает значения пикселей в интервал [0, 255].

Обнаружение пересечения нуля

К сожалению, документация OpenCV демонстрирует только пример применения Лапласа, но не показывает, как использовать результаты для обнаружения краев по пересечению нуля. Ниже приведен простой фрагмент кода для этого:

laplacian_sign = np.sign(laplacian_signed)
zero_crossings = np.zeros_like(laplacian_sign, dtype=bool)
for shift in [-5, 5]:
    zero_crossings |= (np.roll(laplacian_sign, shift, axis=0) * laplacian_sign < 0)
    zero_crossings |= (np.roll(laplacian_sign, shift, axis=1) * laplacian_sign < 0)
threshold = 20
edges = np.uint8(zero_crossings & (np.abs(laplacian_signed) > threshold)) * 255

Простыми словами, мы создаем переменную zero_crossings, которая хранит информацию о том, является ли пиксель в позиции (x, y) кандидатом на пересечение нуля. В коде пиксель считается пересечением нуля, если его знак (+ или -) отличается от знака любого сдвинутого пикселя на пять позиций в горизонтальном или вертикальном направлении.

Можно выбрать другой константу сдвига (не обязательно 5) или комбинировать несколько, а также учитывать диагональные сдвиги.

Чтобы исключить нерелевантные пересечения нуля, оставляем только те, абсолютное значение Лапласа которых превышает заданный порог (20).

Визуализация

Наконец, отобразим изображения, полученные в ходе анализа:

plt.figure(figsize=(12, 4))
plt.subplot(1, 3, 1)
im1 = plt.imshow(laplacian_signed, cmap='gray', vmin=laplacian_signed.min(), vmax=laplacian_signed.max())
plt.title("Laplacian (signed)")
plt.axis('off')
plt.colorbar(im1, fraction=0.05, pad=0.05, label='Pixel value')
plt.subplot(1, 3, 2)
im2 = plt.imshow(laplacian_absolute, cmap='gray', vmin=laplacian_absolute.min(), vmax=laplacian_absolute.max())
plt.title("Laplacian (absolute)")
plt.axis('off')
plt.colorbar(im2, fraction=0.05, pad=0.05, label='Pixel value')
plt.subplot(1, 3, 3)
im2 = plt.imshow(edges, cmap='gray', vmin=edges.min(), vmax=edges.max())
plt.title("Edges from zero-crossings")
plt.axis('off')
plt.colorbar(im2, fraction=0.05, pad=0.05, label='Pixel value')
plt.tight_layout()
plt.show()

Вот результат вывода:

Вывод после применения фильтров Лапласа. Правое изображение бинарное (содержит только пиксели со значениями 0 или 255).
Вывод после применения фильтров Лапласа. Правое изображение бинарное (содержит только пиксели со значениями 0 или 255).

Как видно, края успешно обнаружены на правом бинарном изображении. Следующим шагом может стать применение метода OpenCV cv2.findContours() для выявления контуров и дальнейшего их анализа.

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

Заключение

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

Ресурсы