Teori penunjang dan desain sistem yang telah dibahas sebelumnya akan diterapkan menjadi sebuah aplikasi yang siap digunakan. Implementasi yang akan dibahas mencakup implementasi software bantu dan source code program.
4.1. Implementasi Software yang Digunakan
Software yang digunakan di sini adalah Borland Delphi 7. Alasan penggunaan Borland Delphi 7 adalah karena Delphi mendukung proses imaging, bersifat user friendly, dan mempunyai interface yang dapat ditata dengan baik.
Selain itu Delphi 7 mempunyai performa yang cukup cepat dalam melakukan perhitungan yang banyak dan mempunyai kuantitas yang cukup untuk menyimpannya dalam memory komputer.
4.2. Implementasi Software yang Dibuat 4.2.1. Library dan unit yang digunakan
Library menggunakan standar dari Delphi, terkecuali dengan Library JPEG. Fungsi dari library ini untuk memudahkan membuka file JPG dan JPEG.
Dalam program ini hanya menggunakan 1 unit utama saja sehingga tidak ada daftar unit. Daftar library yang digunakan selengkapnya pada segmen program 4.1.
Segmen Program 4.1. Daftar Library
uses
Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls, Forms,Dialogs,Menus,ExtCtrls,ExtDlgs,JPEG,StdCtrls,ComCtrls,Grids, Buttons;
4.2.2. Header Procedure
Header procedure yang terdapat pada segmen program 4.2. merupakan
header procedure yang terdapat pada form dimana gambar ditampilkan dan
diproses. Ada beberapa procedure lainnya yang bersifat umum yang tidak terdapat pada segmen program 4.2.
Segmen Program 4.2. Header Procedure utama.
procedure bersih_gambar();
procedure converttogray();
procedure crop();
procedure evolve();
procedure gaussian_blur();
procedure hitung_distance();
procedure hitung_K();
procedure make_boundary();
function hitung_xderivative(i,j:integer):real;
function hitung_xxderivative(i,j:integer):real;
function hitung_xyderivative(i,j:integer):real;
function hitung_yderivative(i,j:integer):real;
function hitung_yyderivative(i,j:integer):real;
Penjelasan mengenai fungsi procedure dan function pada segmen program 4.2.
ditunjukan pada tabel 4.1. Isi lengkap dari procedure dan function akan dibahas lebih lanjut.
Tabel 4.1. Penjelasan procedure dan function
PROCEDURE DAN FUNCTION KETERANGAN
bersih_gambar(); Procedure untuk mengganti gambar yang telah digambar kurva didalamnya dengan gambar asli yang masih bersih, ini dilakukan untuk keperluan
animasi penggambaran pergerakan kurva.
converttogray(); Procedure untuk mengubah gambar berwarna menjadi Gray- Level
crop(); Procedure untuk mengkopi
gambar yang sudah disegmentasi ke gambar baru.
evolve(); Procedure untuk menggerakkan kurva menuju border dari obyek pada gambar.
gaussian_blur(); Procedure untuk melakukan proses gaussian filter pada gambar.
hitung_distance(); Procedure untuk menghitung
distance dari setiap titik terhadap
kurva inisialisasi.
hitung_K(); Procedure untuk nilai K
Ipada setiap titik dengan menggunakan Sobel.
make_boundary(); Procedure untuk menentukan boundary dan evolving area.
hitung_xderivative(i,j:integer):real; Function untuk menghitung turunan pertama dari distance pada suatu titik terhadap sumbu x.
hitung_xxderivative(i,j:integer):real; Function untuk menghitung turunan kedua dari distance pada suatu titik terhadap sumbu x.
hitung_xyderivative(i,j:integer):real; Function untuk menghitung turunan dari distance pada suatu titik terhadap sumbu x dan sumbu y.
hitung_yderivative(i,j:integer):real; Function untuk menghitung turunan pertama dari distance pada suatu titik terhadap sumbu y.
hitung_yyderivative(i,j:integer):real; Function untuk menghitung turunan kedua dari distance pada
suatu titik terhadap sumbu y.
4.2.3. Menu File
Gambar 4.1. menunjukan user interface dari software ini dan pada menu file terdapat 3 tombol. Tombol-tombol tersebut adalah Open Image, Save Image dan Close. Tombol Open Image berguna untuk membuka file gambar digital, tombol Save Image berguna untuk menyimpan gambar hasil segmentasi dan tombol Close untuk keluar dari program. Tombol yang akan dibahas lebih lanjut adalah tombol Open Image.
Gambar 4.1 Menu File pada User Interface
4.2.3.1. Membuka Gambar
Menu File – Open Image berfungsi untuk melakukan proses membuka file gambar, inisialisasi variabel yang diperlukan dan melakukan preprocessing.
Source code untuk proses membuka gambar, inisialisasi variabel, dan Grayscaling terdapat pada segmen program 4.3.
Segmen Program 4.3. Membuka gambar
procedure TForm1.OpenImage1Click(Sender: TObject);
var y,i,j:integer;
begin
if OpenPictureDialog1.Execute then begin
bwhite:=TBitmap.Create;
image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
bwhite.Width:=Image1.Width;
bwhite.Height:=Image1.Height;
image1.Visible:=false;
image2.Left:=image1.Left;
image2.Top:=image1.Top;
image2.Width:=image1.Width;
image2.Height:=image1.Height;
image2.Picture.Bitmap.Assign(bwhite);
image2.Visible:=false;
temporary.Left:=image1.Left;
temporary.Top:=image1.Top;
temporary.Width:=image1.Width;
temporary.Height:=image1.Height;
temporary.Picture.Bitmap.Assign(bwhite);
temporary.Visible:=false;
image4.Left:=image1.Left;
image4.Top:=image1.Top;
image4.Width:=image1.Width;
image4.Height:=image1.Height;
image4.Picture.Bitmap.Assign(bwhite);
image4.Canvas.Draw(0,0,image1.Picture.Graphic);
image4.Visible:=true;
temporary.Canvas.Draw(0,0,image1.Picture.Graphic);
temporary.Picture.Bitmap.PixelFormat:=pf24bit;
image4.Picture.Bitmap.PixelFormat:=pf24bit;
cropp.Left:=image1.Left;
cropp.Top:=image1.Top;
cropp.Picture.Bitmap.Assign(bwhite);
cropp.Visible:=false;
gray_image.Left:=image1.Left;
gray_image.Top:=image1.Top;
gray_image.Width:=image4.Width;
gray_image.Height:=image4.Height;
gray_image.Picture.Bitmap.Assign(bwhite);
gray_image.Visible:=False;
border_image.Left:=image1.Left;
border_image.Top:=image1.Top;
border_image.Width:=image4.Width;
border_image.Height:=image4.Height;
border_image.Picture.Bitmap.Assign(bwhite);
border_image.Visible:=False;
SetLength(data,image4.Height);
SetLength(temp,image4.Height);
SetLength(gray,image4.Width,image4.Height);
setlength(distance,image4.Width,image4.Height);
setlength(K,image4.Width,image4.Height);
setlength(negatif,image4.Width,image4.Height);
setlength(boundary,image4.Width,image4.Height);
setlength(evolving_area,image4.Width,image4.Height);
OriginalImage1.Enabled:=True;
for y:=0 to image4.Height-1 do begin
data[y]:=image4.Picture.Bitmap.ScanLine[y];
temp[y]:=temporary.Picture.Bitmap.ScanLine[y];
end;
for j:=0 to form1.Image4.Height-1 do begin
for i:=0 to form1.Image4.Width-1 do begin
gray[i,j]:= round((temp[j][i*3+2]*0.299) +
(temp[j][i*3+1]*0.587)+(temp[j][i*3]*0.114));
end;
end;
gaussian_blur;
hitung_K;
end;
Dalam Segmen Program 4.3 dilakukan proses grayscaling dengan mengalikan masing-masing komponen warna dengan persentasi R = 0.299, G
=0.587, B=0.114 sehingga menghasilkan nilai RGB yang baru. Kemudian dilakukan proses gaussian_blur dan hitung_K yang juga termasuk dalam preprocessing. Source code untuk proses gaussian_blur dan hitung_K terdapat dalam Segmen Program 4.4 dan Segmen Program 4.5.
Segmen Program 4.4 Gaussian_Blur
procedure gaussian_blur();
var i,j:integer;
jummatrik:real;
begin
for i:=1 to form1.image4.Width-2 do begin
for j:=1 to form1.Image4.Height-2 do begin
jummatrik:=0;
jummatrik:=jummatrik + (gray[i-1,j-1]*0.37);
jummatrik:=jummatrik + (gray[i,j-1]*0.61);
jummatrik:=jummatrik + (gray[i+1,j-1]*0.37);
jummatrik:=jummatrik + (gray[i-1,j]*0.61);
jummatrik:=jummatrik + gray[i,j];
jummatrik:=jummatrik + (gray[i+1,j]*0.61);
jummatrik:=jummatrik + (gray[i-1,j+1]*0.37);
jummatrik:=jummatrik + (gray[i,j+1]*0.61);
jummatrik:=jummatrik + (gray[i+1,j+1]*0.37);
jummatrik:=jummatrik/4.92;
gray[i,j]:=round(jummatrik);
Form1.gray_image.Canvas.Pixels[i,j]:=RGB(gray[i,j],gray[i,j], gray[i,j]);
end;
end;
form1.GrayImagewithGaussianBlur1.Enabled:=True;
end;
Pada segmen program 4.4 dilakukan perhitungan Gaussian Blur dengan menggunakan matriks Gaussian averaging operator pada gambar grayscale seperti yang sudah dijelaskan dalam bab 2. Kemudian hasil dari perhitungan tersebut digambarkan pada gray_image.
Segmen Program 4.5 Hitung_K
procedure hitung_K();
var i,j:integer;
matrik_horisontal:integer;
matrik_vertikal:integer;
hasil:integer;
begin
for j:=1 to form1.image4.Height-2 do begin
for i:=1 to form1.image4.Width-2 do begin
matrik_horisontal:=0;
matrik_vertikal:=0;
matrik_horisontal:=matrik_horisontal-gray[i-1,j-1];
matrik_vertikal:=matrik_vertikal+gray[i-1,j-1];
matrik_vertikal:=matrik_vertikal+(gray[i,j-1]*2);
matrik_horisontal:=matrik_horisontal+gray[i+1,j-1];
matrik_vertikal:=matrik_vertikal+gray[i+1,j-1];
matrik_horisontal:=matrik_horisontal+(gray[i-1,j]*-2);
matrik_horisontal:=matrik_horisontal+(gray[i+1,j]*2);
matrik_horisontal:=matrik_horisontal-gray[i-1,j+1];
matrik_vertikal:=matrik_vertikal-gray[i-1,j+1];
matrik_vertikal:=matrik_vertikal+(gray[i,j+1]*-2);
matrik_horisontal:=matrik_horisontal+gray[i+1,j+1];
matrik_vertikal:=matrik_vertikal-gray[i+1,j+1];
if matrik_horisontal<0 then
matrik_horisontal:=abs(matrik_horisontal);
if matrik_vertikal<0 then
matrik_vertikal:=abs(matrik_vertikal);
hasil:=abs(matrik_horisontal) OR abs(matrik_vertikal);
if hasil < treshold then hasil:=0;
K[i,j]:=1/(1+hasil);
form1.border_image.Canvas.Pixels[i,j]:=RGB(hasil,hasil,hasil);
end;
end;
Form1.BorderImage1.Enabled:=True;
end;
Pada segmen program 4.4 dilakukan perhitungan untuk mencari nilai K
Idengan menggunakan gabungan dari matriks Sobel vertikal dan Sobel horisontal.
Penggabungan dengan menggunakan operator OR. Semua hasil perhitungan dijadikan positif, disesuaikan dengan nilai treshold, kemudian nilai K
Idihitung.
Hasil dari semua ditampilkan pada gambar border_image.
4.2.4. Menu View
Pada menu view, ditunjukkan oleh gambar 4.2, terdapat 4 tombol yaitu Original Image, Gray Image with Gaussian Blur, Border Image dan Crop Image.
Fungsi dari tombol-tombol tersebut adalah untuk menampilkan gambar sesuai
dengan judulnya. Jika Original Image yang dipilih maka yang akan terlihat di
layar adalah gambar berwarna, dimana pada gambar ini akan dilakukan
segmentasi. Jika Gray Image with Gaussian Blur yang dipilih maka yang akan
terlihat adalah gambar yang sudah diproses dengan menggunakan grayscaling dan
gaussian blur. Jika Border Image yang dipilih maka yang akan terlihat adalah
border dari semua obyek di dalam gambar tersebut. Jika Crop Image yang dipilih
maka yang akan terlihat adalah obyek yang sudah disegmentasi.
Source code untuk menu ini terdapat dalam segmen program 4.6.
Gambar 4.2 Menu View
Segmen Program 4.6 Menu View
procedure TForm1.OriginalImage1Click(Sender: TObject);
begin
image4.Visible:=true;
gray_image.Visible:=false;
border_image.Visible:=false;
cropp.Visible:=false;
SaveImage1.Enabled:=false;
end;
procedure TForm1.GrayImagewithGaussianBlur1Click(Sender: TObject);
begin
gray_image.Visible:=True;
image4.Visible:=false;
border_image.Visible:=false;
cropp.Visible:=false;
SaveImage1.Enabled:=false;
end;
procedure TForm1.BorderImage1Click(Sender: TObject);
begin
gray_image.Visible:=false;;
image4.Visible:=false;
border_image.Visible:=true;
cropp.Visible:=false;
SaveImage1.Enabled:=false;
end;
procedure TForm1.CropImage1Click(Sender: TObject);
begin
gray_image.Visible:=false;;
image4.Visible:=false;
border_image.Visible:=false;
cropp.Visible:=true;
SaveImage1.Enabled:=true;
end;
4.2.5 Menu Segmentation
Menu Segmentation seperti pada gambar 4.3 merupakan menu yang berhubungan dengan proses segmentasi. Di dalam menu ini terdapat 2 tombol yaitu Parameter dan Excecute. Fungsi tombol parameter untuk mengeluarkan panel parameter dimana user dapat mengubah parameter-parameter yang ada.
Fungsi tombol parameter untuk menjalankan proses evolusi dari kurva. Source code dari proses excecute terdapat dalam segmen program 4.7, dalam segmen program 4.8 juga akan dijelaskan semua fungsi yang mendukung untuk evolusi kurva, seperti fungsi untuk menghitung turunan pertama terhadap sumbu x, turunan kedua terhadap sumbu x, turunan pertama terhadap sumbu y, turunan kedua terhadap sumbu y, dan turunan terhadap sumbu x dan sumbu y.
Gambar 4.3. Menu Segmentation
Segmen Program 4.7 Evolusi Kurva
procedure evolve();
var i,j:integer;
F,pembagi,kurva,update_value:real;
turunanx,turunany,turunanxx,turunanyy,turunanxy:real;
begin
for i:=1 to form1.image4.width-2 do begin
for j:=1 to form1.image4.Height-2 do begin
if evolving_area[i,j] then begin
turunanx:=hitung_xderivative(i,j);
turunanxx:=hitung_xxderivative(i,j);
turunany:=hitung_yderivative(i,j);
turunanyy:=hitung_yyderivative(i,j);
turunanxy:=hitung_xyderivative(i,j);
pembagi:=(turunanx * turunanx) + (turunany * turunany);
if pembagi=0 then kurva:=0 else kurva:=(
(turunanxx*(turunany*turunany)) -(2*(turunanx*turunany*turunanxy)) +(turunanyy*turunanx*turunanx) /sqrt(pembagi*pembagi*pembagi)
);
if kurva>5 then kurva:=5;
if kurva<-5 then kurva:=-5;
if mengembang then if kurva>0 then kurva:=kurva * -1;
if mengempis then if kurva<0 then kurva:=abs(kurva);
F:=1-(epsilon*kurva);
F:=F*K[i,j];
update_value:=deltaT*F;
if (update_value<0.1) and (update_value>-0.1) then update_value:=0;
distance[i,j]:=distance[i,j]-update_value;
end;
end;
end;
bersih_gambar;
make_boundary;
Segmen Program 4.8 Fungsi Turunan
function hitung_xderivative(i,j:integer):real;
begin
result:=(distance[i+1,j]-distance[i-1,j])/2;
end;
function hitung_yderivative(i,j:integer):real;
begin
result:=(distance[i,j+1]-distance[i,j-1])/2;
end;
function hitung_xxderivative(i,j:integer):real;
begin
result:=(distance[i+1,j]-(2*distance[i,j])+distance[i-1,j]);
end;
function hitung_yyderivative(i,j:integer):real;
begin
result:=(distance[i,j+1]-(2*distance[i,j])+distance[i,j-1]);
end;
function hitung_xyderivative(i,j:integer):real;
begin
result:=(distance[i+1,j+1]-distance[i-1,j+1]-distance[i+1,j-1]
+distance[i-1,j-1])/4;
end;
Menu segmentation ini hanya bisa diakses apabila kurva inisialisasi telah
dibuat. Seperti pada gambar 4.4 berikut ini
Gambar 4.4 Kurva Inisialisasi
Proses-proses yang berhubungan dengan kurva inisialisasi adalah proses penggambaran kurva, proses hitung distance, dan proses pembuatan boundary.
Penggambaran kurva tidak hanya berupa lingkaran hitam saja tetapi warnanya juga disesuaikan dengan warna dari lingkungannya, warna kurva yang ditampilkan selalu bertolak belakang dengan warna dari latar belakang (background). Hal ini untuk memudahkan mencari dimana kurva berada. Source code dari penggambaran kurva akan terdapat pada segmen program 4.9, hitung distance pada segmen program 4.10 dan proses pembuatan boundary pada segmen program 4.11.
Segmen Program 4.9 Penggambaran Kurva
Procedure TForm1.Image4MouseDown(Sender: TObject; Button:
TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
image2.Picture.Bitmap.Assign(bwhite);
bersih_gambar;
image4.Refresh;
jari:=0;
xpusat:=X;
x2:=X;
ypusat:=Y;
y2:=Y;
image2.Canvas.Brush.Color:=RGB(100,0,0);
image2.Canvas.Ellipse(xpusat,ypusat,x2,y2);
mouse_ditekan:=1;
end;
procedure TForm1.Image4MouseMove(Sender: TObject; Shift:
TShiftState; X, Y: Integer);
var i,j,r,valid,temp_jari:integer;
begin
valid:=1;
temp_jari:=0;
if mouse_ditekan=1 then begin
image2.Picture.Bitmap.Assign(bwhite);
x2:=X;
y2:=Y;
if x2>xpusat then begin
temp_jari:=jari;
jari:=x2-xpusat;
end
else if x2<xpusat then begin
temp_jari:=jari;
jari:=xpusat-x2;
end;
if (xpusat-jari<0) or (xpusat+jari>image4.Width-1) then begin
jari:=temp_jari;
valid:=0;
end;
if (ypusat-jari<0) or (ypusat+jari>image4.Height-1) then begin
jari:=temp_jari;
valid:=0;
end;
if valid=1 then begin
image2.Canvas.Ellipse(xpusat-jari,ypusat- jari,xpusat+jari,ypusat+jari);
bersih_gambar;
for j:=ypusat-jari to ypusat+jari do begin
for i:=xpusat-jari to xpusat+jari do begin
r:=GetRValue(image2.Canvas.Pixels[i,j]);
if r=0 then begin
data[j][i*3]:=255-data[j][i*3];
data[j][(i*3)+1]:=255-data[j][(i*3)+1];
data[j][(i*3)+2]:=255-data[j][(i*3)+2];
end;
end;
end;
end;
image4.Refresh;
end;
end;
procedure TForm1.Image4MouseUp(Sender: TObject; Button:
TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
hitung_distance;
hitung_K;
mouse_ditekan:=0;
Parameter1.Enabled:=True;
Excecute1.Enabled:=True;
end;
Segmen Program 4.10 hitung distance
procedure hitung_distance();
var i,j,minus:integer;
jarak:real;
begin
minus:=-1;
bersih_gambar;
for i:=0 to form1.image4.Width-1 do begin
for j:=0 to form1.image4.Height-1 do begin
jarak:=sqrt(((i-xpusat)*(i-xpusat))+
((j-ypusat)*(j-ypusat)));
if jarak>=jari then distance[i,j]:=(jarak-jari) else distance[i,j]:=(jari-jarak)*minus;
end;
end;
make_boundary;
end;
Segmen Program 4.11 Pembuatan Boundary
procedure make_boundary();
var i,j:integer;
begin
xmin:=9999;
xmax:=0;
ymin:=9999;
ymax:=0;
for i:=0 to form1.Image4.Width-1 do begin
for j:=0 to form1.Image4.Height-1 do begin
if distance[i,j]<=0 then begin
negatif[i,j]:=True;
end
else negatif[i,j]:=False;
boundary[i,j]:=False;
evolving_area[i,j]:=False;
end;
end;
for i:=1 to form1.Image4.Width-2 do begin
for j:=1 to form1.Image4.Height-2 do begin
if (negatif[i,j]=negatif[i-1,j-1]) and (negatif[i,j] =
negatif[i,j-1]) and (negatif[i,j] = negatif[i+1,j-1]) and (negatif[i,j]=negatif[i-1,j]) and (negatif[i,j] = negatif[i+1,j])
and (negatif[i,j]=negatif[i-1,j+1]) and (negatif[i,j] = negatif[i,j+1]) and (negatif[i,j]=negatif[i+1,j+1]) then boundary[i,j]:=false
else begin
boundary[i,j]:=True;
if i<xmin then xmin:=i;
if j<ymin then ymin:=j;
if i>xmax then xmax:=i;
if j>ymax then ymax:=j;
data[j][i*3]:=255-temp[j][i*3];
data[j][(i*3)+1]:=255-temp[j][(i*3)+1];
data[j][(i*3)+2]:=255-temp[j][(i*3)+2];
end;
end;
end;
for i:=1 to form1.Image4.Width-2 do begin
for j:=1 to form1.Image4.Height-2 do begin
if boundary[i-1,j-1] then evolving_area[i,j]:=true;
if boundary[i,j-1] then evolving_area[i,j]:=true;
if boundary[i+1,j-1] then evolving_area[i,j]:=true;
if boundary[i-1,j] then evolving_area[i,j]:=true;
if boundary[i,j] then evolving_area[i,j]:=true;
if boundary[i+1,j] then evolving_area[i,j]:=true;
if boundary[i-1,j+1] then evolving_area[i,j]:=true;
if boundary[i,j+1] then evolving_area[i,j]:=true;
if boundary[i+1,j+1] then evolving_area[i,j]:=true;
end;
end;
form1.Image4.Refresh;
end;