Anda di halaman 1dari 7

Efisiensi Algoritma untuk Gaussian Blur dengan Metode Fastest Gaussian

Diaz Chikal Setiawan, Didin Anandi dan Emul Mulyati

ABSTRAK

Operasi Gaussian blur banyak digunakan dalam aplikasi pengolahan gambar atau image
processing. Waktu yang dibutuhkan untuk membuat operasi tersebut cukup lama, terutama
dari besarnya kernel yang terlibat. Untuk membantu mengurangi waktu yang lama tersebut
ada dua cara yang dilakukan
1. Kernel yang besar dapat di dekomposisi atau diuraikan menjadi beberapa kernel kecil
2. Operasi Gaussian blur dapat dipisahkan menjadi baris dan kolom.
Dalam paper ini menjelaskan mengenai formula metode fastest Gaussian blur untuk kasus
umum dan menyediakan contoh algoritmanya. Metode ini berdasarkan pada Fast image
convolutions dari Wojciech Jarosz yang menyediakan algoritma yang lebih efisien untuk
operasi Gaussian blur. Perbandingan kecepatan untuk beberapa imlementasi juga dijelaskan
dengan beberapa contoh.
Kata kunci : Gaussian, Fastest Gaussian.

PENDAHULUAN
Operasi low-pass filtering banyak digunakan dalam image processing. low-pass filtering
dalam artian melewati frekuensi dengan spasial yang rendah dan menolak frekuensi dengan
spasial yang tinggi. Operasi ini dinamakan smoothing, averaging atau blurring. Salah satu
operasi yang sering digunakan dari jenis ini adalah Gaussian blur dimana memberikan hasil
yang lebih “smooth” dan juga simetris sirkuler. Dalam beberapa kasus, ideal Gaussian “bell
curve” harus mendekati nilai integer. Nilai yang digunakan berdasarkan segitiga pascal.

Index N Koefisien
0
1
2
3
4
5
6
7
8
9
10
Koefisien ini sangat berguna untuk menetapkan N = k yang diperoleh dari konvolusi dari N =
i dan N = j, dimana k = i+j. Sebagai contoh N = 7 diperoleh dari konvolusi [1 3 3 1] dan [1 4
6 4 1].
Paper ini menjelaskan mengenai formula metode fastest Gaussian blur untuk kasus umum
dan menyediakan contoh algoritmanya. Metode ini berdasarkan pada Fast image
convolutions dari Wojciech Jarosz yang menyediakan algoritma yang lebih efisien untuk
operasi Gaussian blur.

Konvolusi 2D dari dua fungsi f dan g didefinisikan sebagai volume dari produk f dan
bergeser ke g. Fungsi kedua g kadang disebut sebagai “weight”, karna menentukan berapa
banyak f yang akan masuk menjadi hasil.
2D Gaussian blur dapat didefinisikan sebagai fungsi konvolusi dengan fungsi 2D Gaussian.
Fungsi Gaussian ini memiliki integral 1 (volume dibawah permukaan) dan didefinisikan
dengan satu parameter σ yang disebut standar deviasi dan bisa juga disebut radius.
Dalam kasus ini, kita akan merepresentasikan fungsi 2D sebagai nilai dari matriks dengan
menghitung volume (integral) dengan penjumlahan. Fungsi Gaussian mendekati nilai nol dibeberapa
radius, jadi nilai yang akan digunakan adalah −r≤x≤r, −r≤y≤r . Nilai ini merupakan bagian dari
“weight” yang biasa disebut sebagai kernel. Nilai konvolusi pada [I,j] adalah rata-rata dari g. Jumlah
dari nilai fungsi sekitar [I,j] dikalikan dengan g.

Algoritma 1
Untuk diskrit konvolusi secara umum dari f dan g, dapat dihitung dengan formula:

b[i,j]=∑y=i−ri+r∑x=j−rj+rf[y,x]∗w[y,x]
Untuk Gaussian, kita dapat hitung hanya disekitar [i,j] (area dari 4.r2). ketika matriks
memiliki nilai n, waktu kompleksitasnya adalah O(n . r2). Untuk radius besar R = 10,
dilakukan operasi n * 400. Berikut algoritmanya

// source channel, target channel, width, height, radius


function gaussBlur_1 (scl, tcl, w, h, r) {
var rs = Math.ceil(r * 2.57); // significant radius
for(var i=0; i<h; i++)
for(var j=0; j<w; j++) {
var val = 0, wsum = 0;
for(var iy = i-rs; iy<i+rs+1; iy++)
for(var ix = j-rs; ix<j+rs+1; ix++) {
var x = Math.min(w-1, Math.max(0, ix));
var y = Math.min(h-1, Math.max(0, iy));
var dsq = (ix-j)*(ix-j)+(iy-i)*(iy-i);
var wght = Math.exp( -dsq / (2*r*r) ) /
(Math.PI*2*r*r);
val += scl[y*w+x] * wght; wsum += wght;
}
tcl[i*w+j] = Math.round(val/wsum);
}
}

Algoritma 2
Box blur merupakan konvolusi dari fungsi f dan bobot w. tapi w merupakan konstan dan
terletak dalam box. Fitur dari box blur ini yaitu ketika memiliki beberapa fungsi w yang
memiliki varian yang sama, maka akan konvergen ke Gaussian blur setelah beberapa passes.
Dalam algoritma ini, kita akan mensimulasikan gaussian blur dengan 3 passing box blur.
Setengah dari ukuran persegi sebagai br ("box radius"). Nilai konstan bobot adalah 1 / (2⋅br)
2
(Jadi jumlah di atas seluruh bobot adalah 1). Kita bisa mendefinisikan box blur sebagai:

bb[i,j]=∑y=i−bri+br∑x=j−brj+brf[y,x]/(2⋅br)2
Dalam kasus ini kita harus mengubah standar deviasi gaussian blur ke dalam dimensi untuk
box blur.

function boxesForGauss(sigma, n) // standard deviation, number of boxes


{
var wIdeal = Math.sqrt((12*sigma*sigma/n)+1); // Ideal averaging
filter width
var wl = Math.floor(wIdeal); if(wl%2==0) wl--;
var wu = wl+2;

var mIdeal = (12*sigma*sigma - n*wl*wl - 4*n*wl - 3*n)/(-4*wl - 4);


var m = Math.round(mIdeal);
// var sigmaActual = Math.sqrt( (m*wl*wl + (n-m)*wu*wu - n)/12 );

var sizes = []; for(var i=0; i<n; i++) sizes.push(i<m?wl:wu);


return sizes;
}

function gaussBlur_2 (scl, tcl, w, h, r) {


var bxs = boxesForGauss(r, 3);
boxBlur_2 (scl, tcl, w, h, (bxs[0]-1)/2);
boxBlur_2 (tcl, scl, w, h, (bxs[1]-1)/2);
boxBlur_2 (scl, tcl, w, h, (bxs[2]-1)/2);
}
function boxBlur_2 (scl, tcl, w, h, r) {
for(var i=0; i<h; i++)
for(var j=0; j<w; j++) {
var val = 0;
for(var iy=i-r; iy<i+r+1; iy++)
for(var ix=j-r; ix<j+r+1; ix++) {
var x = Math.min(w-1, Math.max(0, ix));
var y = Math.min(h-1, Math.max(0, iy));
val += scl[y*w+x];
}
tcl[i*w+j] = val/((r+r+1)*(r+r+1));
}
}

Algoritma 3
Dalam kasus ini algoritma Gaussian blur disederhanakan menjadi 3 passes dari box blur.
Didefinisikan blur horizontal dan total blur:
bh[i,j]=∑x=j−brj+brf[i,x]/(2⋅br)
bt[i,j]=∑y=j−brj+brbh[y,j]/(2⋅br)
Kedua fungsi itu di looping dalam satu garis yang menghasilkan satu dimensi blur yang
sesuai dengan :

bt[i,j]=∑y=i−bri+brbh[y,j]/(2⋅br)=∑y=j−brj+br(∑x=j−brj+brf[y,x]/(2⋅br))/(2⋅b
r)=∑y=i−bri+br∑x=j−brj+brf[y,x]/(2⋅br)2
Berikut algoritmanya:

function gaussBlur_3 (scl, tcl, w, h, r) {


var bxs = boxesForGauss(r, 3);
boxBlur_3 (scl, tcl, w, h, (bxs[0]-1)/2);
boxBlur_3 (tcl, scl, w, h, (bxs[1]-1)/2);
boxBlur_3 (scl, tcl, w, h, (bxs[2]-1)/2);
}
function boxBlur_3 (scl, tcl, w, h, r) {
for(var i=0; i<scl.length; i++) tcl[i] = scl[i];
boxBlurH_3(tcl, scl, w, h, r);
boxBlurT_3(scl, tcl, w, h, r);
}
function boxBlurH_3 (scl, tcl, w, h, r) {
for(var i=0; i<h; i++)
for(var j=0; j<w; j++) {
var val = 0;
for(var ix=j-r; ix<j+r+1; ix++) {
var x = Math.min(w-1, Math.max(0, ix));
val += scl[i*w+x];
}
tcl[i*w+j] = val/(r+r+1);
}
}
function boxBlurT_3 (scl, tcl, w, h, r) {
for(var i=0; i<h; i++)
for(var j=0; j<w; j++) {
var val = 0;
for(var iy=i-r; iy<i+r+1; iy++) {
var y = Math.min(h-1, Math.max(0, iy));
val += scl[y*w+j];
}
tcl[i*w+j] = val/(r+r+1);
}
}
Algoritma 4

Satu dimensi blur dapat dihitung lebih cepat lagi. Untuk menghitung blur horizontal dapat
menggunakan:

bh[i,j],bh[i,j+1],bh[i,j+2]

Untuk nilai bh[i,j] and bh[i,j+1] hampir sama. Satu-satunya perbedaannya adalah satu nilai
paling kiri dan satu nilai paling kanan. Oleh karna itu formulanya

bh[i,j+1]=bh[i,j]+f[i,j+r+1]−f[i,j−r]
Dalam algoritma baru yang akan dibuat, kita akan menghitung satu dimensi blur dengan
membuat akumulator. Pertama dengan meletakan nilai sel paling kiri ke dalamnya. Kemudian
kita akan menghitung nilai berikutnya hanya dengan mengedit nilai sebelumnya dalam waktu
konstan. 1D blur ini memiliki kompleksitas O(n) (independen pada r). Hal ini dua kali
dilakukan untuk mendapatkan box blur, dan 3 kali untuk mendapatkan Gaussian blur. Jadi
kompleksitas Gaussian blur ini adalah 6 * O (n).

Berikut Algoritmanya:

function gaussBlur_4 (scl, tcl, w, h, r) {


var bxs = boxesForGauss(r, 3);
boxBlur_4 (scl, tcl, w, h, (bxs[0]-1)/2);
boxBlur_4 (tcl, scl, w, h, (bxs[1]-1)/2);
boxBlur_4 (scl, tcl, w, h, (bxs[2]-1)/2);
}
function boxBlur_4 (scl, tcl, w, h, r) {
for(var i=0; i<scl.length; i++) tcl[i] = scl[i];
boxBlurH_4(tcl, scl, w, h, r);
boxBlurT_4(scl, tcl, w, h, r);
}
function boxBlurH_4 (scl, tcl, w, h, r) {
var iarr = 1 / (r+r+1);
for(var i=0; i<h; i++) {
var ti = i*w, li = ti, ri = ti+r;
var fv = scl[ti], lv = scl[ti+w-1], val = (r+1)*fv;
for(var j=0; j<r; j++) val += scl[ti+j];
for(var j=0 ; j<=r ; j++) { val += scl[ri++] - fv ;
tcl[ti++] = Math.round(val*iarr); }
for(var j=r+1; j<w-r; j++) { val += scl[ri++] - scl[li++];
tcl[ti++] = Math.round(val*iarr); }
for(var j=w-r; j<w ; j++) { val += lv - scl[li++];
tcl[ti++] = Math.round(val*iarr); }
}
}
function boxBlurT_4 (scl, tcl, w, h, r) {
var iarr = 1 / (r+r+1);
for(var i=0; i<w; i++) {
var ti = i, li = ti, ri = ti+r*w;
var fv = scl[ti], lv = scl[ti+w*(h-1)], val = (r+1)*fv;
for(var j=0; j<r; j++) val += scl[ti+j*w];
for(var j=0 ; j<=r ; j++) { val += scl[ri] - fv ; tcl[ti] =
Math.round(val*iarr); ri+=w; ti+=w; }
for(var j=r+1; j<h-r; j++) { val += scl[ri] - scl[li]; tcl[ti] =
Math.round(val*iarr); li+=w; ri+=w; ti+=w; }
for(var j=h-r; j<h ; j++) { val += lv - scl[li]; tcl[ti] =
Math.round(val*iarr); li+=w; ti+=w; }
}
}

Hasil

Setelah dilakukan pengujian dari keempat algoritma diatas pada gambar 800x200 pixel.
Berikut hasil yang didapatkan:

Algoritma 1 merupakan komputasi yang sebenarnya dari Gaussian blur menggunakan kernel
Gaussian, sedangkan algoritma 2, 3, 4 menggunakan pendekatan dengan melewati 3 passing box
blur. Perbedaan dari algoritma 2,3,4 adalah pada kompleksitas dari komputasi box blurnya dan
output yang dihasilkannya sama.

Original Image
Perfect Gaussian Blur (Algoritma 1)

Algoritma 2,3,4 dengan rata-rata error per pixel 0.04%

Blur menggunakan adobe photoshop dengan rata-rata error per pixel 0.09%

Anda mungkin juga menyukai