Saya telah menerapkan shader fragmen gaussian blur di GLSL. Saya memahami konsep utama di balik semua itu: konvolusi, pemisahan x dan y menggunakan linearitas, beberapa lintasan untuk meningkatkan radius ...
Saya masih punya beberapa pertanyaan:
Apa hubungan antara sigma dan jari-jari?
Saya telah membaca bahwa sigma setara dengan jari-jari, saya tidak melihat bagaimana sigma diekspresikan dalam piksel. Atau "radius" hanya nama untuk sigma, tidak terkait dengan piksel?
Bagaimana saya memilih sigma?
Mengingat saya menggunakan beberapa pass untuk meningkatkan sigma, bagaimana cara saya memilih sigma yang baik untuk mendapatkan sigma yang saya inginkan pada setiap pass yang diberikan? Jika sigma yang dihasilkan sama dengan akar kuadrat dari jumlah kuadrat sigma dan sigma setara dengan jari-jari, apa cara mudah untuk mendapatkan jari-jari yang diinginkan?
Apa ukuran yang baik untuk kernel, dan bagaimana hubungannya dengan sigma?
Saya telah melihat sebagian besar implementasi menggunakan kernel 5x5. Ini mungkin pilihan yang baik untuk implementasi cepat dengan kualitas yang layak, tetapi apakah ada alasan lain untuk memilih ukuran kernel lain? Bagaimana sigma berhubungan dengan ukuran kernel? Haruskah saya menemukan sigma terbaik sehingga koefisien di luar kernel saya dapat diabaikan dan hanya menjadi normal?
sumber
Parameter sigma cukup untuk mendefinisikan blur Gaussian dari sudut pandang kontinu. Namun dalam praktiknya, gambar dan kernel konvolusi terpisah. Bagaimana memilih perkiraan diskrit optimal dari kernel Gaussian kontinu?
Perkiraan diskrit akan lebih dekat ke kernel Gaussian kontinu ketika menggunakan radius yang lebih besar. Tetapi ini mungkin datang dengan biaya tambahan durasi perhitungan.
Idealnya, seseorang akan memilih nilai untuk sigma, kemudian menghitung radius yang memungkinkan untuk mewakili dengan setia kernel Gaussian kontinu yang sesuai. Untuk kesalahan perkiraan yang diberikan, semakin besar sigma, semakin besar radiusnya.
Menariknya, ini bisa menjadi sangat rumit untuk memperbaikinya. Ketika membangun matriks Gaussian, apakah solusi terbaik untuk sampel kernel kontinu atau ada perkiraan yang lebih baik? Bagaimana cara menormalkan kernel diskrit yang dihitung untuk memperhitungkan pemotongan? dll.
Sebagai referensi, dalam Mathematica fungsi GaussianMatrix menampilkan beberapa cara untuk menghitung matriks diskrit Gaussian, misalnya menggunakan pendekatan Bessel diskrit. Secara default, radius = 2 * sigma, yang berarti bahwa dengan sigma = 1, matriks akan menjadi 5x5.
sumber
Ternyata deretan Pascal's Triangle mendekati Gaussian dengan cukup baik dan memiliki keuntungan praktis memiliki nilai integer yang jumlahnya adalah kekuatan 2 (kita dapat menyimpan nilai-nilai ini tepat sebagai integer, nilai titik tetap, atau mengapung). Sebagai contoh, katakanlah kita ingin membangun 7x7 Gaussian Kernel kita dapat melakukannya menggunakan baris ke-7 dari segitiga Pascal sebagai berikut:
Perhatikan bahwa filter ini memiliki pengaruh minimum di sudut-sudutnya sementara sisanya bernilai integer. Anda dapat menggunakan nilai tengah 20/64 untuk menentukan sigma standar deviasi yang sesuai yaitu 64 / (20 * sqrt (2 * pi)) = 1.276 untuk Gaussian yang diperkirakan dalam kasus ini. Anda dapat membuat grafik Gaussian untuk melihat ini sangat cocok.
Jadi titik awal yang baik untuk menentukan standar deviasi yang wajar untuk Gaussian Kernel berasal dari Segitiga Pascal (alias Koefisien Binomial ) - untuk filter (N + 1) x (N + 1) yang sesuai dengan penggunaan konstruksi di atas
GaussianMatrix dari Wolfram Alpha [3] hanya menggunakan r / 2 = 1.5. Anehnya, GaussianMatrix [{3,1.276}] tidak menghasilkan filter 2D yang sama dengan tambang dan bukan yang berikut untuk x, y antara -3 dan 3:
Saya tidak yakin mengapa tidak? Filter 2D saya sangat pas.
sumber