5.14. Гауссове згладжування та межі

Два завдання домінують у використанні сусідних вікон у класичному технічному зорі: чисте згладжування варіацій від пікселя до пікселя та пошук меж там, де зображення різко змінюється. Фільтр Гауса є стандартним інструментом для першого завдання, детектори на основі лапласіана — стандартним інструментом для другого, і вони поєднуються, оскільки кожен детектор меж працює краще на злегка згладженому вхідному сигналі.

5.14.1. Фільтр Гауса

gaussian() — це центрально-зважений варіант mean(). Обидва обчислюють середнє значення в сусідстві кожного пікселя, але ваги Гауса не однорідні: пікселі ближче до центру сусідства враховуються більше, пікселі на краю сусідства — менше, при цьому ваги слідують знайомій кривій дзвоника, яка дала фільтру назву.

Зважування у формі дзвоника робить фільтр Гауса плавнішим, ніж прямокутне усереднення. Усереднення (mean) може створювати видимі артефакти на межах об’єктів — жорстке відсікання вагових коефіцієнтів вносить невеликі ефекти дзвону на різких переходах. Плавно спадаючі ваги Гауса уникають цього дзвону і дають результат, що виглядає ближче до того, яким має бути «розмиття». Вартість — більше обчислень на піксель, ніж у фільтрі усереднення, але не надто — вартість на піксель все ще значно нижча, ніж у двосторонньому фільтрі.

img.gaussian(1)    # 3x3 Gaussian -- a clean light blur
img.gaussian(2)    # 5x5 Gaussian -- stronger smoothing

Гауссове згладжування є стандартним першим етапом майже кожного конвеєра виявлення меж. Детектори меж нижче підсилюють високочастотний вміст, включаючи шум датчика, який алгоритм насправді не хоче виявляти. Попереднє легке гауссове згладжування пригнічує цей шум, не розмиваючи реальних меж, залишаючи детектору меж знаходити справжні межі замість плям.

5.14.2. Нерізке маскування

Гауссово-розмита копія зображення — це вихідний матеріал, який техніка нерізкого маскування використовує для класичного підвищення різкості. Встановлення unsharp=True на фільтрі перемикає його з режиму «отримати розмите зображення» до режиму «відняти розмите зображення від оригіналу та додати різницю назад до оригіналу» — ефект полягає в тому, що високочастотні межі підсилюються відносно рівних внутрішніх областей.

img.gaussian(1, unsharp=True)

Необов’язкові параметри mul та add масштабують силу результату нерізкого маскування; значення за замовчуванням (mul=1.0, add=0.0) є помірним підвищенням різкості, яке не перебільшує шум датчика.

5.14.3. Фільтр лапласіана

laplacian() обчислює дискретне наближення другої просторової похідної зображення. Вихідне значення велике там, де значення пікселів змінюються швидко, і близьке до нуля там, де вони постійні або змінюються лінійно. Природне трактування результату — це відгук на межах: пікселі, де зображення різко змінюється, яскраво виділяються, а пікселі в рівних внутрішніх областях залишаються темними.

img.laplacian(1)   # 3x3 Laplacian -- edge response

Доступні ті самі параметри, що і для gaussian. sharpen=True дає зображення з підвищеною різкістю (лапласіан додається до оригіналу, а не повертається окремо). mul та add масштабують відгук.

Практичне застосування, що виходить за межі виявлення меж, — це вимірювання різкості фокусу. Усереднений відгук лапласіана по регіону дає грубу оцінку кількості високочастотного вмісту в регіоні; у добре сфокусованому кадрі це середнє значення є високим, у розмитому кадрі воно спадає. Порівняння відгуку лапласіана між кадрами — дешевий спосіб відповісти на питання «чи сфокусовано об’єктив?» без необхідності у складнішій метриці контрасту.

5.14.4. Метод find_edges

find_edges() запускає повний конвеєр виявлення меж, а не просто фільтр відгуку на межах. Він працює на зображеннях у відтінках сірого, і результатом є бінарне зображення, ненульові пікселі якого позначають позиції, де вхідне зображення має такий тип зміни яскравості, який слід вважати межею.

Метод приймає параметр edge_type, що вибирає між двома алгоритмами:

EDGE_SIMPLE запускає фільтр верхніх частот, застосовує поріг і повертає результат. Швидкий, але вивід включає будь-яку зміну яскравості вище порогу, включаючи шум і текстуру, які застосунок, мабуть, не цікавлять. Підходить для чистих зображень і випадків, де шум буде очищено пізнішим морфологічним проходом.

EDGE_CANNY запускає детектор меж Canny — класичний багатоетапний алгоритм. Він обчислює градієнт яскравості, пригнічує всі не-максимальні відгуки вздовж напрямку градієнта (тому кожна межа має ширину в один піксель) і застосовує пороговий гістерезис (тому межа, що є сильною в одному місці, простежується навіть там, де вона слабшає). Результат — чистий, тонкий, зв’язний набір пікселів меж, якого прагне кожен класичний алгоритм на основі меж.

Параметр threshold — це кортеж з двох елементів (low, high). Для EDGE_CANNY значення high — це граничне значення, вище якого піксель однозначно є межею, а значення low — граничне значення, вище якого піксель є межею тільки якщо він з’єднаний з однозначною межею. Для EDGE_SIMPLE важливе лише значення high: це єдиний поріг, вище якого піксель вважається межею. Значення за замовчуванням (100, 200) є відправною точкою, яку варто налаштовувати для конкретної сцени.

img.gaussian(1)                                   # pre-smooth
img.find_edges(image.EDGE_CANNY, threshold=(50, 100))

Детектор Canny є кращим вибором для майже кожного застосунку, де важливі межі. Швидший EDGE_SIMPLE варто пам’ятати для випадків, де вартість Canny є проблемою, а відхилення шуму його гістерезису насправді не потрібне.

5.14.5. Адаптивний поріг на Гаусі

Як і статистичні фільтри, gaussian() приймає пару ключових слів threshold=True / offset=N для адаптивного порогу. Поведінка така сама, як і з mean(): статистика Гауса в кожній позиції стає локальним порогом, і вихідний піксель порівнюється зі статистикою плюс зміщення для отримання бінарного результату.

Варіант Гауса зазвичай є найчистішим вибором для адаптивного порогу, коли вхідний сигнал відносно вільний від шуму. Зважене середнє дає плавніший поріг, ніж фільтр усереднення, з меншою кількістю артефактів на різких переходах освітленості.