Як реалізується розмиття Гаусса?


42

Я читав, що розмиття робиться в графіці в реальному часі, роблячи це на одній осі, а потім на іншій.

У минулому я робив трохи згортки в 1D, але мені це не дуже комфортно, і не знаю, що саме в цьому випадку слід робити.

Чи може хто-небудь пояснити простими словами, як робиться 2D розмиття Гаусса зображення?

Я також чув, що радіус розмиття може вплинути на продуктивність. Це пов'язано з тим, що потрібно зробити більшу згортку?

Відповіді:


48

За згодом дві математичні функції поєднуються для отримання третьої функції. У функції обробки зображень зазвичай називають ядрами. Ядро - це не що інше, як (квадратний) масив пікселів (невелике зображення, так би мовити). Зазвичай значення в ядрі складаються до одного. Це робиться для того, щоб після операції зображення не додавались і не знімалися.

Зокрема, ядро ​​Гаусса (використовується для розмиття Гаусса) - це квадратний масив пікселів, де значення пікселів відповідають значенням кривої Гаусса (у 2D).

Зображення пов'язане з http://homepages.inf.ed.ac.uk/rbf/HIPR2/gsmooth.htm

Кожен піксель у зображенні множиться на ядро ​​Гаусса. Це робиться шляхом розміщення центрального пікселя ядра на пікселі зображення та множення значень у вихідному зображенні на пікселі в ядрі, що перекриваються. Значення, отримані в результаті цих множень, додаються, і цей результат використовується для значення в пікселі призначення. Дивлячись на зображення, ви помножили б значення на (0,0) у вхідному масиві на значення в (i) в масиві ядра, значення на (1,0) у вхідному масиві на значення at (h) ) у масиві ядра тощо. а потім додайте всі ці значення, щоб отримати значення для (1,1) на вихідному зображенні.

Зображення пов'язане з http://www.songho.ca/dsp/convolution/convolution.html

Щоб відповісти на ваше друге питання спочатку, чим більше ядро, тим дорожча операція. Отже, чим більший радіус розмиття, тим довше буде тривати операція.

Щоб відповісти на ваше перше питання, як було пояснено вище, згортання можна зробити, помноживши кожен вхідний піксель на все ядро. Однак якщо ядро ​​симетричне (яким є ядро ​​Гаусса), ви можете також множити кожну вісь (x і y) незалежно, що зменшить загальну кількість множень. У правильному математичному плані, якщо матриця відокремлена, її можна розкласти на (M × 1) та (1 × N) матриці. Для ядра Гаусса вище це означає, що ви також можете використовувати такі ядра:

1256[1464141624164624362464162416414641]=1256[14641][14641]

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

Для отримання додаткової інформації про те, як дізнатись, чи відокремлено ядро, перейдіть за цим посиланням .

Редагувати: два ядра, показані вище, використовують дещо різні значення. Це тому, що параметр (sigma), який використовується для кривої Гаусса для створення цих ядер, в обох випадках дещо відрізнявся. Для пояснення того, які параметри впливають на форму кривої Гаусса, і, таким чином, значення ядра переходять за цим посиланням

Редагувати: на другому зображенні вище написано, що ядро, яке використовується, перевернуте. Це, звичайно, має значення лише в тому випадку, якщо ядро, яке ви використовуєте, не симетричне. Причина, по якій вам потрібно перевернути ядро, пов'язана з математичними властивостями операції згортання ( більш детальне пояснення щодо згортання див. У посиланні ). Простіше кажучи: якщо ви не перевернете ядро, результат операції згортання буде перевернутий. Перегортаючи ядро, ви отримуєте правильний результат.


1
Чи можете ви додати коротку примітку, щоб пояснити, чому два різних ядра 5 на 5 мають дещо різні числа (одне підсумовує 273, інше підсумовує 256)? Здається, це потенційна плутанина для когось нового в цьому.
трихоплакс

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

Не забувайте працювати в лінійному кольоровому просторі для отримання правильних результатів.
v.oddou

16

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

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

Отже, для розміру ( ) вам потрібно лише оцінити значень ( ), що значно менше. Якщо ваша операція полягає в читанні текстурного елемента (зазвичай його називають "краном" ), це хороша новина: менше натискань дешевше, оскільки отримання текстури має вартість.n×nO(n2)2×nO(n)

Ось чому алгоритми розмивання використовують цю властивість, роблячи два проходи, один для розмивання по горизонталі шляхом збору горизонтальних пікселів, а другий для розмивання вертикально шляхом збирання вертикальних пікселів. Результат - остаточний розмитий колір пікселя.nn


13

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

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

У нашому дискретному контексті ми можемо помножити два наші сигнали, просто помноживши кожен відповідний зразок. Інтеграл також просто зробити дискретно, ми просто додаємо кожен зразок в інтервал, через який ми інтегруємось. Один простий дискретний згортка - обчислення ковзної середньої. Якщо ви хочете взяти ковзну середню в 10 зразків, це можна вважати суперечливим вашим сигналом розподілом 10 зразків завдовжки та 0,1 заввишки, кожен зразок у вікні спочатку отримується на множення на 0,1, потім всі 10 додаються разом для отримання Середня. Це також виявляє цікаву та важливу відмінність, коли ви розмиваєте згортку, розподіл, який ви використовуєте, повинен становити 1,0 на всі його зразки, інакше це збільшить або зменшить загальну яскравість зображення при його застосуванні.

Тепер, коли ми подивилися на згортки, ми можемо перейти до розмиття. Розмитість Гаусса реалізується шляхом перетворення образу на розподіл Гаусса. Інші розмивання, як правило, реалізуються шляхом перетворення зображення на інші дистрибутиви. Найпростішим розмиттям є розмиття поля, і він використовує той самий розподіл, який ми описали вище, коробку з одиницею площі. Якщо ми хочемо розмити область 10х10, то ми множимо кожен зразок у полі на 0,01, а потім підсумовуємо їх усі разом для отримання центрального пікселя. Нам ще потрібно забезпечити, щоб загальна сума всіх зразків у нашому розподілі розмитості становила 1,0, щоб переконатися, що зображення не стає яскравішим або темнішим.

Розмиття Гаусса дотримується тієї ж широкої процедури, що і розмиття в коробці, але для визначення ваг використовується більш складна формула. Розподіл можна обчислити, виходячи з відстані від центру r, оцінивши Сума всіх зразків у гаусса з часом буде приблизно 1,0, якщо ви вибираєте кожен окремий піксель, але той факт, що Гаусс має нескінченну підтримку (у нього є всюди значення), означає, що вам потрібно використовувати трохи модифіковану версію, яка дорівнює 1,0, використовуючи лише декілька значень.

ex2/22π

Звичайно, обидва ці процеси можуть бути дуже дорогими, якщо виконувати їх на дуже великому радіусі, оскільки для обчислення розмитості потрібно відібрати чимало пікселів. Ось тут і підходить остаточний трюк: і розмиття Гаусса, і розмиття в коробці - це те, що називається "відокремленим" розмиттям. Це означає, що якщо виконати розмиття вздовж однієї осі, а потім виконати його вздовж іншої осі, це дасть такий самий результат, як якщо б ви виконували його по обох осях одночасно. Це може бути надзвичайно важливим. Якщо ваша розмитість становить 10 пікселів поперек, для наївної форми потрібно 100 зразків, але при розділенні лише 20. Різниця лише збільшується, оскільки комбіноване розмиття дорівнює , тоді як відокремлена форма - .O(n2)O(n)


1
Дивлячись на вашу іншу відповідь, схоже, що ваш математичний досвід кращий, ніж я працював, але сподіваюся, що він все-таки детально описується, щоб бути корисним. Я хотів, щоб це було корисно людям будь-якого походження, що вступають у це.
porglezomp

1
Якщо ти розмовляєш зі мною, зовсім не так. Ваша відповідь і Берта напрочуд освічують. Дуже дякую! Зараз
Алан Вулф,

11

Найважливіше, що слід враховувати при здійсненні розмиття Гаусса, як зазначають інші, розділити 2D фільтр згортки на два 1D згортки, оскільки він зводить складність від до .O(n2)O(n)

Але є ще два хитрощі, які ви, можливо, захочете врахувати в реальній реалізації:

Фільтр має певний радіус, і через це на самих кордонах вам потрібно буде обчислити пікселі, які випадають поза зображення. У такому випадку ви можете спробувати одне з наступного: для зовнішніх пікселів ви просто приймаєте останнє можливе значення (тобто піксель на самій межі, як в max(x, 0). Або ви можете "відобразити" зображення назовні (як на x < 0 ? -x : x) Або ви можете просто зупинитися на кордоні, але тоді вам потрібно буде відрегулювати знаменник у фільтрі згортки таким чином, щоб він становив до 1. Наприклад:

sum1256[1464141624164624362464162416414641]=sum1225[0000001624160024361600162416000000]=1.
Ще одна хитрість стосується того, як обчислити фактичні коефіцієнти ядра. Очевидно, ви можете спробувати реалізувати функцію Гаусса, але набагато швидшим способом є зауваження, що ядро ​​1D повторно збирає трикутник Паскаля . Наприклад:
     1
    1 1
   1 2 1
  1 3 3 1
[1 4 6 4 1]
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.