ALGORITMA THINNING STENTIFORD UNTUK MENDAPATKAN BENTUK DASAR HURUF
Skripsi
Diajukan untuk Memenuhi Salah Satu Syarat Memperoleh Gelar Sarjana Sains Program Studi Ilmu Komputer
Oleh
Leonardus Beni Aji Prabangkoro NIM : 043124005
PROGRAM STUDI ILMU KOMPUTER JURUSAN MATEMATIKA FAKULTAS SAINS DAN TEKNOLOGI UNIVERSITAS SANATA DHARMA YOGYAKARTA 2008
i
STENTIFORD THINNING ALGORITHM TO OBTAIN THE BASIC FORM OF LETTER
A Thesis
Presented as Partial Fulfillment of the Requirements to obtain the Sarjana Sains Degree in Computer Science
By
Leonardus Beni Aji Prabangkoro Student Number : 043124005
COMPUTER SCIENCE STUDY PROGRAM DEPARTMENT OF MATHEMATHICS FACULTY OF SCIENCE AND TECHNOLOGY SANATA DHARMA UNIVERSITY YOGYAKARTA 2008
i
HALAMAN MOTTO
Love, like truth and beauty, is concrete. Love is not fundamentally a sweet feeling; not, at heart, a matter of sentiment, attachment, or being "drawn toward." Love is active, effective, a matter of making reciprocal and mutually beneficial relation with one's friends and enemies (Carter Heyward)
You're not obligated to win. You're obligated to keep trying to do the best you can every day. (Marian Wright Edelman)
Difficulties increase the nearer we get to the goal. (Goethe)
iv
HALAMAN PERSEMBAHAN
Tugas akhir ini kupersembahkan untuk ¾ Tuhan Yesus Kristus, Puji syukur atas segala rahmat, anugrah dan cinta kasih – Mu yang selama ini yang telah membimbing hidupku untuk mencapai tahap ini. ¾ Kedua Orang Tuaku, Bapak dan Ibu, Tugas akhirku ini sebagai ungkapan hormat, terima kasih dan baktiku. ¾ Kakak dan Adikku, Anita dan Yoyok, Terima kasih atas dukungan kalian, O.. ya..dan maafkan adik dan kakakmu ini yang telah mengambil jatah waktu komputer kalian
v
ABSTRAK
Kemajuan teknologi telah membuat perkembangan aplikasi di bidang pengenalan karakter maju dengan pesat. Pengenalan karakter meliputi pengolahan dan analisa dokumen citra. Data masukan untuk analisa dokumen atau pengenalan karakter umumnya berupa citra dokumen yang diperoleh secara offline. Dalam pengolahan dan analisa ada beberapa proses yang umumnya dijalankan yaitu grayscaling, binerisasi atau tresholding dan thinning. Thinning merupakan operasi pengolahan citra yang beroperasi pada citra biner dengan mengikis bagian objek menjadi bentuk garis yang mewakili kerangka dari objek tersebut. Operasi thinning mempunyai beberapa definisi. Iterative Morphological Method merupakan salah satu dari definisi tersebut. Metode ini melakukan operasi penghapusan piksel dengan dasar pencocokan pada template. Algoritma Stentiford menjadi salah satu contoh dari metode ini yang dapat digunakan. Dari hasil pengujian, Algoritma Stentiford mempunyai beberapa isu atau kekurangan. Dalam pengujian yang telah dilakukan, timbulnya line fuzz membuat data citra hasil pengoperasian thinning secara visual tidak memenuhi asumsi atau definisi dari kerangka. Oleh karena itu, beberapa operasi dapat ditambahkan untuk mengatasi permasalahan ini.
vi
ABSTRACT
The progress of technology has made a great development in pattern recognition field of study. Pattern recognition is covering image document processing and analysis. Input data that used for document analysis and letter recognition are generally in a form of image document that obtained in an offline manner. Grayscaling, tresholding and thinning are few process that generally included in processing and analysis step. Thinning is an image-processing operation in which binary valued image regions are reduced to lines that approximate the center lines, or skeletons of the regions. Thinning operation has several definitions. Iterative morphological method is one of those definitions. This operation is being done by doing a deletion process to some pixels that have a match to some templates. Stentiford algorithm is an example for this kind of method that can be used. The test shows that Stentiford Thinning Algorithm has some issues and problems. On the test that already done, line fuzz appearance had made input data became visually inappropriate to the assumption and definition for skeleton. Therefore, additional operations are needed to solve these problems.
vii
KATA PENGANTAR
Puji syukur penulis panjatkan ke Tuhan atas berkat dan cinta kasih – Nya, sehingga penulis dapat menyelesaikan penelitian dan penyusunan skripsi berjudul “Algoritma Thinning Stentiford untuk Mendapatkan Bentuk Dasar Huruf”. Skripsi ini disusun sebagai salah satu syarat mencapai gelar Sarjana Sains (S.Si) Program Studi Ilmu Komputer. Dalam pelaksanaan penelitian dan penyusunan skripsi ini tidak terlepas dari bantuan berbagai pihak. Oleh karena itu penulis ucapkan terima kasih kepada: 1. Bapak Y. Joko Nugroho, S.Si selaku dosen pembimbing, terima kasih atas
segala
bimbingan,
saran,
kritik
dan
kesabarannya
dalam
membimbing penulis selama menyelesaikan skripsi ini. 2. Ibu P. H. Prima Rosa, S.Si, M.Sc. , selaku kaprodi ilmu komputer, Terima Kasih sudah menemani kami dan menjadi ibu kedua bagi kami sebagai generasi ikom yang terakhir. 3. Kedua Orang Tuaku, Bapak dan Ibu, Terima kasih atas restu dan dukungan kalian, dan terima kasih atas persediaan kopi yang tak perna habis. 4. Kakak dan Adikku, Anita dan Yoyok, Terima kasih atas dukungan kalian, O..Ya...dan maafkan adik atau kakakmu ini yang telah mengambil jatah waktu komputer kalian. 5. Mas Tukijo dan Mbak Linda, beserta segenap karyawan sekretariat.
viii
6. Mas Susilo, Terima kasih atas bantuannya selama ini. 7. Steven, Thanks Buat Nomer HP nya!!, Ayo buruan nyusul. 8. Komunitas Lab, Gurit, Lilik, Iyus, Hendro, Ferry, Yus,Terima Kasih untuk sentilan – sentilan kalian. 9. Komunitas Triple3Bugs, Angga, Aryo`, Cnug, DC, Evan, Krena, Emon, Miko, Kotank....hei kapan kita ngumpul lagi?, “Ayo...Ngopi neng Code!”, terima kasih sudah menjadi pengobat stress di masa – masa beratku. 10. Teman – Teman IKOM angkatan 2004, Seto, Thomas, Kornel, Beni Dam, Henry, Ipunk, Hali, Githa, Mia, Tina, Arum, Bli, Adit, Steven, Debi, Pakdhe (ndari), Yo, Dewi, Amel, Munik, Via, Fitria, Madya, Willy, Trivo, Agung, Elin, Eka, Desi, Terima kasih atas dukungan dan kerjasama kalian selama ini. 11. Lielie, Sobat jauhku, Terima kasih untuk dorongan semangat yang kau beri tanpa henti. 12. Dan pihak – pihak yang belum dapat penulis sebutkan. Penulis menyadari bahwa skripsi ini masih jauh dari sempurna. Harapan penulis semoga skripsi ini bermanfaat bagi kemajuan kita semua. Yogyakarta, Juli 2008 Penulis
Leonardus Beni Aji Prabangkoro
ix
PERNYATAAN KEASLIAN KARYA
Saya menyatakan dengan sesungguhnya bahwa skripsi yang saya tulis ini tidak memuat dan menggunakan hasil karya atau bagian dari hasil karya orang lain, kecuali yang telah tercantum dan disebutkan dalam kutipan serta daftar pustaka sebagaimana layaknya karya ilmiah.
Yogyakarta,
Juli 2008
Penulis
Leonardus Beni Aji Prabangkoro
x
DAFTAR ISI
HALAMAN JUDUL ...........................................................................................
i
HALAMAN PERSETUJUAN PEMBIMBING ..............................................
ii
HALAMAN PENGESAHAN ............................................................................
iii
HALAMAN MOTTO ........................................................................................
iv
HALAMAN PERSEMBAHAN .........................................................................
v
ABSTRAK ..........................................................................................................
vi
ABSTRACT ........................................................................................................
vii
KATA PENGANTAR ........................................................................................
viii
HALAMAN KEASLIAN KARYA ...................................................................
x
DAFTAR ISI .......................................................................................................
xi
DAFTAR TABEL ...............................................................................................
xiv
DAFTAR GAMBAR ..........................................................................................
xv
BAB I PENDAHULUAN ...................................................................................
1
1.1. Latar Belakang ...................................................................................
1
1.2. Perumusan Masalah ..........................................................................
2
1.3. Batasan Masalah ................................................................................
2
1.4. Tujuan Dan Manfaat Penelitian .......................................................
3
1.5. Metode Penulisan ...............................................................................
3
1.6. Sistematika Penulisan ........................................................................
4
BAB II DASAR TEORI .....................................................................................
6
2.1 Citra .....................................................................................................
6
2.1.1. Pengertian Citra ....................................................................
6
2.1.2. Format Citra Digital .............................................................
6
2.2. Pemrosesan Citra ...............................................................................
8
2.3. Thinning .............................................................................................
9
xi
2.3.1. Pengertian Thinning .............................................................
9
2.3.2. Definisi Thinning ...................................................................
10
2.4. Algoritma Thinning Stentiford .........................................................
14
BAB III ANALISA DAN PERANCANGAN ...................................................
19
3.1. Rancangan Umum .............................................................................
19
3.2. Perancangan Proses Dalam Aplikasi ...............................................
19
3.2.1. Proses Input Citra .................................................................
20
3.2.2. Proses Grayscaling ................................................................
20
3.2.3. Proses Binerisasi ...................................................................
21
3.2.4. Proses penduplikasian citra ke dalam bentuk array 2 dimensi ...................................................................................
21
3.2.5. Proses Thinning .....................................................................
22
3.2.6. Proses rekonstruksi array 2 dimensi ke dalam bentuk citra .........................................................................................
22
3.3. Kebutuhan Perangkat Lunak ...........................................................
23
3.4. Kebutuhan Perangkat Keras ............................................................
23
3.5. Perancangan Tampilan Antar Muka ...............................................
23
3.5.1. Form Tampilan Awal ............................................................
24
3.5.2. Form Menu Utama (Tampilan Utama) ...............................
24
3.5.3. Form Penampil Citra Input .................................................
25
3.5.4. Form Penampil Citra Hasil Olahan ....................................
25
3.5.5. Form Masukkan Citra ..........................................................
26
3.5.6. Form Simpan Citra ...............................................................
26
3.5.7. Form Dialog ...........................................................................
27
3.5.8. Form Message Box ................................................................
27
BAB IV IMPLEMENTASI ...............................................................................
28
4.1. Deskripsi Kerja Program Secara Umum ........................................
28
4.2. Implementasi Algoritma ...................................................................
30
xii
4.2.1. Algoritma Membuka dan Menampilkan Citra ..................
30
4.2.2. Algoritma Menyimpan Citra ...............................................
30
4.2.3. Algoritma Fungsi Grayscaling ..............................................
30
4.2.4. Algoritma Fungsi Binerisasi .................................................
32
4.2.5. Algoritma Fungsi Duplikasi .................................................
33
4.2.6. Algoritma Fungsi Smoothing ...............................................
34
4.2.7. Algoritma Fungsi Acute Angle Emphasis ............................
36
4.2.8. Algoritma Fungsi Thinning Stentiford ................................
40
4.2.9. Algoritma Fungsi Rekonstruksi Citra .................................
47
4.2.10. Algoritma Utama .................................................................
48
4.3. Implementasi Antarmuka Tampilan ................................................
49
4.4. Pengujian Program ............................................................................
54
BAB V PENUTUP ............................................................................................... 61 5.1. Kesimpulan .........................................................................................
61
5.2. Saran ....................................................................................................
61
DAFTAR PUSTAKA .......................................................................................... 63 LAMPIRAN ......................................................................................................... 65
xiii
DAFTAR TABEL
Tabel 4.1 Daftar Hasil Pengujian..........................................................................
xiv
58
DAFTAR GAMBAR
Gambar 2.1. Contoh kombinasi elemen Red, Green dan Blue ...........................
7
Gambar 2.2. Contoh hasil Medial Axis Tranform seperti yang diuraikan J.R. Parker (1997) ................................................................................. 11 Gambar 2.3. Contoh iterasi pada huruf T yang terjadi dalam algoritma Stentiford seperti yang diungkapkan oleh J.R. Parker (1997) ......
12
Gambar 2.4. Ilustrasi polygon dan kerangkanya seperti yang diungkapkan oleh J.R. Parker (1997) ...............................................................
13
Gambar 2.5. Template yang digunakan Stentiford ............................................. 14 Gambar 2.6. Ilustrasi konektivitas piksel tengah dengan 8 piksel disekitarnya .
16
Gambar 2.7. Posisi nomor setiap delapan anggota tetangga ..............................
17
Gambar 2.8. Template yang digunakan oleh prosedur Acute Angle Emphasis.... 18 Gambar 3.1. Gambaran Proses Secara Umum ....................................................
20
Gambar 3.2. Gambaran Proses Level 1 ..............................................................
20
Gambar 3.3. Variabel yang bertipe Tbitmap di-scan dan diambil nilai RGBnya yang kemudian akan dilakukan penghitungan. ......................
21
Gambar 3.4. Gambar yang sudah dalam bentuk grayscale di-scan kembali untuk dikonversi menjadi gambar biner ........................................ 21 Gambar 3.5. Variabel bitmap yang sudah dalam format warna 1bit kemudian diduplikasi ke dalam bentuk array 2 dimensi ................................ 22 Gambar 3.6. Proses Thinning yang didahului dengan smoothing dan AAE .......
22
Gambar 3.7. Rekonstruksi gambar (variabel TBitmap) dari array ......................
23
Gambar 3.8. Tampilan form tampilan awal ......................................................... 24 Gambar 3.9. Tampilan form utama .....................................................................
24
Gambar 3.10. Tampilan Form Penampil Citra Input ........................................... 25 Gambar 3.11. Tampilan Form Penampil Citra hasil olahan ................................ 25 Gambar 3.12. Tampilan form dialog masukkan citra .......................................... 26
xv
Gambar 3.13. Tampilan form dialog simpan citra ..............................................
26
Gambar 3.14. Tampilan form konfirmasi untuk user .......................................... 27 Gambar 3.15. Tampilan form message box ......................................................... 27 Gambar 4.1. Jalannya proses dalam program ..................................................... 28 Gambar 4.2. Tampilan utama dari program .......................................................
50
Gambar 4.3. Tampilan form dialog buka citra ...................................................
51
Gambar 4.4. Tampilan form citra RGB .............................................................
52
Gambar 4.5. Tampilan form peringatan ketika ukuran lebar dan tinggi citra tidak sama .....................................................................................
52
Gambar 4.6. Tampilan form citra yang telah direkonstruksi dari array dan telah melalui proses thinning Stentiford .......................................
53
Gambar 4.7. Tampilan form dialog ketika user ingin menyimpan citra hasil operasi thinning ............................................................................
54
Gambar 4.8. Tampilan form konfirmasi bagi user .............................................
54
Gambar 4.9. Tampilan form tentang program yang menyajikan informasi program .........................................................................................
55
Gambar 4.10 Tampilan form bantuan. Form ini menyajikan hal-hal yang perlu diperhatikan sebelum menjalankan program ................................
xvi
56
BAB I PENDAHULUAN
1.1 LATAR BELAKANG Pengenalan pola karakter merupakan proses pengolahan citra yang diikuti dengan proses penghitungan dengan rumus matematis agar dapat dikenali. Dalam penerapan prinsip pengenalan pola, terkadang citra yang menjadi objek pengenalan mempunyai banyak aspek visual yang dapat dianggap sebagai gangguan, misal seperti noise, ukuran objek yang berbeda, dan lain-lain. Atau dengan kata lain, citra yang menjadi objek pengenalan belum menjadi objek data yang siap olah. Preprocessing, ekstraksi ciri dan klasifikasi adalah garis besar dari proses pengenalan pola yang dikembangkan. Beberapa proses dikembangkan untuk menjadikan objek tersebut menjadi siap olah. Thinning menjadi salah satu aspek dalam preprocessing atau pengolahan citra disamping grayscaling, tresholding, binerisasi dan banyak tahap–tahap lainnya yang dikembangkan. Thinning merupakan tahap dalam preprocessing yang berfungsi untuk menyederhanakan objek dalam citra agar proses penghitungan dan pengolahan selanjutnya menjadi semakin cepat, ringan dan mudah. Tetapi, Thinning sendiri pun belum menjamin apakah data hasil operasi dapat langsung dilakukan pengenalan. Iterative Morphological Method merupakan salah satu dari sekian banyak algoritma thinning yang dikembangkan. Algoritma Stentiford merupakan salah satu
2
contoh dari metode tersebut. Algoritma tersebut menggunakan 4 buah template yang menjadi pedoman pencocokan piksel. 1.2 PERUMUSAN MASALAH Bagaimana mendapatkan kerangka dasar dan sederhana dari sebuah objek citra dengan menggunakan Algoritma stentiford?
1.3 BATASAN MASALAH Ada beberapa batasan dalam jalannya proses penelitian. •
Cakupan materi dari penelitian ini hanya meliputi pembuktian metode dan percobaan implementasi saja.
•
Bahan atau objek dari penelitian adalah berupa citra / gambar objek huruf yang diambil secara offline dengan tipe BMP.
•
Citra yang digunakan mempunyai ukuran / dimensi panjang dan lebar yang sama.
•
Piranti lunak atau bahasa pemrograman yang digunakan Delphi versi 7 dalam implementasi aplikasi.
•
Binerisasi, tresholding, thinning merupakan subbagian dari preprocessing citra. Penelitian ditekankan pada proses thinning saja, meskipun tidak menutup kemungkinan pada proses implementasi dan pengujian aplikasi ada beberapa proses yang mungkin akan tetap dilakukan dengan porsi kecil.
3
1.4 TUJUAN DAN MANFAAT PENELITIAN 1. Tujuan Penelitian •
Mencari dan mengetahui isu atau masalah penting yang berkaitan dengan algoritma Stentiford.
2. Manfaat Penelitian •
Menemukan bentuk atau kerangka yang lebih sederhana dari objek citra yang sebenarnya.
1.5 METODE PENULISAN 1. Analisa metode dan studi pustaka Pada tahap ini akan dilakukan analisa metode yang digunakan dan mencoba mencari pemecahannya, lalu mengumpulkan bahan dengan studi literatur baik dari artikel yang didapat melalui browsing di internet, maupun arsip yang didapat dari hasil studi pada buku – buku acuan. 2. Perancangan aplikasi Perancangan model aplikasi dilakukan pada tahap ini yang meliputi perancangan proses / algoritma, perancangan tampilan / antarmuka. 3. Implementasi Proses implementasi merupakan proses yang menjadi titik awal percobaan / uji apakah hasil studi literatur yang telah kita lakukan telah sesuai dengan
4
jalan / algoritma yang ada. Pada proses ini akan dilakukan pembuatan aplikasi sesuai dengan rancangan yang telah ada pada tahap perancangan aplikasi. 4. Pengujian Proses pengujian merupakan proses dimana aplikasi yang dibuat penulis sebagai hasil studi teori akan diuji. Dalam pengujian ini, Akan digunakan hasil pengujian teori sebagai pembanding yang dilakukan oleh beberapa penulis buku yang menjadi acuan teori. 5. Pembuatan Laporan Tahap terakhir dari proses penelitian adalah pembuatan laporan yang mendokumentasikan semua proses dan hasil yang sudah ditempuh selama penelitian berlangsung.
1.6 SISTEMATIKA PENULISAN BAB I. PENDAHULUAN Dalam Pendahuluan, hal yang akan dibahas meliputi latar belakang masalah, rumusan masalah, batasan masalah, tujuan penulisan, manfaat penulisan, metode penulisan, sistematika penulisan. BAB 2. DASAR TEORI Dasar teori merupakan bab dimana landasan teori tentang hal yang dibahas dan diteliti akan dikupas secara mendalam.
5
BAB 3. ANALISA DAN PERANCANGAN Analisa dan perancangan merupakan bab dimana akan dilakukan analisa terhadap teori yang dipergunakan dan bagaimana proses perancangan terhadap aplikasi. Sehingga pada akhirnya nanti pada saat implementasi, aplikasi yang dibuat tidak akan melenceng dari dasar teori yang digunakan. BAB 4. IMPLEMENTASI Pada tahap implementasi, akan dibuat aplikasi untuk pengujian metode BAB 5. PENUTUP Penutup, akan ditarik kesimpulan tentang hasil dari pengujian yang dilakukan.
BAB 2 DASAR TEORI
2.1 Citra 2.1.1 Pengertian Citra Citra adalah representasi informasi yang diciptakan dalam bentuk 2 dimensi dimana representasi tersebut merupakan susunan array dari bilangan real atau bilangan kompleks yang diwakilkan dalam bilangan–bilangan bit terhingga. Citra adalah gambar pada bidang dwimatra (dua dimensi) (Munir, 2004). Citra ada dua macam : Citra Kontinyu dan Citra Diskrit. Agar sebuah citra dapat diolah dengan komputer digital, maka suatu citra harus direpresentasikan secara numerik dengan nilai–nilai diskrit. Representasi citra dari fungsi malar (kontinyu) menjadi nilai–nilai diskrit disebut digitalisasi citra dan citra yang dihasilkan inilah yang disebut sebagai citra digital. Pada umumnya citra digital berbentuk empat persegi panjang dan dimensi ukurannya dinyatakan sebagai tinggi x lebar (atau lebar x panjang) (Munir, 2004). 2.1.2 Format Citra Digital Menurut intensitas warnanya format citra digital dapat dikategorikan, antara lain : 1. Citra RGB (True Color) Citra RGB merupakan citra yang mempunyai 3 komponen channel yaitu Red, Green, dan Blue. Setiap channel mempunyai nilai intensitas yang berbeda
7
tergantung warna yang akan direpresentasikan. Misal, Untuk merepresentasikan warna Biru Muda, seperti pada gambar 2.1, ada tiga kombinasi tingkat warna Red, Green dan Blue untuk menghasilkan warna biru muda.
Gambar 2.1 : Contoh kombinasi elemen Red, Green dan Blue
2. Citra Grayscale Citra grayscale merupakan citra menggunakan satu fungsi intensitas untuk menentukan warnanya. Fungsi intensitas yang digunakan adalah fungsi intensitas warna keabuan (hitam - putih). Fungsi intensitas warna yang digunakan pada citra grayscale mempunyai kedalaman piksel yang beragam. Tetapi, pada kebanyakan aplikasi, citra grayscale dikuantisasi pada 256 level dan membutuhkan 1 byte (8 bit) untuk representasi setiap pikselnya.
8
3. Citra Biner Citra biner atau yang sering juga disebut citra monokrom merupakan citra yang hanya mempunyai dua nilai kemungkinan warna pada setiap pikselnya. Citra biner hanya dikuantisasikan pada dua level yaitu 0 dan 1, sehingga setiap piksel pada citra cukup direpresentasikan dengan 1 bit (0 atau 1) .
2.2 Pemrosesan Citra Analisa dokumen citra mempunyai tujuan untuk mengenali komponen tulisan dan gambar yang terkandung dalam citra serta mengambil informasi yang ada dalam citra itu sendiri. Analisa citra dokumen mempunyai 2 komponen penting yaitu pemrosesan textual dan pemrosesan grafis. Pemrosesan citra merupakan salah satu tahap dalam analisa dokumen citra yang berfungsi untuk mempersiapkan citra yang akan dianalisa. Pemrosesan citra sendiri mempunyai tujuan agar citra dapat lebih mudah dan lebih cepat untuk diproses. Dalam Pemrosesan citra, beberapa tahap yang akan dilakukan dapat dijabarkan sebagai berikut : 1. Grayscaling Citra grayscale merupakan citra dimana representasi setiap piksel diwakili dengan hanya satu jenis atau satu nilai warna dalam skala keabuan. Untuk mendapatkan
nilai
intensitas
keabuan,
maka
dapat
dihitung
dengan
menjumlahkan 30% dari nilai channel Red pada citra RGB, 59% channel Green,
9
dan 11% channel Blue. Hasil penjumlahan dari setiap elemen tersebut, yang kemudian akan direpresentasikan dalam setiap channel Red, Green dan Blue dengan nilai intensitas yang sama. 2. Tresholding Tresholding atau yang disebut juga sebagai gray – level segmentation (pemisahan warna dalam skala keabuan) merupakan proses pengubahan dari sebuah citra dengan skala keabuan menjadi citra biner atau citra dengan 2 intensitas warna yaitu hitam dan putih. 3. Thinning Thinning atau skeletonization merupakan proses dimana citra yang telah dibinerkan akan direduksi hingga yang tersisa merupakan garis tengah atau kerangka dari objek. Tujuan dari proses thinning adalah mencari informasi dasar dari citra sehingga dapat mempermudah analisis pada tahap selanjutnya.
2.3 Thinning 2.3.1 Pengertian Thinning Secara garis besar, thinning dapat diartikan sebagai proses pereduksian wilayah dari tepi objek berupa citra hingga yang tersisa merupakan garis tengahnya saja atau dapat disebut juga sebagai skeleton atau kerangka. Skeleton atau kerangka oleh J.R. Parker (1997) diasumsikan sebagai representasi bentuk dari suatu objek dalam jumlah piksel yang relatif kecil (sedikit), yang dimana kesemuanya merupakan bagian yang struktural, oleh karena itu representasi itu menjadi dibutuhkan. Sebuah
10
kerangka diharapkan dapat merepresentasikan bentuk dari sebuah objek dalam jumlah piksel yang relatif kecil, yang dimana semuanya saling berkaitan dan merupakan yang terpenting. Dalam garis yang ada pada kerangka, dapat terwakili informasi yang ada pada citra yang sesungguhnya. Dalam konsep yang telah dikembangkan oleh banyak orang, J.R. Parker (1997) mengemukakan bahwa tidak semua objek dapat dikenai operasi thinning, dan hasil dari operasi thinning itu sendiri yang disebut sebagai kerangka mempunyai kemungkinan untuk tidak berfungsi disemua situasi. J.R. Parker (1997) juga mengemukakan bahwa thinning merupakan operasi untuk mengidentifikasi kerangka sebuah objek, operasi thinning itu sendiri tidak didefinisikan oleh algoritma yang digunakan. 2.3.2 Definisi thinning Thinning mempunyai beberapa definisi atau metode berdasarkan uraian yang dikemukakan oleh J.R. Parker (1997), yang diantaranya adalah sebagai berikut : 1. Medial Axis Transform Medial Axis Function (MAF) mungkin merupakan definisi yang diperkenalkan oleh Blum pada tahun 1967. MAF memperlakukan semua batas piksel terluar objek sebagai titik–titik sumber dari wave front (gelombang tepi). Setiap piksel membangkitkan setiap titik tetangganya (titik yang berhubungan) agar menjadi bagian dari wave front. Gelombang ini melewati setiap titik hanya satu kali dan ketika dua gelombang bertemu mereka akan saling membatalkan dan
11
menghasilkan sudut. Medial axis (poros tengah) merupakan tempat dimana sudut itu berada dan saling membentuk skeleton. Metode Medial Axis Transform yang diterapkan pada sebuah objek huruf T dapat diilustrasikan pada gambar 2.2 berikut (J.R. Parker, 1997):
Gambar 2.2 contoh hasil Medial Axis Transform seperti yang diuraikan J.R. Parker (1997)
2. Iterative Morphological Method Mayoritas dari algoritma thinning didasarkan pada penghilangkan lapisan– lapisan piksel hingga tidak ada lagi lapisan yang dapat dihilangkan. Pada penerapannya, ada beberapa aturan yang digunakan dalam penghilangan lapisan piksel. Dan kadang - kadang, proses pencocokan dengan template digunakan untuk mengimplementasikan metode ini. Algoritma thinning Stentiford merupakan salah satu contoh dari metode ini. Penjelasan secara detail dari algoritma Stentiford akan dibahas pada bab ini. Algoritma Stentiford yang diterapkan pada huruf T dapat diilustrasikan pada gambar 2.3 di bawah ini:
12
Gambar 2.3 Contoh iterasi pada huruf T yang terjadi dalam algoritma Stentiford seperti yang diungkapkan oleh J.R. Parker (1997)
3. Contour Based Method Contour Based Method merupakan cara lain dalam mendapatkan kerangka dari sebuah objek. Metode ini bekerja dengan mendeteksi bentuk terluar dari objek. Contour Based Algorithm mempunyai alur inti sebagai berikut : 1. Mendeteksi bagian / bentuk terluar dari objek. 2. Mengidentifikasi piksel dari bagian yang tidak dapat dihapus. 3. Hapus semua bagian piksel kecuali yang telah dideteksi di bagian ke – 2.
13
4. Jika ada bagian piksel yang telah dihapuskan pada langkah 3 , ulangi dari langkah pertama. Metode ini mencoba untuk menyingkirkan penggunaan template 3 x 3 dalam operasinya. 4. Line Following (Line Tracing) Line Following merupakan salah satu metode dalam mengidentifikasi dan mendapatkan kerangka dari objek. Metode ini bekerja dengan menggunakan pointer untuk menentukan arah dari garis. 5. Memperlakukan objek sebagai Polygon Cara lain untuk melakukan operasi thinning dapat dilakukan dengan memperlakukan batas terluar (boundary) objek sebagai polygon sebelum diidentifikasi kerangkanya. Memperlakukan batas luar objek sebagai polygon dapat diilustrasikan dengan gambar 2.4 berikut:
Gambar 2.4 ilustrasi polygon dan kerangkanya seperti yang diungkapkan oleh J.R. Parker (1997)
6. Force Based Thinning Forced
Based
Thinning
juga
merupakan
salah
satu
metode
untuk
mengidentifikasi kerangka objek. Metode ini bekerja, pertama dengan mencari
14
piksel background yang mempunyai setidaknya satu objek piksel sebagai tetangganya dan memberi tanda. Piksel ini akan diasumsikan memberi penekanan gaya berlawanan ke semua objek piksel, semakin dekat jarak piksel disekitarnya dengan piksel yang ditandai ini, maka semakin besar gaya tekan yang akan didapat. Daerah gaya ini dipetakan dengan membagi-bagi daerah menjadi kotakkotak kecil dan menghitung gaya yang bekerja pada sudut-sudut kotak. Kerangka (skeleton) dari objek terletak di dalam kotak yang mempunyai gaya bekerja di sudutnya mempunyai arah yang saling berlawanan.
2.4 Algoritma Thinning Stentiford Algoritma Thinning Stentiford pertama kali diperkenalkan oleh F. W. M. Stentiford dan R. G. Mortimer. Algoritma Stentiford menggunakan template berukuran 3 x 3 untuk melakukan pencocokan dengan citra. Ketika kecocokan terjadi, titik tengah dari piksel 3 x 3 tersebut akan dihapus (diubah warnanya ke warna putih). Algoritma Stentiford menggunakan 4 buah template, yaitu :
M1
M2
M3
M4
Gambar 2.5. Template yang digunakan Stentiford
Tanda X yang dijabarkan pada template mengindikasikan piksel, dimana nilai pada piksel tersebut dapat bernilai 0 maupun 1.
15
Algoritma stentiford dapat dijabarkan sebagai berikut : 1. Cari lokasi piksel (i,j) dimana piksel yang ada di citra I, cocok dengan template M1. 2. Jika titik tengah piksel bukan merupakan endpoint (titik akhir) dan mempunyai indeks konektivitas = 1, maka tandai piksel ini untuk penghapusan. 3. ulangi langkah 1 – 2 untuk semua lokasi piksel yang cocok dengan template M1. 4. ulangi langkah 1 – 3 untuk sisa template yang belum dicocokkan : M2, M3, M4. 5. jika ada piksel yang telah ditandai sebelumnya untuk proses penghapusan, maka hapuskan piksel tersebut dengan mengubahnya menjadi warna putih. 6. jika masih ada piksel yang dapat dihapus pada langkah ke 5, maka ulangi semua proses mulai dari langkah ke – 1, jika tidak berhenti Setiap Template mempunyai fungsi yang berbeda – beda. M1 berfungsi untuk mencari piksel-piksel yang dapat dihilangkan pada bagian tepi atas objek, bergerak dengan arah kiri ke kanan atas ke bawah. M2 akan mencocokkan pada bagian tepi kiri dari objek, template ini bergerak dengan arah dari bawah ke atas, dari kiri ke kanan. M3 akan mencari piksel–piksel sepanjang tepi bawah bergerak dari kanan ke kiri, bawah ke atas. M4 akan mencocokan piksel–piksel pada bagian kanan objek dari atas ke bawah, kanan ke kiri.
16
Dalam proses tersebut, ditemukan beberapa permasalahan. Yaitu ketika proses penghapusan menemui sebuah endpoint. Sebuah piksel disebut Endpoint (Titik ujung) ketika piksel tersebut hanya terhubung dengan 1 piksel diantara 8 piksel disekitarnya. Ketika proses dilakukan dan endpoint tersebut akan dihapus, Semua bagian dari citra yang berupa garis lurus, kurva terbuka akan ikut terhapus. Indeks Konektivitas adalah konsep yang dikembangkan untuk mengurangi masalah tersebut. Indeks Konektivitas merupakan ukuran untuk menentukan seberapa banyak objek akan terhubung dengan sebuah piksel. Untuk menghitung indeks konektivitas dapat digunakan rumus:
C = ∑ N − (N ⋅ N n
k∈s
k
k
k +1
⋅ N k +2 )
Dari konsep konektivitas tersebut, dapat diilustrasikan:
C1
C2
C3
C4
C0
Gambar 2.6 : Ilustrasi konektivitas piksel tengah dengan 8 piksel disekitarnya
Nk merupakan nilai warna dari salah satu dari delapan tetangga piksel yang terlibat, dan S = {1, 3, 5, 7}, N1 adalah nilai warna dari piksel di sebelah kanan dari piksel tengah dan piksel lainnya diberi nomor secara berurutan mengikuti arah jarum jam. Posisi dari setiap delapan anggota piksel yang menjadi tetangga dari piksel pusat, mungkin dapat ditunjukkan dengan gambar 2.7 di bawah ini:
17
Gambar 2.7 Posisi nomor setiap delapan anggota tetangga
Nilai dari Nk adalah 1 jika berwarna putih (Background) dan 0 jika hitam (objek). Dan piksel tengah diberi nomor N0. Dari hasil penghitungan indeks konektivitas, dihasilkan kesimpulan tentang kriteria dari piksel yang dapat dihapus (diubah menjadi putih), yaitu: 1. Jika sebuah piksel tidak terhubung dengan piksel lainnya, maka dapat disimpulkan bahwa indeks konektivitasnya = 1. Ketika indeks konektivitas dari sebuah piksel pusat tersebut bernilai satu maka piksel pusat tersebut dapat dihapus dengan mengesetnya ke warna putih. 2. Indeks konektivitas = 2, piksel nilai konektivitas ini mempunyai keterhubungan dengan 2 buah piksel lain di sekitarnya. Maka ketika piksel ini dihapus akan membuat bagian kiri dan kananya terputus. 3. Indeks konektivitas = 3. 4. Indeks konektivitas = 4. 5. Indeks konektivitas = 0 Dalam perkembangannya Stentiford menyarankan untuk memasukkan tahap preprocessing sebelum dilakukan operasi thinning. Tahap preprocessing tersebut meliputi operasi smoothing dan prosedur acute angle emphasis. Operasi smoothing adalah operasi penghapusan piksel yang mempunyai dua atau kurang tetangga disekitarnya dan mempunyai index konektivitas kurang dari dua. Operasi ini
18
digunakan untuk mengatasi permasalahan tentang line fuzz yang sering muncul di implementasi algoritma Stentiford. Oleh J.R. Parker (1997), diuraikan bahwa line fuzz sering disebabkan oleh bentuk yang tidak biasa dari outline (bagian tepi atau garis tepi) objek. Prosedur acute angle emphasis dilakukan untuk menangani masalah necking pada algoritma. Operasi ini melakukan pencocokan piksel pada citra dengan template acute angle emphasis. Operasi–operasi tersebut dilaksanakan dengan urutan smoothing, acute angle emphasis kemudian baru diikuti oleh operasi thinning. Template yang digunakan dalam prosedur acute angle emphasis adalah seperti pada gambar 2.3 berikut:
D1
U1
D2
D3
D4
D5
U2
U3
U4
U5
Gambar 2.8 Template yang digunakan oleh prosedur Acute Angle Emphasis
BAB III ANALISA DAN PERANCANGAN
3.1.RANCANGAN UMUM Secara umum, program ini menitikberatkan pada proses thinning meskipun dalam proses yang dilakukan meliputi proses grayscaling, binerisasi. Program Simulasi Thinning ini bertujuan memberikan gambaran sebuah proses thinning yang dilakukan dalam proses pengenalan pola. Simulasi ini menggunakan algoritma Stentiford. Proses thinning merupakan proses mengambil bentuk pokok dari suatu objek sebelum dilakukan klasifikasi dalam pengenalan pola. Dalam program ini, gambar yang digunakan merupakan gambar huruf–huruf dan diambil dan dibuat secara offline. Dalam program, gambar tersebut diolah terlebih dahulu dengan grayscaling dan binerisasi.
3.2.PERANCANGAN PROSES DALAM APLIKASI Dalam pemrosesan yang terjadi dalam aplikasi, secara umum proses dibagi menjadi 5 buah proses inti yang dapat diilustrasikan menjadi desain proses secara umum dan Proses Level 1, yaitu:
Gambar 3.1 Gambaran Proses secara umum
20
Gambar 3.2 Gambaran Proses Level 1
3.2.1. Proses input citra. Proses input citra merupakan proses awal dalam program dimana citra di baca oleh sistem. Dalam proses ini, citra dimasukkan oleh user untuk dilakukan simulasi. Proses ini terlebih dahulu dilakukan dengan memilih citra yang telah diambil
secara
offline.
Adapun
cara
yang
dilakukan
dengan
modul
OpenPictureDialog yang telah tersedia dalam Delphi. Input citra berupa citra BMP dengan ukuran dimensi yang sama (MxN, dimana M=N). Setelah dilakukan pemilihan, Citra maka akan ditampilkan dalam program.
3.2.2. Proses grayscaling Proses grayscaling merupakan proses mengubah citra berwarna ke dalam skala keabuan. Proses pengubahan mode citra dilakukan dengan perhitungan per piksel
21
= (0.3 x Red + 0.59 x Green + 0. 11 x Blue) / 3. Setelah dilakukan perhitungan per piksel, hasil yang didapat dari hasil tersebut dimasukkan menjadi nilai setiap piksel yang baru. Proses Grayscaling dapat digambarkan sebagai berikut:
Gambar 3.3 Variabel yang bertipe Tbitmap di-scan dan diambil nilai RGB-nya yang kemudian akan dilakukan penghitungan.
3.2.3. Proses binerisasi Proses binerisasi merupakan proses pengambangan citra menjadi 2 jenis warna yaitu hitam dan putih (0 dan 1). Proses pengambangan dilakukan dengan menentukan batas pengambangan dari hasil penghitungan nilai tengah sebaran histogram citra. Proses Binerisasi dapat digambarkan sebagai berikut:
Gambar 3.4 Gambar yang sudah dalam bentuk grayscale di-scan kembali untuk dikonversi menjadi gambar biner
3.2.4. Proses penduplikasian citra ke dalam bentuk array 2 dimensi Proses penduplikasian citra dilakukan dengan melakukan scanning ke seluruh bagian citra. Proses dilakukan dengan membuat sebuah array 2 dimensi dimana ukuran baris dan kolom dari array tersebut sama dengan ukuran dimensi citra
22
biner. Kemudian, ketika dilakukan scanning ke citra biner tersebut, saat ditemukan warna hitam pada posisi piksel(x,y) di citra maka pada array 2 dimensi di masukkan nilai 0 pada posisi yang sama dengan posisi piksel(x,y) citra. Proses duplikasi citra ke array 2 dimensi dapat digambarkan sebagai berikut:
Gambar 3.5 Variabel bitmap yang sudah dalam format warna 1bit kemudian diduplikasi ke dalam bentuk array 2 dimensi
3.2.5. Proses Thinning Proses Thinning merupakan proses pereduksian dari kulit luar objek. Dalam proses ini, Algoritma Thinning Stentiford digunakan untuk menjalankan proses thinning. Proses ini dapat digambarkan sebagai berikut:
Gambar 3.6 Proses Thinning yang didahului dengan smoothing dan AAE
3.2.6. Proses rekonstruksi array 2 dimensi ke dalam bentuk citra proses rekonstruksi array 2 dimensi ini dilakukan setelah array dimensi dikenai proses thinning. Proses rekonstruksi citra terjadi dengan melakukan scanning pada array 2 dimensi. Ketika dilakukan scanning 2 dimensi, nilai 0 dan 1 yang
23
ditemukan pada posisi baris dan kolom digantikan dengan representasi warna hitam dan putih pada posisi piksel di citra.
Gambar 3.7 Rekonstruksi gambar (variabel TBitmap) dari array
3.3.KEBUTUHAN PERANGKAT LUNAK Kebutuhan perangkat lunak yang digunakan untuk menyelesaikan tugas akhi ini adalah Borland Delphi versi 7 yang dipergunakan untuk membangun program. Photoshop digunakan untuk meng-edit citra yang akan digunakan menguji jalannya program.
3.4.KEBUTUHAN PERANGKAT KERAS Perangkat keras yang digunakan untuk menyelesaikan tugas akhir ini adalah seperangkat komputer dengan spesifikasi : a. Prosesor
: AMD Duron 1,8 Ghz
b. Sistem Operasi
: Microsoft Windows XP
c. Media Tampilan
: VGA 64 Mb
d. Memory
: 256 MB
e. Media Penyimpanan
: Hard Disk 40 GB
f. Scanner
: Scanner Hewlett Packard Scanjet G3010
24
3.5.PERANCANGAN TAMPILAN ANTAR MUKA 3.5.1. Form Tampilan Awal Form tampilan awal merupakan form yang berfungsi untuk menampilkan identitas dari penulis dan dosen pembimbing.
Gambar 3.8 Tampilan form tampilan awal
3.5.2. Form Menu Utama (Tampilan Utama) Form utama merupakan form dimana semua interface dibutuhkan dimunculkan. Form utama berupa MDI (Multiple Document Interface) Form.
Gambar 3.9 Tampilan form utama
25
3.5.3. Form Penampil Citra Input Form Penampil Citra Input merupakan form yang berfungsi untuk menampilkan citra yang telah dipilih oleh user.
Gambar 3.10 Tampilan Form Penampil Citra Input
3.5.4. Form Penampil Citra Hasil Olahan Form Penampil Citra hasil olahan berfungsi untuk menampilkan citra dari hasil pengolahan (Thinning) yang telah dilalui.
Gambar 3.11 Tampilan Form Penampil Citra hasil olahan
26
3.5.5. Form Masukkan Citra Form masukkan Citra merupakan bagian form dialog dimana user diminta untuk mencari dan memilih sendiri citra yang akan diolah.
Gambar 3.12 Tampilan form dialog masukkan citra
3.5.6. Form Simpan Citra Form Simpan Citra merupakan Bagian dari form dialog dimana user dapat menyimpan hasil dari proses thinning yang telah dilakukan.
Gambar 3.13 Tampilan form dialog simpan citra
27
3.5.7. Form Dialog Form Dialog berfungsi untuk menyampaikan pesan dan membutuhkan konfirmasi dari user.
Gambar 3.14 Tampilan form konfirmasi untuk user
3.5.8. Form Message Box Form message Box berfungsi untuk menampilkan pesan – pesan dari program.
Gambar 3.15 Tampilan form message box
BAB IV IMPLEMENTASI
4.1. DESKRIPSI KERJA PROGRAM SECARA UMUM Secara umum, Program dirancang untuk menjalankan implementasi algoritma thinning Stentiford, diluar algoritma tersebut hanya merupakan sub-sub program yang berfungsi untuk membuat jalan program menjadi lancar dan efisien. Adapun alur kerja program dapat digambarkan dengan alur sebagai berikut:
Gambar 4.1 Jalanya proses dalam program
Dari ilustrasi alur program dapat dijelaskan, program berjalan dengan diawali pengambilan (pengaksesan) citra truecolor 24bit. Setelah pengaksesan dilakukan,
29
citra akan diperiksa apakah telah sesuai dengan syarat yang telah ditentukan, apabila citra memenuhi syarat maka citra tersebut akan dimasukkan ke dalam variabel bitmap. Pada proses selanjutnya, variabel bitmap tersebut dikenai operasi grayscaling, binerisasi dan duplikasi. Operasi
graycaling merupakan operasi
pengubahan format citra yang semula RGB(Red, Green, Blue) menjadi format citra grayscale. Operasi binerisasi merupakan operasi pengubahan format citra grayscale menjadi format citra biner. Dari operasi grayscaling dan binerisasi yang telah dijalankan, akan menghasilkan sebuah citra biner yang masih bertipe data bitmap. Untuk dapat menjadikannya lebih mudah dan cepat untuk diolah maka perlu diubah bentuknya menjadi sebuah array 2 dimensi yang berelemen 0 dan 1 sebagai wakil dari citra biner. Operasi duplikasi dijalankan untuk memenuhi kebutuhan tersebut akan format citra dalam bentuk array 2 dimensi. Operasi duplikasi menghasilkan data dalam bentuk record yang berisi nilai dimensi citra dan array 2 dimensi yang mewakili citra biner. Dari data hasil duplikasi tersebut digunakan untuk operasi smoothing, aae (acute angle emphasis), thinning. Setelah ketiga operasi dijalankan didapatkan sebuah record yang berisi array 2 dimensi hasil dari operasi thinning. Untuk dapat menampilkan array tersebut, maka perlu dilakukan rekonstruksi array tersebut menjadi variabel bitmap. Operasi Rekonstruksi digunakan untuk merekonstruksi array tersebut dalam bentuk variabel bitmap agar dapat ditampilkan. Untuk menjalankan program, beberapa hal yang perlu dipersiapakan antara lain sebuah file citra dengan ekstensi *.BMP, citra tersebut mempunyai ukuran
30
dimensi yang sama. Yang dimaksud dengan ukuran dimensi yang sama adalah ukuran panjang dan lebar (lebar dan tinggi) harus sama.
4.2. IMPLEMENTASI ALGORITMA 4.2.1. Algoritma membuka dan menampilkan Citra Untuk mengambil dan menggunakan gambar tertentu, maka digunakan: Application.CreateForm(TView,View); View.GBR.Picture.LoadFromFile(Utama.Buka_Gambar_Dialog.FileName); View.Show;
Algoritma untuk membuka dan menampilkan citra merupakan algoritma yang menggunakan fungsi dasar dalam Delphi. Prosedur yang menggunakan fungsi ini dijalankan ketika user akan memulai mengoperasikan program.
4.2.2. Algoritma Menyimpan Citra Utama.Simpan_Gambar_Dialog.DefaultExt:= GraphicExtension(TBitmap); View_Thin.GBR.Picture.Bitmap.SaveToFile(Utama.Simpan_Gambar_Dialog.FileName+' .'+Utama.Simpan_Gambar_Dialog.DefaultExt);
Proses penyimpanan citra merupakan proses yang dijalankan atau dioperasikan pada tahap akhir program. Proses ini merupakan prosedur pilihan yang dapat dijalankan dapat juga tidak, sesuai dengan keinginan user.
4.2.3. Algoritma Fungsi Grayscaling function grayscaling(var gbrIn:TBitmap):TBitmap; Var GbrTmp:TBitmap;
31
i,j,GrayVal :Cardinal; pixArrRGB,pixArrGrey:Pbytearray; Begin GbrTmp:=TBitmap.Create; GbrIn.PikselFormat:=pf24bit; Try With GbrTmp Do Begin PikselFormat:=pf8bit; Height:=gbrIn.Height; Width:=gbrIn.Width; End; for i:=0 to gbrIn.height-1 do begin pixArrRGB:=gbrIn.ScanLine[i]; pixArrGrey:=GbrTmp.ScanLine[i]; for j:=0 to gbrIn.width-1 do begin GrayVal:=round((pixArrRGB[j*3]) * 0.11)+round((pixArrRGB[j*3+1]) * 0.59)+round((pixArrRGB[j*3+2]) * 0.3); pixArrGrey[j]:= GrayVal; end end; GbrTmp.PikselFormat:=pf8bit; //digunakan seandainya GbrTmp.PikselFormat masih pf24bit grayscaling:=GbrTmp Finally End; End; {akhir dari fungsi grayscale}
Proses grayscaling merupakan proses yang harus dijalankan. Proses ini berguna untuk mengkonversi citra yang semula merupakan citra truecolor 24 bit menjadi citra grayscale 8 bit. Sesuai dengan alur kerja program, fungsi operasi citra ini dijalankan paling awal diantara operasi citra–citra yang lain yaitu tresholding (dalam pembahasan ini adalah binerisasi), Thinning. Proses berjalan dengan melakukan scanning ke setiap piksel pada citra kemudian menggambil nilai Red, Green dan Blue untuk dilakukan penghitungan nilai grayscale. Perhitungan yang dilakukan menggunakan 11% Nilai Blue, 59% Nilai Green, 30% Nilai Red.
32
4.2.4. Algoritma Fungsi Binerisasi function binerisasi(var gbrIn:TBitmap):TBitmap; Var GbrTmp:TBitmap; i,j:Cardinal; pixArrBin,pixArrGrey:Pbytearray; Begin GbrTmp:=Tbitmap.create; GbrIn.PikselFormat:=pf8bit; Try With GbrTmp Do Begin PikselFormat:=pf8bit; Height:=gbrIn.Height; Width:=gbrIn.Width; End; for i:=0 to gbrIn.height-1 do begin pixArrGrey:=gbrIn.ScanLine[i]; for j:=0 to gbrIn.width-1 do begin if pixArrGrey[j]>=128then begin //pixArrBin[j]:=255 GbrTmp.Canvas.Piksels[j,i]:=255; //sama aja dengan yang diatas end else if pixArrGrey[j]<128then //pixArrBin[j]:=0; GbrTmp.Canvas.Piksels[j,i]:=0; //sama aja dengan yang diatas end; end; GbrTmp.PikselFormat:=pf1bit; binerisasi:=GbrTmp; Finally GbrIn.Free; End End; {akhir dari fungsi binerisasi}
Proses binerisasi merupakan proses setelah grayscale dimana fungsi ini berfungsi untuk mengkonversi citra grayscale 8 bit menjadi citra monokrom (biner) 1 bit. Proses binerisasi berjalan dengan operasi tresholding dimana nilai ambang yang diambil adalah 128.
33
4.2.5. Algoritma Fungsi Duplikasi Function Duplikasi(var Gbr_2Klon:TBitmap):TBinData; var x,y,H,W:cardinal; klon_out:TBinData; Begin Try H:=Gbr_2Klon.Height; W:=Gbr_2Klon.Width; klon_out.Tinggi:=H; klon_out.Lebar:=W; SetLength(klon_out.Kloning,H,W);//ngeset variabel dinamis array [baris] For x:=Low(klon_out.Kloning) to High(klon_out.Kloning) do//mengakses index X dari yang terendah ke yg tertinggi Begin //SetLength(klon_out.Kloning[x],W);//ngeset Besar array[baris][Kolom] For y:=Low(klon_out.Kloning[x]) to High(klon_out.Kloning[x]) do //mengakses kolom X dgn index Y dari yang terendah ke yg tertinggi Begin if Gbr_2Klon.Canvas.Piksels[x,y]=clBlack then Begin klon_out.Kloning[x,y]:=0; End Else klon_out.Kloning[x,y]:=1; //akhir else if End;//akhir For2 End;//akhir For1 Finally Duplikasi:=klon_out; //parse kluar hasil kloning, yang nantinya akan dicek_THin End; End;//akhir function Duplikasi
Proses duplikasi merupakan proses penduplikasian citra hasil operasi binerisasi menjadi array 2 dimensi yang mempunyai ke-identikan dalam susunan nilai elemen array dan nilai piksel yang ada dalam matriks citra. Fungsi duplikasi menghasilkan output yang berupa record dengan isi nilai tinggi dan lebar dari citra, serta array hasil duplikasi dari citra biner. Proses yang terjadi dalam duplikasi merupakan proses dimana program melakukan deteksi pada canvas citra dan mengklasifikasikan warna yang ada ke dalam array 2 dimensi.
34
4.2.6. Algoritma Fungsi Smoothing function smoothing(var Gbr_4Thin:TBinData):TBinData; var //variabel local Gbr_Buffer : Array of array of byte; i, j,endpoint_counter :cardinal; konektivitas,Nk1,Nk3,Nk5,Nk7: integer; Begin setLength(Gbr_Buffer,Gbr_4Thin.Tinggi,Gbr_4Thin.Lebar); //t4 mencatat yang akan disetPutih for i:=low(Gbr_Buffer)+1 to High(Gbr_Buffer)-1 do //baris Begin for j:=low(Gbr_Buffer[i])+1 to High(Gbr_Buffer[i])-1 do //kolom Begin Gbr_buffer[i,j]:=0; End End; for i:=low(Gbr_4Thin.Kloning)+1 to High(Gbr_4Thin.Kloning)-1 do //baris Begin for j:=low(Gbr_4Thin.Kloning[i])+1 to High(Gbr_4Thin.Kloning[i])-1 do //kolom Begin if Gbr_4Thin.Kloning[i,j]=0 Then Begin konektivitas:=0;Nk1:=0;Nk3:=0;Nk5:=0;Nk7:=0; Nk1:=Gbr_4Thin.Kloning[i,j+1]((Gbr_4Thin.Kloning[i,j+1])*(Gbr_4Thin.Kloning[i+1,j+1])*(Gbr_4Thin.Kloning[i+1,j])); Nk3:=Gbr_4Thin.Kloning[i+1,j]((Gbr_4Thin.Kloning[i+1,j])*(Gbr_4Thin.Kloning[i+1,j-1])*(Gbr_4Thin.Kloning[i,j-1])); Nk5:=Gbr_4Thin.Kloning[i,j-1]-((Gbr_4Thin.Kloning[i,j-1])*(Gbr_4Thin.Kloning[i1,j-1])*(Gbr_4Thin.Kloning[i-1,j])); Nk7:=Gbr_4Thin.Kloning[i-1,j]-((Gbr_4Thin.Kloning[i-1,j])*(Gbr_4Thin.Kloning[i1,j+1])*(Gbr_4Thin.Kloning[i,j+1])); //zigmaNK:=Nk1+Nk3+Nk5+Nk7; konektivitas:=(Nk1)+(Nk3)+(Nk5)+(Nk7); //pembuktian EndPoint==============================// endpoint_counter:=0; if Gbr_4Thin.Kloning[i,j+1]=0 then //N1 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j+1]=0 then //N2 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j]=0 then //N3 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j-1]=0 then //N4 Begin endpoint_counter:=endpoint_counter+1;
35
End; if Gbr_4Thin.Kloning[i,j-1]=0 then //N5 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j-1]=0 then //N6 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j]=0 then //N7 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j+1]=0 then //N8 Begin endpoint_counter:=endpoint_counter+1; End; //pembuktian EndPoint===========================// //pencocokan konektivitas=========================// if (konektivitas=2) and (endpoint_counter<=2) then Begin Gbr_Buffer[i,j]:=2; End;//akhir if2 End;//akhir if1 //pencocokan konektivitas=========================// End//akhir for2 End;//akhir for1 for i:=low(Gbr_Buffer) to High(Gbr_Buffer) do //baris Begin for j:=low(Gbr_Buffer[i]) to High(Gbr_Buffer[i]) do //kolom Begin if Gbr_Buffer[i,j]=2 then Begin //count:=count+1; Gbr_4Thin.Kloning[i,j]:=1; End; if i=low(Gbr_Buffer) Then //ngeset paling tepi Begin Gbr_4Thin.Kloning[i,j]:=1; End; if i=High(Gbr_Buffer) Then //ngeset paling tepi Begin Gbr_4Thin.Kloning[i,j]:=1; End; if j=low(Gbr_Buffer[i]) Then //ngeset paling tepi Begin Gbr_4Thin.Kloning[i,j]:=1; End; if j=High(Gbr_Buffer[i]) Then //ngeset paling tepi Begin Gbr_4Thin.Kloning[i,j]:=1;
36
End; End //akhir dari for2 End;//akhir dari for1 Smoothing:=Gbr_4Thin; //hasil dari smoothing di parse keluar fungsi End;//akhir fungsi smoothing
Smoothing merupakan proses yang disarankan oleh Stentiford untuk dijalankan, fungsi ini berguna untuk menghilangkan permasalahan yang sering timbul dalam hasil algoritma thinning stentiford, permasalahan tersebut adalah line fuzz. Smoothing beroperasi dengan mencari piksel yang mempunyai nilai konektivitas 2 dan mempunyai keterhubungan dengan tetangganya maksimal 2. 4.2.7. Algoritma Fungsi Acute Angle Emphasis (AAE) function acute_angle_emphasis(var gbr_msk:TBinData):TBinData; var Gbr_Buffer : Array of array of byte; i, j:cardinal; Begin setLength(Gbr_Buffer,gbr_msk.Tinggi,gbr_msk.Lebar); for i:=low(Gbr_Buffer)+2 to High(Gbr_Buffer)-2 do Begin for j:=low(Gbr_Buffer)+2 to High(gbr_Buffer)-2 do Begin {D template} {D1}if {/1/}(gbr_msk.Kloning[i-2,j-2]=0) and (gbr_msk.Kloning[i-2,j-1]=0) and (gbr_msk.Kloning[i-2,j]=1) and (gbr_msk.Kloning[i-2,j+1]=0) and (gbr_msk.Kloning[i2,j+2]=0) and{/2/}(gbr_msk.Kloning[i-1,j-2]=0) and (gbr_msk.Kloning[i-1,j-1]=0) and (gbr_msk.Kloning[i-1,j]=1) and (gbr_msk.Kloning[i-1,j+1]=0) and (gbr_msk.Kloning[i1,j+2]=0) and{/3/} (gbr_msk.Kloning[i,j-2]=0) and (gbr_msk.Kloning[i,j-1]=0) and (gbr_msk.Kloning[i,j]=0) and (gbr_msk.Kloning[i,j+1]=0) and (gbr_msk.Kloning[i,j+2]=0) and{/4/} (gbr_msk.Kloning[i+1,j-2]=0) and (gbr_msk.Kloning[i+1,j-1]=0) and (gbr_msk.Kloning[i+1,j]=0) and (gbr_msk.Kloning[i+1,j+1]=0) and (gbr_msk.Kloning[i+1,j+2]=0) and{/5/}(gbr_msk.Kloning[i+2,j-1]=0) and (gbr_msk.Kloning[i+2,j]=0) and (gbr_msk.Kloning[i+2,j+1]=0) then Begin Gbr_Buffer[i,j]:=0; End; {D2}if {/1/}(gbr_msk.Kloning[i-2,j-2]=0) and (gbr_msk.Kloning[i-2,j-1]=1) and (gbr_msk.Kloning[i-2,j]=1) and (gbr_msk.Kloning[i-2,j+1]=0) and (gbr_msk.Kloning[i2,j+2]=0) and{/2/}(gbr_msk.Kloning[i-1,j-2]=0) and (gbr_msk.Kloning[i-1,j-1]=0) and (gbr_msk.Kloning[i-1,j]=1) and (gbr_msk.Kloning[i-1,j+1]=0) and (gbr_msk.Kloning[i1,j+2]=0) and{/3/} (gbr_msk.Kloning[i,j-2]=0) and (gbr_msk.Kloning[i,j-1]=0) and (gbr_msk.Kloning[i,j]=0) and (gbr_msk.Kloning[i,j+1]=0) and (gbr_msk.Kloning[i,j+2]=0)
37
and{/4/} (gbr_msk.Kloning[i+1,j-2]=0) and (gbr_msk.Kloning[i+1,j-1]=0) and (gbr_msk.Kloning[i+1,j]=0) and (gbr_msk.Kloning[i+1,j+1]=0) and (gbr_msk.Kloning[i+1,j+2]=0) and{/5/}(gbr_msk.Kloning[i+2,j-1]=0) and (gbr_msk.Kloning[i+2,j]=0) and (gbr_msk.Kloning[i+2,j+1]=0) then Begin Gbr_Buffer[i,j]:=0; End; {D3}if {/1/}(gbr_msk.Kloning[i-2,j-2]=0) and (gbr_msk.Kloning[i-2,j-1]=0) and (gbr_msk.Kloning[i-2,j]=1) and (gbr_msk.Kloning[i-2,j+1]=1) and (gbr_msk.Kloning[i2,j+2]=0) and{/2/}(gbr_msk.Kloning[i-1,j-2]=0) and (gbr_msk.Kloning[i-1,j-1]=0) and (gbr_msk.Kloning[i-1,j]=1) and (gbr_msk.Kloning[i-1,j+1]=0) and (gbr_msk.Kloning[i1,j+2]=0) and{/3/} (gbr_msk.Kloning[i,j-2]=0) and (gbr_msk.Kloning[i,j-1]=0) and (gbr_msk.Kloning[i,j]=0) and (gbr_msk.Kloning[i,j+1]=0) and (gbr_msk.Kloning[i,j+2]=0) and{/4/} (gbr_msk.Kloning[i+1,j-2]=0) and (gbr_msk.Kloning[i+1,j-1]=0) and (gbr_msk.Kloning[i+1,j]=0) and (gbr_msk.Kloning[i+1,j+1]=0) and (gbr_msk.Kloning[i+1,j+2]=0) and{/5/}(gbr_msk.Kloning[i+2,j-1]=0) and (gbr_msk.Kloning[i+2,j]=0) and (gbr_msk.Kloning[i+2,j+1]=0) then Begin Gbr_Buffer[i,j]:=0; End; {D4}if {/1/}(gbr_msk.Kloning[i-2,j-2]=0) and (gbr_msk.Kloning[i-2,j-1]=1) and (gbr_msk.Kloning[i-2,j]=1) and (gbr_msk.Kloning[i-2,j+1]=0) and (gbr_msk.Kloning[i2,j+2]=0) and{/2/}(gbr_msk.Kloning[i-1,j-2]=0) and (gbr_msk.Kloning[i-1,j-1]=1) and (gbr_msk.Kloning[i-1,j]=1) and (gbr_msk.Kloning[i-1,j+1]=0) and (gbr_msk.Kloning[i1,j+2]=0) and{/3/} (gbr_msk.Kloning[i,j-2]=0) and (gbr_msk.Kloning[i,j-1]=0) and (gbr_msk.Kloning[i,j]=0) and (gbr_msk.Kloning[i,j+1]=0) and (gbr_msk.Kloning[i,j+2]=0) and{/4/} (gbr_msk.Kloning[i+1,j-2]=0) and (gbr_msk.Kloning[i+1,j-1]=0) and (gbr_msk.Kloning[i+1,j]=0) and (gbr_msk.Kloning[i+1,j+1]=0) and (gbr_msk.Kloning[i+1,j+2]=0) and{/5/}(gbr_msk.Kloning[i+2,j-1]=0) and (gbr_msk.Kloning[i+2,j]=0) and (gbr_msk.Kloning[i+2,j+1]=0) then Begin Gbr_Buffer[i,j]:=0; End; {D5}if {/1/}(gbr_msk.Kloning[i-2,j-2]=0) and (gbr_msk.Kloning[i-2,j-1]=0) and (gbr_msk.Kloning[i-2,j]=1) and (gbr_msk.Kloning[i-2,j+1]=1) and (gbr_msk.Kloning[i2,j+2]=0) and{/2/}(gbr_msk.Kloning[i-1,j-2]=0) and (gbr_msk.Kloning[i-1,j-1]=0) and (gbr_msk.Kloning[i-1,j]=1) and (gbr_msk.Kloning[i-1,j+1]=1) and (gbr_msk.Kloning[i1,j+2]=0) and{/3/} (gbr_msk.Kloning[i,j-2]=0) and (gbr_msk.Kloning[i,j-1]=0) and (gbr_msk.Kloning[i,j]=0) and (gbr_msk.Kloning[i,j+1]=0) and (gbr_msk.Kloning[i,j+2]=0) and{/4/} (gbr_msk.Kloning[i+1,j-2]=0) and (gbr_msk.Kloning[i+1,j-1]=0) and (gbr_msk.Kloning[i+1,j]=0) and (gbr_msk.Kloning[i+1,j+1]=0) and (gbr_msk.Kloning[i+1,j+2]=0) and{/5/}(gbr_msk.Kloning[i+2,j-1]=0) and (gbr_msk.Kloning[i+2,j]=0) and (gbr_msk.Kloning[i+2,j+1]=0) then Begin Gbr_Buffer[i,j]:=0; End; {U template} {U1}if {/1/} (gbr_msk.Kloning[i-2,j-1]=0) and (gbr_msk.Kloning[i-2,j]=0) and (gbr_msk.Kloning[i-2,j+1]=0) and{/2/}(gbr_msk.Kloning[i-1,j-2]=0) and (gbr_msk.Kloning[i-1,j-1]=0) and (gbr_msk.Kloning[i-1,j]=0) and (gbr_msk.Kloning[i1,j+1]=0) and (gbr_msk.Kloning[i-1,j+2]=0) and{/3/} (gbr_msk.Kloning[i,j-2]=0) and
38
(gbr_msk.Kloning[i,j-1]=0) and (gbr_msk.Kloning[i,j]=0) and (gbr_msk.Kloning[i,j+1]=0) and (gbr_msk.Kloning[i,j+2]=0) and{/4/} (gbr_msk.Kloning[i+1,j-2]=0) and (gbr_msk.Kloning[i+1,j-1]=0) and (gbr_msk.Kloning[i+1,j]=1) and (gbr_msk.Kloning[i+1,j+1]=0) and (gbr_msk.Kloning[i+1,j+2]=0) and{/5/}(gbr_msk.Kloning[i+2,j-2]=0) and (gbr_msk.Kloning[i+2,j-1]=0) and (gbr_msk.Kloning[i+2,j]=1) and (gbr_msk.Kloning[i+2,j+1]=0) and (gbr_msk.Kloning[i+2,j+2]=0) then Begin Gbr_Buffer[i,j]:=0; End; {U2}if {/1/} (gbr_msk.Kloning[i-2,j-1]=0) and (gbr_msk.Kloning[i-2,j]=0) and (gbr_msk.Kloning[i-2,j+1]=0) and{/2/}(gbr_msk.Kloning[i-1,j-2]=0) and (gbr_msk.Kloning[i-1,j-1]=0) and (gbr_msk.Kloning[i-1,j]=0) and (gbr_msk.Kloning[i1,j+1]=0) and (gbr_msk.Kloning[i-1,j+2]=0) and{/3/} (gbr_msk.Kloning[i,j-2]=0) and (gbr_msk.Kloning[i,j-1]=0) and (gbr_msk.Kloning[i,j]=0) and (gbr_msk.Kloning[i,j+1]=0) and (gbr_msk.Kloning[i,j+2]=0) and{/4/} (gbr_msk.Kloning[i+1,j-2]=0) and (gbr_msk.Kloning[i+1,j-1]=0) and (gbr_msk.Kloning[i+1,j]=1) and (gbr_msk.Kloning[i+1,j+1]=0) and (gbr_msk.Kloning[i+1,j+2]=0) and{/5/}(gbr_msk.Kloning[i+2,j-2]=0) and (gbr_msk.Kloning[i+2,j-1]=1) and (gbr_msk.Kloning[i+2,j]=1) and (gbr_msk.Kloning[i+2,j+1]=0) and (gbr_msk.Kloning[i+2,j+2]=0) then Begin Gbr_Buffer[i,j]:=0; End; {U3}if {/1/} (gbr_msk.Kloning[i-2,j-1]=0) and (gbr_msk.Kloning[i-2,j]=0) and (gbr_msk.Kloning[i-2,j+1]=0) and{/2/}(gbr_msk.Kloning[i-1,j-2]=0) and (gbr_msk.Kloning[i-1,j-1]=0) and (gbr_msk.Kloning[i-1,j]=0) and (gbr_msk.Kloning[i1,j+1]=0) and (gbr_msk.Kloning[i-1,j+2]=0) and{/3/} (gbr_msk.Kloning[i,j-2]=0) and (gbr_msk.Kloning[i,j-1]=0) and (gbr_msk.Kloning[i,j]=0) and (gbr_msk.Kloning[i,j+1]=0) and (gbr_msk.Kloning[i,j+2]=0) and{/4/} (gbr_msk.Kloning[i+1,j-2]=0) and (gbr_msk.Kloning[i+1,j-1]=0) and (gbr_msk.Kloning[i+1,j]=1) and (gbr_msk.Kloning[i+1,j+1]=0) and (gbr_msk.Kloning[i+1,j+2]=0) and{/5/}(gbr_msk.Kloning[i+2,j-2]=0) and (gbr_msk.Kloning[i+2,j-1]=0) and (gbr_msk.Kloning[i+2,j]=1) and (gbr_msk.Kloning[i+2,j+1]=1) and (gbr_msk.Kloning[i+2,j+2]=0) then Begin Gbr_Buffer[i,j]:=0; End; {U4}if {/1/} (gbr_msk.Kloning[i-2,j-1]=0) and (gbr_msk.Kloning[i-2,j]=0) and (gbr_msk.Kloning[i-2,j+1]=0) and{/2/}(gbr_msk.Kloning[i-1,j-2]=0) and (gbr_msk.Kloning[i-1,j-1]=0) and (gbr_msk.Kloning[i-1,j]=0) and (gbr_msk.Kloning[i1,j+1]=0) and (gbr_msk.Kloning[i-1,j+2]=0) and{/3/} (gbr_msk.Kloning[i,j-2]=0) and (gbr_msk.Kloning[i,j-1]=0) and (gbr_msk.Kloning[i,j]=0) and (gbr_msk.Kloning[i,j+1]=0) and (gbr_msk.Kloning[i,j+2]=0) and{/4/} (gbr_msk.Kloning[i+1,j-2]=0) and (gbr_msk.Kloning[i+1,j-1]=1) and (gbr_msk.Kloning[i+1,j]=1) and (gbr_msk.Kloning[i+1,j+1]=0) and (gbr_msk.Kloning[i+1,j+2]=0) and{/5/}(gbr_msk.Kloning[i+2,j-2]=0) and (gbr_msk.Kloning[i+2,j-1]=1) and (gbr_msk.Kloning[i+2,j]=1) and (gbr_msk.Kloning[i+2,j+1]=0) and (gbr_msk.Kloning[i+2,j+2]=0) then Begin Gbr_Buffer[i,j]:=0;
39
End; {U5}if {/1/} (gbr_msk.Kloning[i-2,j-1]=0) and (gbr_msk.Kloning[i-2,j]=0) and (gbr_msk.Kloning[i-2,j+1]=0) and{/2/}(gbr_msk.Kloning[i-1,j-2]=0) and (gbr_msk.Kloning[i-1,j-1]=0) and (gbr_msk.Kloning[i-1,j]=0) and (gbr_msk.Kloning[i1,j+1]=0) and (gbr_msk.Kloning[i-1,j+2]=0) and{/3/} (gbr_msk.Kloning[i,j-2]=0) and (gbr_msk.Kloning[i,j-1]=0) and (gbr_msk.Kloning[i,j]=0) and (gbr_msk.Kloning[i,j+1]=0) and (gbr_msk.Kloning[i,j+2]=0) and{/4/} (gbr_msk.Kloning[i+1,j-2]=0) and (gbr_msk.Kloning[i+1,j-1]=0) and (gbr_msk.Kloning[i+1,j]=1) and (gbr_msk.Kloning[i+1,j+1]=1) and (gbr_msk.Kloning[i+1,j+2]=0) and{/5/}(gbr_msk.Kloning[i+2,j-2]=0) and (gbr_msk.Kloning[i+2,j-1]=0) and (gbr_msk.Kloning[i+2,j]=1) and (gbr_msk.Kloning[i+2,j+1]=1) and (gbr_msk.Kloning[i+2,j+2]=0) then Begin Gbr_Buffer[i,j]:=0; End; End End; for i:=low(Gbr_Buffer) to High(Gbr_Buffer) do //baris Begin for j:=low(Gbr_Buffer[i]) to High(Gbr_Buffer[i]) do //kolom Begin if Gbr_Buffer[i,j]=2 then Begin //count:=count+1; gbr_msk.Kloning[i,j]:=1; End; if i=low(Gbr_Buffer) Then //ngeset paling tepi Begin gbr_msk.Kloning[i,j]:=1; End; if i=High(Gbr_Buffer) Then //ngeset paling tepi Begin gbr_msk.Kloning[i,j]:=1; End; if j=low(Gbr_Buffer[i]) Then //ngeset paling tepi Begin gbr_msk.Kloning[i,j]:=1; End; if j=High(Gbr_Buffer[i]) Then //ngeset paling tepi Begin gbr_msk.Kloning[i,j]:=1; End; End //akhir dari for2 End;//akhir dari for1 //pasing keluar hasil dari AAE proses acute_angle_emphasis:=gbr_msk; End;
40
Fungsi Acute Angle Emphasis merupakan fungsi kedua sebelum fungsi thinning dijalankan. Fungsi ini berfungsi untuk menangani permasalahan necking yang juga sering muncul dalam thinning. Necking, sesuai dengan yang diuraikan oleh J.R. Parker (1997) adalah titik terbatas pada perpotongan dari dua garis yang direntangkan menjadi sebuah bagian garis yang kecil. Fungsi AAE menggunakan 10 buah template seperti yang telah diilustrasikan pada gambar 2.3. Dalam program implementasi, template AAE diindikasikan dengan nama D1, D2, D3, D4, D5, U1, U2, U3, U4, U5.
4.2.8. Algoritma Fungsi Thinning Stentiford function Thinkan(var Gbr_4Thin:TBinData):TBinData; //inputnya diganti TBinData var //variabel local Gbr_Hsl_Thin,Gbr_Tmp,Gbr_Buffer : Array of array of byte; //Gbr_Buffer :Array of array of Char; i, j,count,endpoint_counter :cardinal; konektivitas,zigmaNK,Nk1,Nk3,Nk5,Nk7: integer; Label Mulai_cocokan;//deklarasi LABEL //mulai function check_thin----> Begin //rumus konektivitas Cn=Zigma(Nk)-(Nk.Nk+1.Nk+2) setLength(Gbr_Hsl_Thin,Gbr_4Thin.Tinggi,Gbr_4Thin.Lebar); setLength(Gbr_Tmp,Gbr_4Thin.Tinggi,Gbr_4Thin.Lebar); setLength(Gbr_Buffer,Gbr_4Thin.Tinggi,Gbr_4Thin.Lebar); //t4 mencatat yang akan disetPutih //Gbr_Tmp:=Gbr_4Thin.Kloning; Mulai_cocokan: //mulai block program count:=0; //===ngeset piksel buffer image kembali ke hitam semua======// for i:=low(Gbr_Buffer)+1 to High(Gbr_Buffer)-1 do //baris Begin for j:=low(Gbr_Buffer[i])+1 to High(Gbr_Buffer[i])-1 do //kolom Begin //count:=count+1; Gbr_buffer[i,j]:=0; End End; //===ngeset piksel buffer image kembali ke hitam semua======//
41
//====================M1_template_matching_============// for i:=low(Gbr_4Thin.Kloning)+1 to High(Gbr_4Thin.Kloning)-1 do //baris Begin for j:=low(Gbr_4Thin.Kloning[i])+1 to High(Gbr_4Thin.Kloning[i])-1 do //kolom Begin if (Gbr_4Thin.Kloning[i,j]=0)And ((Gbr_4Thin.Kloning[i-1,j]=1) And (Gbr_4Thin.Kloning[i+1,j]=0)) Then Begin konektivitas:=0;Nk1:=0;Nk3:=0;Nk5:=0;Nk7:=0; Nk1:=Gbr_4Thin.Kloning[i,j+1]((Gbr_4Thin.Kloning[i,j+1])*(Gbr_4Thin.Kloning[i+1,j+1])*(Gbr_4Thin.Kloning[i+1,j])); Nk3:=Gbr_4Thin.Kloning[i+1,j]((Gbr_4Thin.Kloning[i+1,j])*(Gbr_4Thin.Kloning[i+1,j-1])*(Gbr_4Thin.Kloning[i,j-1])); Nk5:=Gbr_4Thin.Kloning[i,j-1]-((Gbr_4Thin.Kloning[i,j-1])*(Gbr_4Thin.Kloning[i1,j-1])*(Gbr_4Thin.Kloning[i-1,j])); Nk7:=Gbr_4Thin.Kloning[i-1,j]-((Gbr_4Thin.Kloning[i-1,j])*(Gbr_4Thin.Kloning[i1,j+1])*(Gbr_4Thin.Kloning[i,j+1])); //zigmaNK:=Nk1+Nk3+Nk5+Nk7; konektivitas:=(Nk1)+(Nk3)+(Nk5)+(Nk7); //pembuktian EndPoint==============================// endpoint_counter:=0; if Gbr_4Thin.Kloning[i,j+1]=0 then //N1 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j+1]=0 then //N2 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j]=0 then //N3 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j-1]=0 then //N4 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i,j-1]=0 then //N5 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j-1]=0 then //N6 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j]=0 then //N7 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j+1]=0 then //N8 Begin
42
endpoint_counter:=endpoint_counter+1; End; //pembuktian EndPoint==============================// //pencocokan konektivitas=========================// if (konektivitas=1) and (endpoint_counter>1) then Begin Gbr_Buffer[i,j]:=1; //Gbr_Buffer[i-1,j]:=1; Gbr_Buffer[i+1,j]:=0; End;//akhir if2 //pencocokan konektivitas=========================// End//akhir If1 {Else Gbr_Buffer[i,j]:=0;} End//akhir for2 End;//akhir for1 //================M1_template_matching_===================// //=================M2_template_matching_===================// for i:=High(Gbr_4Thin.Kloning)-1 downto low(Gbr_4Thin.Kloning)+1 do //baris Begin for j:=low(Gbr_4Thin.Kloning[i])+1 to High(Gbr_4Thin.Kloning[i])-1 do //kolom Begin if (Gbr_4Thin.Kloning[i,j]=0)and ((Gbr_4Thin.Kloning[i,j-1]=1) And (Gbr_4Thin.Kloning[i,j+1]=0)) Then //templateNya Begin konektivitas:=0;Nk1:=0;Nk3:=0;Nk5:=0;Nk7:=0; Nk1:=Gbr_4Thin.Kloning[i,j+1]((Gbr_4Thin.Kloning[i,j+1])*(Gbr_4Thin.Kloning[i+1,j+1])*(Gbr_4Thin.Kloning[i+1,j])); Nk3:=Gbr_4Thin.Kloning[i+1,j]((Gbr_4Thin.Kloning[i+1,j])*(Gbr_4Thin.Kloning[i+1,j-1])*(Gbr_4Thin.Kloning[i,j-1])); Nk5:=Gbr_4Thin.Kloning[i,j-1]-((Gbr_4Thin.Kloning[i,j-1])*(Gbr_4Thin.Kloning[i1,j-1])*(Gbr_4Thin.Kloning[i-1,j])); Nk7:=Gbr_4Thin.Kloning[i-1,j]-((Gbr_4Thin.Kloning[i-1,j])*(Gbr_4Thin.Kloning[i1,j+1])*(Gbr_4Thin.Kloning[i,j+1])); //zigmaNK:=Nk1+Nk3+Nk5+Nk7; konektivitas:=(Nk1)+(Nk3)+(Nk5)+(Nk7); //pembuktian EndPoint==============================// endpoint_counter:=0; if Gbr_4Thin.Kloning[i,j+1]=0 then //N1 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j+1]=0 then //N2 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j]=0 then //N3 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j-1]=0 then //N4
43
Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i,j-1]=0 then //N5 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j-1]=0 then //N6 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j]=0 then //N7 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j+1]=0 then //N8 Begin endpoint_counter:=endpoint_counter+1; End; //pembuktian EndPoint==============================// //pencocokan konektivitas=========================// if (konektivitas=1) and (endpoint_counter>1) then Begin Gbr_Buffer[i,j]:=1; //Gbr_Buffer[i,j-1]:=1; Gbr_Buffer[i,j+1]:=0; End;//akhir if2 //pencocokan konektivitas=========================// End//akhir If1 {Else Gbr_Buffer[i,j]:=0;} End//akhir for2 End;//akhir for1 //=================M2_template_matching_===================// //================M3_template_matching_===================// for i:=High(Gbr_4Thin.Kloning)-1 downto low(Gbr_4Thin.Kloning)+1 do //baris Begin for j:=High(Gbr_4Thin.Kloning[i])-1 downto low(Gbr_4Thin.Kloning[i])+1 do //kolom Begin if (Gbr_4Thin.Kloning[i,j]=0)and ((Gbr_4Thin.Kloning[i-1,j]=0) And (Gbr_4Thin.Kloning[i+1,j]=1)) Then Begin konektivitas:=0;Nk1:=0;Nk3:=0;Nk5:=0;Nk7:=0; Nk1:=Gbr_4Thin.Kloning[i,j+1]((Gbr_4Thin.Kloning[i,j+1])*(Gbr_4Thin.Kloning[i+1,j+1])*(Gbr_4Thin.Kloning[i+1,j])); Nk3:=Gbr_4Thin.Kloning[i+1,j]((Gbr_4Thin.Kloning[i+1,j])*(Gbr_4Thin.Kloning[i+1,j-1])*(Gbr_4Thin.Kloning[i,j-1])); Nk5:=Gbr_4Thin.Kloning[i,j-1]-((Gbr_4Thin.Kloning[i,j-1])*(Gbr_4Thin.Kloning[i1,j-1])*(Gbr_4Thin.Kloning[i-1,j])); Nk7:=Gbr_4Thin.Kloning[i-1,j]-((Gbr_4Thin.Kloning[i-1,j])*(Gbr_4Thin.Kloning[i1,j+1])*(Gbr_4Thin.Kloning[i,j+1]));
44
//zigmaNK:=Nk1+Nk3+Nk5+Nk7; konektivitas:=(Nk1)+(Nk3)+(Nk5)+(Nk7); //pembuktian EndPoint==============================// endpoint_counter:=0; if Gbr_4Thin.Kloning[i,j+1]=0 then //N1 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j+1]=0 then //N2 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j]=0 then //N3 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j-1]=0 then //N4 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i,j-1]=0 then //N5 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j-1]=0 then //N6 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j]=0 then //N7 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j+1]=0 then //N8 Begin endpoint_counter:=endpoint_counter+1; End; //pembuktian EndPoint==============================// //pencocokan konektivitas=========================// if (konektivitas=1) and (endpoint_counter>1)then Begin Gbr_Buffer[i,j]:=1; Gbr_Buffer[i-1,j]:=0; //Gbr_Buffer[i+1,j]:=1; End;//akhir if2 //pencocokan konektivitas=========================// End//akhir If1 {Else Gbr_Buffer[i,j]:=0;} End//akhir for2 End;//akhir for1 //===================M3_template_matching_===================//
45
//====================M4_template_matching_===================/ for i:=low(Gbr_4Thin.Kloning)+1 to High(Gbr_4Thin.Kloning)-1 do //baris Begin for j:=High(Gbr_4Thin.Kloning[i])-1 downto low(Gbr_4Thin.Kloning[i])+1 do //kolom Begin if (Gbr_4Thin.Kloning[i,j]=0)and ((Gbr_4Thin.Kloning[i,j-1]=0) And (Gbr_4Thin.Kloning[i,j+1]=1)) Then Begin konektivitas:=0;Nk1:=0;Nk3:=0;Nk5:=0;Nk7:=0; Nk1:=Gbr_4Thin.Kloning[i,j+1]((Gbr_4Thin.Kloning[i,j+1])*(Gbr_4Thin.Kloning[i+1,j+1])*(Gbr_4Thin.Kloning[i+1,j])); Nk3:=Gbr_4Thin.Kloning[i+1,j]((Gbr_4Thin.Kloning[i+1,j])*(Gbr_4Thin.Kloning[i+1,j-1])*(Gbr_4Thin.Kloning[i,j-1])); Nk5:=Gbr_4Thin.Kloning[i,j-1]-((Gbr_4Thin.Kloning[i,j-1])*(Gbr_4Thin.Kloning[i1,j-1])*(Gbr_4Thin.Kloning[i-1,j])); Nk7:=Gbr_4Thin.Kloning[i-1,j]-((Gbr_4Thin.Kloning[i-1,j])*(Gbr_4Thin.Kloning[i1,j+1])*(Gbr_4Thin.Kloning[i,j+1])); //zigmaNK:=Nk1+Nk3+Nk5+Nk7; konektivitas:=(Nk1)+(Nk3)+(Nk5)+(Nk7); //pembuktian EndPoint==============================// endpoint_counter:=0; if Gbr_4Thin.Kloning[i,j+1]=0 then //N1 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j+1]=0 then //N2 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j]=0 then //N3 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j-1]=0 then //N4 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i,j-1]=0 then //N5 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j-1]=0 then //N6 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j]=0 then //N7 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j+1]=0 then //N8 Begin
46
endpoint_counter:=endpoint_counter+1 End; //pembuktian EndPoint==============================// //pencocokan konektivitas=========================// if (konektivitas=1) and (endpoint_counter>1)then Begin Gbr_Buffer[i,j]:=1; Gbr_Buffer[i,j-1]:=0; //Gbr_Buffer[i,j+1]:=1; End;//akhir if2 //pencocokan konektivitas=========================// End//akhir If1 {Else Gbr_Buffer[i,j]:=0;} End//akhir for2 End;//akhir for1 //==================M4_template_matching_===================// //====operasi penghapusan piksel (mulai thinning) = set to white ==========// for i:=low(Gbr_Buffer) to High(Gbr_Buffer) do //baris Begin for j:=low(Gbr_Buffer[i]) to High(Gbr_Buffer[i]) do //kolom Begin if Gbr_Buffer[i,j]=1 then Begin count:=count+1; Gbr_4Thin.Kloning[i,j]:=1; End; if i=low(Gbr_Buffer) Then //ngeset paling tepi Begin Gbr_4Thin.Kloning[i,j]:=1; End; if i=High(Gbr_Buffer) Then //ngeset paling tepi Begin Gbr_4Thin.Kloning[i,j]:=1; End; if j=low(Gbr_Buffer[i]) Then //ngeset paling tepi Begin Gbr_4Thin.Kloning[i,j]:=1; End; if j=High(Gbr_Buffer[i]) Then //ngeset paling tepi Begin Gbr_4Thin.Kloning[i,j]:=1; End; End End; //=========operasi penghapusan piksel (mulai thinning) ===========// if count>0 then Begin goto mulai_cocokan; End; Application.CreateForm(TView_Thin, View_Thin);
47
View_Thin.Caption:='rekonstruksi Bitmap dari Array'; View_Thin.GBR.Picture.Bitmap:=Rekonstruksi(Gbr_4Thin); End; //akhir function check_thin
Fungsi Thinning ini merupakan Fungsi yang menjadi pokok bahasan, karena dalam fungsi ini memuat implementasi dari algoritma thinning Stentiford. Algoritma Stentiford menggunakan 4 buah template, seperti yang sudah diilustrasikan pada gambar 2.1. Selain penggunaan template tersebut Stentiford juga melakukan penghitungan nilai konektivitas dari setiap pixel.
4.2.9. Algoritma Fungsi Rekonstruksi Citra function Rekonstruksi(var test_data:TBinData):TBitmap; var Bmp_prev:TBitmap; x,y:cardinal; //data_in:TBinData; begin Bmp_prev:=TBitmap.Create; Try //seperti cara merekonstruksi bitmap dari array with Bmp_prev do Begin PikselFormat:=pf1bit; Height:=test_data.Tinggi; Width:=test_data.Lebar; End;//akhir with for x:=0 to test_data.Tinggi-1 do Begin for y:=0 to test_data.Lebar-1 do Begin if test_data.Kloning[x,y] = 1 then Begin Bmp_prev.Canvas.Piksels[x,y]:= clWhite; End//akhir if Else if test_data.Kloning[x,y] = 0 then Begin Bmp_prev.Canvas.Piksels[x,y]:= clBlack; End //buat ngetes array {else Bmp_prev.Canvas.Piksels[x,y]:= clRed;} End;
48
End;//akhir for1 Finally Rekonstruksi:=Bmp_prev; End;//akhir try {menggenerate Form baru dalam runtime program dan meng-assignkan nama baru kepreviewImagenya; } end;
Proses rekonstruksi citra dari array merupakan proses yang penting karena citra array yang ada dan yang telah diproses membutuhkan suatu proses agar dapat ditampilkan menjadi sebuah citra mandiri dan dapat disimpan oleh user. Proses rekonstruksi berjalan dengan melakukan scanning dalam array yang telah dikenai proses thinning. Dalam scanning tersebut, program mengklasifikasikan nilai 0 dan 1 ke nilai warna clBlack dan clWhite pada komponen image pada program. Citra mandiri yang disimpan oleh user secara standar akan disimpan dengan tipe *.BMP.
4.2.10. Algoritma Utama if FileExists(Utama.Buka_Gambar_Dialog.FileName)Then Begin if (check_prepro.Checked=True) Then Begin View.GBR.Picture.Bitmap.LoadFromFile(Utama.Buka_Gambar_Dialog.FileName); View.Name:='RGB_Pic'; cobaBit1:=View.GBR.Picture.Bitmap; View.Caption:='Format Gambar:Biner'; cobaBit2:=grayscaling(cobaBit1); cobaBit3:=binerisasi(cobaBit2); hasil:=Duplikasi(cobaBit3);//mengkloning nilai image ke array hasil_biner_smooth:=smoothing(hasil); hasil_after_aae:=acute_angle_emphasis(hasil_biner_smooth); View.GBR.Picture.Bitmap:=Rekonstruksi(hasil); View.Caption:='Format Gambar:Biner'; Thinkan(hasil_after_aae); Propertis.Simpan_Tombol.Enabled:=True; Propertis.Proses_tombol.Enabled:=False; Utama.Jalankan_proses.Enabled:=False; End Else
49
View.GBR.Picture.Bitmap.LoadFromFile(Utama.Buka_Gambar_Dialog.FileName); View.Name:='RGB_Pic'; cobaBit1:=View.GBR.Picture.Bitmap; View.Caption:='Format Gambar:Biner'; cobaBit2:=grayscaling(cobaBit1); cobaBit3:=binerisasi(cobaBit2); hasil:=Duplikasi(cobaBit3);//mengkloning nilai image ke array View.GBR.Picture.Bitmap:=Rekonstruksi(hasil); View.Caption:='Format Gambar:Biner'; Thinkan(hasil); Propertis.Simpan_Tombol.Enabled:=True; Propertis.Proses_tombol.Enabled:=False; Utama.Jalankan_proses.Enabled:=False; end else MessageDlg('File Belum DiBuka',mtInformation,[mbOK],1);
Algoritma utama ini merupakan proses yang menentukan urutan pemanggilan fungsi agar proses dapat berjalan dengan baik. Karena, dapat dilihat pada cuplikan kode program di atas bagaimana fungsi–fungsi pada program secara berurutan dipanggil dan dijalankan. Program mempunyai dua alternatif pemanggilan fungsi, karena pada program tersedia fasilitas dimana user dapat memilih akan menyertakan proses smoothing dan AAE sebelum dilakukan operasi thinning.
4.3. IMPLEMENTASI ANTARMUKA TAMPILAN Dalam implementasinya, program Algoritma Thinning mempunyai 5 tombol utama yang mewakili dari 5 operasi yang difasilitasi oleh program. Antara lain ambil gambar, proses thinning, simpan hasil operasi thinning, dan operasi dasar untuk keluar program dan bantuan. Ketika program dijalankan, halaman awal yang akan muncul adalah Form Halaman Utama, seperti yang tampak pada Gambar 4.2 berikut ini:
50
Gambar 4.2 Tampilan utama dari program
Halaman Utama merupakan sebuah aplikasi utama yang dibuat dengan tipe MDI application. MDI application merupakan tipe yang memungkinkan beberapa Form dapat ditampilkan secara bersamaan dalam sebuah aplikasi. Dari gambar diatas dapat dilihat bahwa terdapat 5 menu utama yang dapat dijalankan oleh user yaitu: 1. Ambil gambar 2. Proses 3. Simpan Hasil 4. Keluar 5. Tentang Program Dari 5 tombol yang ada, masing tombol mempunyai fungsi:
51
1. Tombol Ambil Gambar tombol “Ambil Gambar” memicu elemen Open Picture Dialog untuk berjalan. Ketika Open Picture Dialog Terpicu, Open Picture Dialog Akan menampilkan sebuah form dialog yang akan membantu user memilih citra yang akan digunakan dalam program. Form dialog tersebut terwakili seperti pada Gambar 4.3 berikut:
Gambar 4.3 Tamilan form dialog buka citra
Dalam dialog tersebut, user diberi pilihan untuk mengambil gambar dengan syarat tipe file harus BMP, dan mempunyai dimensi lebar dan tinggi yang sama. Program ini mensyaratkan tinggi dan lebar citra harus sama, mengapa?, hal ini dikarenakan ketika proses pengesetan (setLength) lebar array ketika prosedur duplikasi citra nilai dimensi lebar dan tinggi array akan berubah - ubah. Ketika user sudah memilih dan mengakses citra yang diinginkan, citra akan ditampilkan dengan sebuah form penampil gambar. Form Penampil Citra merupakan sebuah form tersendiri yang dibuat khusus sebagai penampil citra RGB. Form tersebut diwakili dengan tampilan seperti pada Gambar 4.4 sebagai berikut:
52
Gambar 4.4 Tampilan form citra RGB
Tetapi, apabila citra yang telah dipilih user mempunyai ketidaksamaan dimensi panjang dan lebar maka program akan memberikan peringatan dan tidak akan mengakses citra tersebut. Form peringatan yang akan diberikan program diwakili dengan tampilan seperti pada Gambar 4.5 sebagai berikut:
Gambar 4.5 Tampilan form peringatan ketika ukuran lebar dan tinggi citra tidak sama
2. Tombol Proses Tombol Proses pada posisi standar akan ter-setting tidak aktif. Tombol proses akan menjadi aktif dan dapat dijalankan apabila sebuah citra telah diambil dan ditampilkan. Tombol proses tersebut merupakan tombol yang memicu jalannya
53
proses dan pemanggilan fungsi. Fungsi – Fungsi program yang menjadi bagian dari implementasi algoritma thinning antara lain grayscale, binerisasi, duplikasi, smoothing, acute angle emphasis, thinning. Proses yang telah berjalan akan menghasilkan sebuah citra dalam format 1 bit (monokrom). Citra dari hasil operasi thinning tersebut akan ditampilkan sebuah form tersendiri. Form tersebut dapat terwakili seperti pada Gambar 4.6 sebagai berikut:
Gambar 4.6 Tampilan form citra yang telah direkonstruksi dari array dan telah melalui proses thinning Stentiford
3. Tombol Simpan Hasil Tombol simpan secara standar akan ter-setting tidak aktif. Tombol tersebut hanya akan aktif apabila citra hasil operasi telah muncul atau tombol proses telah tertekan. Tombol simpan menjadi pemicu dari sebuah elemen dalam program yang disebut. Save Picture Dialog. Save Picture Dialog membantu user agar lebih mudah ketika user ingin menyimpan hasil operasi thinning menjadi sebuah file citra secara
54
terpisah. Ketika tombol simpan hasil ditekan, maka elemen Save Picture Dialog akan terpicu dan memberikan sebuah form dialog dimana user dapat memilih direktori dan nama file untuk citra hasil operasi thinning, form dialog tersebut diwakili dengan tampilan seperti pada Gambar 4.7 sebagai berikut:
Gambar 4.7 Tampilan form dialog ketika user ingin menyimpan citra hasil operasi thinning
4. Tombol Keluar Tombol keluar berfungsi untuk menutup aplikasi. Ketika tombol keluar ditekan, akan memberikan sebuah form konfirmasi kepada user. Form konfirmasi berfungsi untuk mencari kepastian apakah user secara sengaja menekan tombol keluar dan ingin keluar atau user secara tidak sengaja menekan tombol keluar. Form konfirmasi keluar diwakili seperti pada Gambar 4.7 sebagai berikut:
Gambar 4.8 Tampilan form konfirmasi bagi user
55
5. Tombol Tentang Program Tombol tentang program merupakan yang berfungsi menyajikan informasi program yang meliputi data pembuat, data pembimbing, judul program, universitas, lokasi universitas. Form Tentang Program diwakili dengan tampilan seperti pada Gambar 4.9 sebagai berikut:
Gambar 4.9 Tampilan form tentang program yang menyajikan informasi program
Selain 5 menu utama yang telah disebutkan tadi, Ada 1 buah Menu yang ditambahkan yaitu menu Bantuan. Menu Bantuan dibuat dan diletakan pada Menu bar bagian atas. Menu Bantuan berfungsi untuk memberikan sedikit penjelasan kepada user tentang informasi syarat–syarat agar dapat menjalankan program secara lancar. Selain itu Menu Bantuan juga berisi tentang sedikit penjelasan tentang topik yang digunakan sebagai inti bahasan dari Thinning atau Skeletonization.
56
Ketika menu bantuan ditekan, menu tersebut akan memicu pemanggilan sebuah form yang penampilannya dapat dilihat pada gambar 4.10:
Gambar 4.10 Tampilan form bantuan. Form ini menyajikan hal-hal yang perlu diperhatikan sebelum menjalankan program
4.4. PENGUJIAN PROGRAM Pengujian dari program merupakan faktor penting yang menentukan apakah penerapan dari algoritma telah berjalan sesuai dengan ketentuan yang ada. Objek yang digunakan untuk melakukan pengujian merupakan objek huruf tulis. O. Di dalam tabel 4.1, terdapat 4 kolom yang terdiri atas Citra Asli, Citra Biner, Hasil Pengolahan dengan Preprocessing, Hasil Pengolahan Tanpa Preprocessing. Preprocessing merupakan tahap dimana citra dikenai operasi Smoothing dan Acute Angle Emphasis sebelum dikenai operasi thinning. Tabel 4.1 merupakan tabel yang berisi gambar dari huruf–huruf, objek dan hasil dari thinning yang telah dilakukan.
57
Dari pengamatan visual yang dilakukan terhadap hasil operasi yang dilakukan, dapat disimpulkan bahwa sebuah operasi thinning memerlukan proses – proses tambahan agar hasil yang diperoleh menjadi lebih baik. Pada tabel 4.1, hasil operasi menunjukkan bahwa masalah yang selalu timbul pada Algoritma Stentiford adalah masalah tentang line fuzz. Hal ini timbul karena adanya ke-tidaksempurna-an bentuk dari garis terluar objek. hasil
pengujian
terhadap
12
macam
bentuk
yang
mempunyai
ketidaksempurnaan bentuk garis luar hal ini dari table 4.1. Dari tabel pengujian tersebut, dapat diamati secara visual bahwa pada gambar 1, 2, 3, 4, 5, 7, 8, 9, 11, 12 pada tabel 4.1 mempunyai kesamaan bentuk dari hasil operasi thinning. Tetapi pada gambar 6 dan 10 dapat dilihat masalah yang muncul dari algoritma Stentiford. Pada gambar nomor 6, operasi thinning yang dikenakan pada sebuah huruf A justru menghilangkan informasi penting yang ada, karena hasil operasi thinning yang ada justru tidak mewakili bentuk objek yang ada. Hal ini timbul karena adanya lobang – lobang pada citra setelah dalam bentuk citra biner. Oleh karena itu, sebuah operasi closing diperlukan untuk mengatasi lobang-lobang kecil tersebut. Closing merupakan operasi morfologi pada citra dimana closing berfungsi untuk menghilangkan lubang kecil yang tak berguna pada citra. Pada gambar nomor 10 pada tabel 4.1, sebuah bulatan utuh dikenai operasi thinning, tetapi hal ini telah disinggung oleh J.R. Parker bahwa sebuah lingkaran cakram (Disk) atau lingkaran utuh tidak dapat dikenai operasi thinning.
58
Tabel 4.1 Daftar Hasil Pengujian
No. 1
2
3
4
Citra Asli
Citra Biner
Dengan Preprocessing
Tanpa Preprocessing
59
5
6
7
8
60
9
10
11
12
BAB V PENUTUP
5.1 Kesimpulan Dari penjelasan, penguraian dan pembuktian dari bab satu hingga akhir pengembangan perangkat lunak ini, dapat disimpulkan sebagai berikut : 1. Dari hasil operasi thinning dengan menggunakan Algoritma Stentiford, hasil kerangka yang didapatkan pada dasarnya sudah memenuhi asumsi dan definisi dari skeleton yang diungkapkan oleh J.R. Parker (1997) tetapi ada beberapa hal yang menjadi kekurangan yaitu adanya line fuzz yang belum teratasi secara baik. Hal ini di dapatkan dari hasil pengamatan visual yang dilakukan pada citra pengujian seperti yang tercantum pada Tabel 4.1. 2. Proses Smoothing dan Acute Angle Emphasis mempunyai pengaruh pada hasil operasi thinning tetapi berperan kecil terhadap kerangka yang dihasilkan. Hal ini dapat dilihat dari gambar nomor 6 pada tabel 4.1, yang menunjukkan bahwa operasi yang ada belum dapat menyederhanakan informasi penting yang ada. 5.2 Saran Beberapa saran yang dapat digunakan untuk menyempurnakan program adalah:
62
1. Dalam pengembangan selanjutnya, penggunaan tipe atau ekstensi yang beragam selain ekstensi *.BMP atau windows bitmap dapat menjadi pertimbangan untuk menjaga fleksibilitas program. 2. Program dapat ditambah operasi untuk meningkatkan kualitas citra sebelum dilakukan operasi thinning, antara lain ekualisasi histogram, closing. 3. Perlu dilakukan studi lebih lanjut tentang operasi lain yang dapat dilakukan setelah atau sebelum operasi thinning untuk menyempurnakan hasil dari skeletonization, antara lain operasi yang dapat mengurangi tailing maupun line fuzz pada kerangka objek. 4. Operasi Thinning agar bisa digunakan pada citra dengan ukuran dimensi panjang dan lebar yang berbeda.
DAFTAR PUSTAKA
Ekanita M.S.,Dewi .(2004).Operasi Morfologi Pada Suatu Berkas Citra Monokrom *.BMP Menggunakan Perangkat Lunak Matlab Versi 6.5 : Skripsi. Yogyakarta : Universitas Sanata Dharma.
Jain, Anil. K. (1989). Fundamentals of Digital Image Processing. Prentice-Hall, Inc. Englewood Cliffs, NJ.
MADCOMS.(2003). Pemrograman Borland Delphi 7. C.V Andi. Yogyakarta
Martin, Alberto & Tosunoglu, Sabri. Image Processing Technique for Machine Vision. Florida International University Department of Mechanical Engineering. http://www.eng.fiu.edu/me/robotics/elib/am_st_fiu_ppr_2000.pdf Diakses pada tanggal 21 juli 2007
O’Gorman, L & Kasturi, R. (1997). Document Image Analysis. IEEE Computer Society Press Executive Briefing Series, Los Alamitos, CA.
Parker, J.R. (1997). Algorithm For Image Processing and Computer Vision. Wiley Computer Publishing, Inc. New York.
64
Sonka, M., Hlavac, V. & Boyle, R. (1998). Image Processing, Analysis, and Machine Vision, 2nd Edition, Pws. Pub. Co.,.
Wikipedia.org/wiki/~Grayscale
LAMPIRAN
LAMPIRAN PROGRAM 1. Thinning.dpr program Thinning; uses Forms, Main in 'Main.pas' {Utama}, AboutBox in 'AboutBox.pas' {About}, Prop in 'Prop.pas' {Propertis}, Prev in 'Prev.pas' {View}, fungsi3 in 'fungsi3.pas', Prev_Thin in 'Prev_Thin.pas' {View_Thin}, bantuan in 'bantuan.pas' {help_frm}; {$R *.res} begin Application.Initialize; Application.Title := 'Algoritma_Thinning_Stentiford'; Application.CreateForm(TUtama, Utama); //Application.CreateForm(Thelp_frm, help_frm); //Application.CreateForm(TView_Thin, View_Thin); //Application.CreateForm(TAbout, About); Application.CreateForm(TPropertis, Propertis); //Application.CreateForm(TView, View); Application.Run; end.
2. Prev_Thin.pas unit Prev_Thin; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls; type TView_Thin = class(TForm) GBR: TImage; procedure FormShow(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } public { Public declarations } end; var
66
View_Thin: TView_Thin; implementation uses Main, Prop, Prev, fungsi3; {$R *.dfm} procedure TView_Thin.FormShow(Sender: TObject); var Nw,Nh :integer; FileHeader: TBitmapfileheader;// InfoHeader: TBitmapinfoheader;// FileBitmap: TFilestream;// //tmp_BMP:TBitmap; begin FileBitmap := TFilestream.Create(Utama.Buka_Gambar_Dialog.FileName, fmOpenRead); FileBitmap.Read(FileHeader, SizeOf(FileHeader)); // membaca FileHeader dr Bitmap FileBitmap.Read(InfoHeader, SizeOf(InfoHeader)); // membaca InfoHeader dr Bitmap FileBitmap.Free; Nw:=InfoHeader.biWidth; Nh:=InfoHeader.biHeight; //ShowMessage(IntToStr(Nw)+' '+IntToStr(Nh)); GBR.width:=Nw; GBR.height:=Nh; View_Thin.width:=Nw+8; View_Thin.height:=Nh+27;//{panjang BiDi Icon = 20pixel} View_Thin.Top:=round(Utama.Height div 15)+20; View_Thin.Left:=Screen.Width ((View_Thin.width)+round(Screen.Width Div 51)); end; procedure TView_Thin.FormClose(Sender: TObject; var Action: TCloseAction); begin Action:=caFree; Utama.Jalankan_proses.Enabled:=True; Propertis.Simpan_Tombol.Enabled:=False; if FileExists(Utama.Buka_Gambar_Dialog.FileName) Then Begin Propertis.Proses_tombol.Enabled:=True; End Else Propertis.Proses_tombol.Enabled:=False; end; end.
3. Prev.pas unit Prev;
67
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls; type TView = class(TForm) GBR: TImage; procedure FormShow(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } public { Public declarations } end; var View: TView; implementation uses Main, Prop; {$R *.dfm} procedure TView.FormShow(Sender: TObject); var Nw,Nh :integer; FileHeader: TBitmapfileheader;// InfoHeader: TBitmapinfoheader;// FileBitmap: TFilestream;// begin FileBitmap := TFilestream.Create(Utama.Buka_Gambar_Dialog.FileName, fmOpenRead); FileBitmap.Read(FileHeader, SizeOf(FileHeader)); // membaca FileHeader dr Bitmap FileBitmap.Read(InfoHeader, SizeOf(InfoHeader)); // membaca InfoHeader dr Bitmap FileBitmap.Free; Nw:=InfoHeader.biWidth; Nh:=InfoHeader.biHeight; GBR.width:=Nw; GBR.height:=Nh; View.Caption:='Mode Gambar : RGB'; View.width:=Nw+8; View.height:=Nh+27;//{panjang BiDi Icon = 20pixel} View.Top:=round(Utama.Height div 15)+20; View.Left:=round(Screen.Width Div 52); end;
68
procedure TView.FormClose(Sender: TObject; var Action: TCloseAction); begin Action:=caFree; Utama.Buka_Gambar_Dialog.FileName:=''; Utama.Jalankan_proses.Enabled:=False; Utama.Ambil_Gambar.Enabled:=True;//tab Menu untuk ngambil gambar Propertis.Buka_Tombol.Enabled:=True; Propertis.Proses_tombol.Enabled:=False; //Propertis.Simpan_Tombol.Enabled:=False; Propertis.NmFL.Caption:='Nama File Yang Digunakan :'; Propertis.SzFL.Caption:= 'Dimensi File : '; end; end.
4.
Main.pas
unit Main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Menus, StdCtrls, ExtDlgs; type TUtama = class(TForm) Label_Judul: TLabel; Buka_Gambar_Dialog: TOpenPictureDialog; MenuUtama: TMainMenu; Ops_dasar: TMenuItem; Ambil_Gambar: TMenuItem; Jalankan_proses: TMenuItem; Keluar: TMenuItem; AboutMenu: TMenuItem; bantuan: TMenuItem; Simpan_Gambar_Dialog: TSavePictureDialog; procedure FormCreate(Sender: TObject); procedure FormShow(Sender: TObject); procedure Ops_dasarClick(Sender: TObject); procedure AboutMenuClick(Sender: TObject); procedure KeluarClick(Sender: TObject); procedure Ambil_GambarClick(Sender: TObject); procedure bantuanClick(Sender: TObject); procedure Jalankan_prosesClick(Sender: TObject); private { Private declarations } public { Public declarations } end;
69
var Utama: TUtama; implementation uses Prop,Prev,Prev_Thin,AboutBox,fungsi3,bantuan; {$R *.dfm} procedure TUtama.FormCreate(Sender: TObject); begin With Utama do Begin Height:=Screen.Height; Width:=Screen.Width; WindowState:=WsMaximized; Label_Judul.Caption:='Algoritma Thinning Stentiford'; Label_Judul.Font.Size:=36; Label_Judul.Left:= (Utama.Width div 2) - (Label_Judul.Width div 2); Label_judul.Top:= round(Utama.Height div 50); //Label_Judul.Font.Style:=fsBold; End; end; procedure TUtama.FormShow(Sender: TObject); begin if Utama.Buka_Gambar_Dialog.FileName='' Then Begin Propertis.Proses_tombol.Enabled:=False; Propertis.Simpan_Tombol.Enabled:=False; End; Propertis.Show; end; procedure TUtama.Ops_dasarClick(Sender: TObject); begin if Utama.Buka_Gambar_Dialog.FileName=''Then Begin Jalankan_proses.Enabled:=False; End end; procedure TUtama.AboutMenuClick(Sender: TObject); begin Application.CreateForm(TAbout,About); end; procedure TUtama.KeluarClick(Sender: TObject); begin if MessageDlg('Apakah Anda yakin ingin Keluar?',mtConfirmation,[mbYes,mbNo],0) = mrYes Then
70
Begin Application.Terminate; End; end; procedure TUtama.Ambil_GambarClick(Sender: TObject); var Nw,Nh :integer; FileHeader: TBitmapfileheader;// InfoHeader: TBitmapinfoheader;// FileBitmap: TFilestream;// begin if Utama.Buka_Gambar_Dialog.Execute Then Begin FileBitmap := TFilestream.Create(Utama.Buka_Gambar_Dialog.FileName, fmOpenRead); FileBitmap.Read(FileHeader, SizeOf(FileHeader)); // membaca FileHeader dr Bitmap FileBitmap.Read(InfoHeader, SizeOf(InfoHeader)); // membaca InfoHeader dr Bitmap FileBitmap.Free; Nw:=InfoHeader.biWidth; Nh:=InfoHeader.biHeight; if Nw <> Nh Then Begin MessageDlg('Ukuran Panjang Dan Lebar File Tidak Sama!, Yang Anda Pilih : '+IntToStr(Nw)+' X '+IntToStr(Nh),mtWarning,[mbOK],0); End Else if Nw = Nh Then Begin {belum ada statement untuk membantu} Application.CreateForm(TView,View); //Form HArus Diberi nama Saat Run-Time View.GBR.Picture.LoadFromFile(Utama.Buka_Gambar_Dialog.FileName); View.Show; Utama.Jalankan_proses.Enabled:=True; Ambil_Gambar.Enabled:=False;//tab Menu untuk ngambil gambar Propertis.Proses_tombol.Enabled:=True; Propertis.Buka_Tombol.Enabled:=False; Propertis.NmFL.Caption:='Nama File Yang Digunakan : '+ExtractFileName(Utama.Buka_Gambar_Dialog.FileName); Propertis.SzFL.Caption:= 'Dimensi File : '+IntToStr(Nw)+' Pixel'+' X ' + IntToStr(Nh)+' Pixel'; End; End end; procedure TUtama.bantuanClick(Sender: TObject); begin //MessageDlg('Maaf Menu Ini Belum Difungsikan!',mtInformation,[mbOK],0); Application.CreateForm(Thelp_frm, help_frm);
71
help_frm.Show; end; procedure TUtama.Jalankan_prosesClick(Sender: TObject); var cobaBit1,cobaBit2,cobaBit3:TBitmap; hasil,hasil_biner_smooth,hasil_after_aae:Fungsi3.TBinData; begin if FileExists(Utama.Buka_Gambar_Dialog.FileName)Then Begin if (propertis.check_prepro.Checked=True) Then Begin View.GBR.Picture.Bitmap.LoadFromFile(Utama.Buka_Gambar_Dialog.FileNa me); View.Name:='RGB_Pic'; cobaBit1:=View.GBR.Picture.Bitmap; View.Caption:='Format Gambar:Biner'; cobaBit2:=grayscaling(cobaBit1); //GbrTmp di fungsi grayscaling jangan di Free karena merupakan input untuk fungsi binerisasi cobaBit3:=binerisasi(cobaBit2); hasil:=Duplikasi(cobaBit3);//mengkloning nilai image ke array hasil_biner_smooth:=smoothing(hasil); hasil_after_aae:=acute_angle_emphasis(hasil_biner_smooth); View.GBR.Picture.Bitmap:=Rekonstruksi(hasil); View.Caption:='Format Gambar:Biner'; Thinkan(hasil_after_aae); Propertis.Simpan_Tombol.Enabled:=True; Propertis.Proses_tombol.Enabled:=False; Utama.Jalankan_proses.Enabled:=False; End Else if (propertis.check_prepro.Checked=False) Then Begin View.GBR.Picture.Bitmap.LoadFromFile(Utama.Buka_Gambar_Dialog.FileNa me); View.Name:='RGB_Pic'; cobaBit1:=View.GBR.Picture.Bitmap; View.Caption:='Format Gambar:Biner'; cobaBit2:=grayscaling(cobaBit1); //GbrTmp di fungsi grayscaling jangan di Free karena merupakan input untuk fungsi binerisasi cobaBit3:=binerisasi(cobaBit2); hasil:=Duplikasi(cobaBit3);//mengkloning nilai image ke array View.GBR.Picture.Bitmap:=Rekonstruksi(hasil); View.Caption:='Format Gambar:Biner'; Thinkan(hasil); Propertis.Simpan_Tombol.Enabled:=True; Propertis.Proses_tombol.Enabled:=False; Utama.Jalankan_proses.Enabled:=False; end end
72
else MessageDlg('File Belum DiBuka',mtInformation,[mbOK],1); end; end.
5.
Fungsi3.pas
unit fungsi3; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ToolWin, ActnMan, ActnCtrls, ActnMenus, Menus, ExtDlgs, ExtCtrls; type TBinData = Record Kloning :Array of Array of byte; //alokasi maksimum 4000X4000byte Tinggi :integer; Lebar :integer; End; function Rekonstruksi(var test_data:TBinData):TBitmap; function grayscaling(var gbrIn:TBitmap):TBitmap; function binerisasi(var gbrIn:TBitmap):TBitmap; function Duplikasi(var Gbr_2Klon:TBitmap):TBinData; function Thinkan(var Gbr_4Thin:TBinData):TBinData; //inputnya diganti TBinData function acute_angle_emphasis(var gbr_msk:TBinData):TBinData; function smoothing(var Gbr_4Thin:TBinData):TBinData; //Function Histogram():Cardinal; implementation uses prev,Prev_Thin,Main; function grayscaling(var gbrIn:TBitmap):TBitmap; Var GbrTmp:TBitmap; i,j,GrayVal :Cardinal; pixArrRGB,pixArrGrey:Pbytearray; Begin GbrTmp:=TBitmap.Create; GbrIn.PixelFormat:=pf24bit; Try With GbrTmp Do Begin PixelFormat:=pf8bit;
73
Height:=gbrIn.Height; Width:=gbrIn.Width; End; for i:=0 to gbrIn.height-1 do begin pixArrRGB:=gbrIn.ScanLine[i]; pixArrGrey:=GbrTmp.ScanLine[i]; for j:=0 to gbrIn.width-1 do begin GrayVal:=round((pixArrRGB[j*3]) * 0.11)+round((pixArrRGB[j*3+1]) * 0.59)+round((pixArrRGB[j*3+2]) * 0.3); pixArrGrey[j]:= GrayVal; end end; GbrTmp.PixelFormat:=pf8bit; //digunakan seandainya GbrTmp.PixelFormat masih pf24bit grayscaling:=GbrTmp Finally End; End; {akhir dari fungsi grayscale} function binerisasi(var gbrIn:TBitmap):TBitmap; Var GbrTmp:TBitmap; i,j:Cardinal; pixArrBin,pixArrGrey:Pbytearray; Begin GbrTmp:=Tbitmap.create; GbrIn.PixelFormat:=pf8bit; Try With GbrTmp Do Begin PixelFormat:=pf8bit; Height:=gbrIn.Height; Width:=gbrIn.Width; End; for i:=0 to gbrIn.height-1 do begin pixArrGrey:=gbrIn.ScanLine[i]; for j:=0 to gbrIn.width-1 do begin if pixArrGrey[j]>=128then begin //pixArrBin[j]:=255; // agar ukuran lebar pixel antara pf8bit dan pf1bit tepat, maka perlu di buat scanline[index div 8] GbrTmp.Canvas.Pixels[j,i]:=255; //sama aja dengan yang diatas end else if pixArrGrey[j]<128then //pixArrBin[j]:=0;//ColorToRGB(clBlack);
74
GbrTmp.Canvas.Pixels[j,i]:=0; //sama aja dengan yang diatas end; end; //GbrTmp.palette:=GetTwoColorPalette; GbrTmp.PixelFormat:=pf1bit; binerisasi:=GbrTmp; Finally //MessageDlg(IntToStr(c),mtInformation,[mbOK],1); //GbrTmp.Free; GbrIn.Free; End End; {akhir dari fungsi binerisasi} Function Duplikasi(var Gbr_2Klon:TBitmap):TBinData; var x,y,H,W:cardinal; klon_out:TBinData; Begin Try H:=Gbr_2Klon.Height; W:=Gbr_2Klon.Width; klon_out.Tinggi:=H; klon_out.Lebar:=W; SetLength(klon_out.Kloning,H,W);//ngeset variabel dinamis array [baris] For x:=Low(klon_out.Kloning) to High(klon_out.Kloning) do//mengakses index X dari yang terendah ke yg tertinggi Begin //SetLength(klon_out.Kloning[x],W);//ngeset Besar array[baris][Kolom] For y:=Low(klon_out.Kloning[x]) to High(klon_out.Kloning[x]) do ////mengakses kolom X dgn index Y dari yang terendah ke yg tertinggi Begin if Gbr_2Klon.Canvas.Pixels[x,y]=clBlack then Begin klon_out.Kloning[x,y]:=0; End Else klon_out.Kloning[x,y]:=1; //akhir else if End;//akhir For2 End;//akhir For1 Finally Duplikasi:=klon_out; //parse kluar hasil kloning, yang nantinya akan dicek_THin End; End;//akhir function Duplikasi function Rekonstruksi(var test_data:TBinData):TBitmap; var Bmp_prev:TBitmap;
75
x,y:cardinal; //data_in:TBinData; begin Bmp_prev:=TBitmap.Create; Try //seperti cara merekonstruksi bitmap dari array with Bmp_prev do Begin PixelFormat:=pf1bit; Height:=test_data.Tinggi; Width:=test_data.Lebar; End;//akhir with for x:=0 to test_data.Tinggi-1 do Begin for y:=0 to test_data.Lebar-1 do Begin if test_data.Kloning[x,y] = 1 then Begin Bmp_prev.Canvas.Pixels[x,y]:= clWhite; End//akhir if Else if test_data.Kloning[x,y] = 0 then Begin Bmp_prev.Canvas.Pixels[x,y]:= clBlack; End //buat ngetes array {else Bmp_prev.Canvas.Pixels[x,y]:= clRed;} End; End;//akhir for1 Finally Rekonstruksi:=Bmp_prev; End;//akhir try {menggenerate Form baru dalam runtime program dan meng-assignkan nama baru kepreviewImagenya; } end; function Thinkan(var Gbr_4Thin:TBinData):TBinData; //inputnya diganti TBinData var //variabel local Gbr_Hsl_Thin,Gbr_Tmp,Gbr_Buffer : Array of array of byte; //Gbr_Buffer :Array of array of Char; i, j,count,endpoint_counter :cardinal; konektivitas,zigmaNK,Nk1,Nk3,Nk5,Nk7: integer; Label Mulai_cocokan;//deklarasi LABEL //mulai function check_thin----> Begin //rumus konektivitas Cn=Zigma(Nk)-(Nk.Nk+1.Nk+2) setLength(Gbr_Hsl_Thin,Gbr_4Thin.Tinggi,Gbr_4Thin.Lebar); setLength(Gbr_Tmp,Gbr_4Thin.Tinggi,Gbr_4Thin.Lebar); setLength(Gbr_Buffer,Gbr_4Thin.Tinggi,Gbr_4Thin.Lebar); //t4 mencatat yang akan disetPutih
76
//Gbr_Tmp:=Gbr_4Thin.Kloning; Mulai_cocokan: //mulai block program count:=0; //===ngeset pixel buffer image kembali ke hitam semua======// for i:=low(Gbr_Buffer)+1 to High(Gbr_Buffer)-1 do //baris Begin for j:=low(Gbr_Buffer[i])+1 to High(Gbr_Buffer[i])-1 do //kolom Begin //count:=count+1; Gbr_buffer[i,j]:=0; End End; //===ngeset pixel buffer image kembali ke hitam semua======//
//=========================M1_template_matching_===================/ / for i:=low(Gbr_4Thin.Kloning)+1 to High(Gbr_4Thin.Kloning)-1 do //baris Begin for j:=low(Gbr_4Thin.Kloning[i])+1 to High(Gbr_4Thin.Kloning[i])-1 do //kolom Begin if (Gbr_4Thin.Kloning[i,j]=0)And ((Gbr_4Thin.Kloning[i1,j]=1) And (Gbr_4Thin.Kloning[i+1,j]=0)) Then Begin konektivitas:=0;Nk1:=0;Nk3:=0;Nk5:=0;Nk7:=0; Nk1:=Gbr_4Thin.Kloning[i,j+1]((Gbr_4Thin.Kloning[i,j+1])*(Gbr_4Thin.Kloning[i+1,j+1])*(Gbr_4Thin. Kloning[i+1,j])); Nk3:=Gbr_4Thin.Kloning[i+1,j]((Gbr_4Thin.Kloning[i+1,j])*(Gbr_4Thin.Kloning[i+1,j1])*(Gbr_4Thin.Kloning[i,j-1])); Nk5:=Gbr_4Thin.Kloning[i,j-1]-((Gbr_4Thin.Kloning[i,j1])*(Gbr_4Thin.Kloning[i-1,j-1])*(Gbr_4Thin.Kloning[i-1,j])); Nk7:=Gbr_4Thin.Kloning[i-1,j]-((Gbr_4Thin.Kloning[i1,j])*(Gbr_4Thin.Kloning[i-1,j+1])*(Gbr_4Thin.Kloning[i,j+1])); //zigmaNK:=Nk1+Nk3+Nk5+Nk7; konektivitas:=(Nk1)+(Nk3)+(Nk5)+(Nk7); //pembuktian EndPoint==============================// endpoint_counter:=0; if Gbr_4Thin.Kloning[i,j+1]=0 then //N1 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j+1]=0 then //N2 Begin endpoint_counter:=endpoint_counter+1;
77
End; if Gbr_4Thin.Kloning[i+1,j]=0 then //N3 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j-1]=0 then //N4 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i,j-1]=0 then //N5 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j-1]=0 then //N6 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j]=0 then //N7 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j+1]=0 then //N8 Begin endpoint_counter:=endpoint_counter+1; End; //pembuktian EndPoint==============================// //pencocokan konektivitas=========================// if (konektivitas=1) and (endpoint_counter>1) then Begin Gbr_Buffer[i,j]:=1; //Gbr_Buffer[i-1,j]:=1; Gbr_Buffer[i+1,j]:=0; End;//akhir if2 //pencocokan konektivitas=========================// End//akhir If1 {Else Gbr_Buffer[i,j]:=0;} End//akhir for2 End;//akhir for1 //=========================M1_template_matching_===================/ /
78
//=========================M2_template_matching_===================/ / for i:=High(Gbr_4Thin.Kloning)-1 downto low(Gbr_4Thin.Kloning)+1 do //baris Begin for j:=low(Gbr_4Thin.Kloning[i])+1 to High(Gbr_4Thin.Kloning[i])-1 do //kolom Begin if (Gbr_4Thin.Kloning[i,j]=0)and ((Gbr_4Thin.Kloning[i,j1]=1) And (Gbr_4Thin.Kloning[i,j+1]=0)) Then //templateNya Begin konektivitas:=0;Nk1:=0;Nk3:=0;Nk5:=0;Nk7:=0; Nk1:=Gbr_4Thin.Kloning[i,j+1]((Gbr_4Thin.Kloning[i,j+1])*(Gbr_4Thin.Kloning[i+1,j+1])*(Gbr_4Thin. Kloning[i+1,j])); Nk3:=Gbr_4Thin.Kloning[i+1,j]((Gbr_4Thin.Kloning[i+1,j])*(Gbr_4Thin.Kloning[i+1,j1])*(Gbr_4Thin.Kloning[i,j-1])); Nk5:=Gbr_4Thin.Kloning[i,j-1]-((Gbr_4Thin.Kloning[i,j1])*(Gbr_4Thin.Kloning[i-1,j-1])*(Gbr_4Thin.Kloning[i-1,j])); Nk7:=Gbr_4Thin.Kloning[i-1,j]-((Gbr_4Thin.Kloning[i1,j])*(Gbr_4Thin.Kloning[i-1,j+1])*(Gbr_4Thin.Kloning[i,j+1])); //zigmaNK:=Nk1+Nk3+Nk5+Nk7; konektivitas:=(Nk1)+(Nk3)+(Nk5)+(Nk7); //pembuktian EndPoint==============================// endpoint_counter:=0; if Gbr_4Thin.Kloning[i,j+1]=0 then //N1 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j+1]=0 then //N2 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j]=0 then //N3 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j-1]=0 then //N4 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i,j-1]=0 then //N5 Begin endpoint_counter:=endpoint_counter+1; End;
79
if Gbr_4Thin.Kloning[i-1,j-1]=0 then //N6 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j]=0 then //N7 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j+1]=0 then //N8 Begin endpoint_counter:=endpoint_counter+1; End; //pembuktian EndPoint==============================// //pencocokan konektivitas=========================// if (konektivitas=1) and (endpoint_counter>1) then Begin Gbr_Buffer[i,j]:=1; //Gbr_Buffer[i,j-1]:=1; Gbr_Buffer[i,j+1]:=0; End;//akhir if2 //pencocokan konektivitas=========================// End//akhir If1 {Else Gbr_Buffer[i,j]:=0;} End//akhir for2 End;//akhir for1 //=========================M2_template_matching_===================/ /
//=========================M3_template_matching_===================/ / for i:=High(Gbr_4Thin.Kloning)-1 downto low(Gbr_4Thin.Kloning)+1 do //baris Begin for j:=High(Gbr_4Thin.Kloning[i])-1 downto low(Gbr_4Thin.Kloning[i])+1 do //kolom Begin if (Gbr_4Thin.Kloning[i,j]=0)and ((Gbr_4Thin.Kloning[i1,j]=0) And (Gbr_4Thin.Kloning[i+1,j]=1)) Then Begin konektivitas:=0;Nk1:=0;Nk3:=0;Nk5:=0;Nk7:=0; Nk1:=Gbr_4Thin.Kloning[i,j+1]((Gbr_4Thin.Kloning[i,j+1])*(Gbr_4Thin.Kloning[i+1,j+1])*(Gbr_4Thin. Kloning[i+1,j]));
80
Nk3:=Gbr_4Thin.Kloning[i+1,j]((Gbr_4Thin.Kloning[i+1,j])*(Gbr_4Thin.Kloning[i+1,j1])*(Gbr_4Thin.Kloning[i,j-1])); Nk5:=Gbr_4Thin.Kloning[i,j-1]-((Gbr_4Thin.Kloning[i,j1])*(Gbr_4Thin.Kloning[i-1,j-1])*(Gbr_4Thin.Kloning[i-1,j])); Nk7:=Gbr_4Thin.Kloning[i-1,j]-((Gbr_4Thin.Kloning[i1,j])*(Gbr_4Thin.Kloning[i-1,j+1])*(Gbr_4Thin.Kloning[i,j+1])); //zigmaNK:=Nk1+Nk3+Nk5+Nk7; konektivitas:=(Nk1)+(Nk3)+(Nk5)+(Nk7); //pembuktian EndPoint==============================// endpoint_counter:=0; if Gbr_4Thin.Kloning[i,j+1]=0 then //N1 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j+1]=0 then //N2 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j]=0 then //N3 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j-1]=0 then //N4 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i,j-1]=0 then //N5 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j-1]=0 then //N6 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j]=0 then //N7 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j+1]=0 then //N8 Begin endpoint_counter:=endpoint_counter+1; End; //pembuktian EndPoint==============================//
81
//pencocokan konektivitas=========================// if (konektivitas=1) and (endpoint_counter>1)then Begin Gbr_Buffer[i,j]:=1; Gbr_Buffer[i-1,j]:=0; //Gbr_Buffer[i+1,j]:=1; End;//akhir if2 //pencocokan konektivitas=========================// End//akhir If1 {Else Gbr_Buffer[i,j]:=0;} End//akhir for2 End;//akhir for1 //=========================M3_template_matching_===================/ /
//=========================M4_template_matching_===================/ / for i:=low(Gbr_4Thin.Kloning)+1 to High(Gbr_4Thin.Kloning)-1 do //baris Begin for j:=High(Gbr_4Thin.Kloning[i])-1 downto low(Gbr_4Thin.Kloning[i])+1 do //kolom Begin if (Gbr_4Thin.Kloning[i,j]=0)and ((Gbr_4Thin.Kloning[i,j1]=0) And (Gbr_4Thin.Kloning[i,j+1]=1)) Then Begin konektivitas:=0;Nk1:=0;Nk3:=0;Nk5:=0;Nk7:=0; Nk1:=Gbr_4Thin.Kloning[i,j+1]((Gbr_4Thin.Kloning[i,j+1])*(Gbr_4Thin.Kloning[i+1,j+1])*(Gbr_4Thin. Kloning[i+1,j])); Nk3:=Gbr_4Thin.Kloning[i+1,j]((Gbr_4Thin.Kloning[i+1,j])*(Gbr_4Thin.Kloning[i+1,j1])*(Gbr_4Thin.Kloning[i,j-1])); Nk5:=Gbr_4Thin.Kloning[i,j-1]-((Gbr_4Thin.Kloning[i,j1])*(Gbr_4Thin.Kloning[i-1,j-1])*(Gbr_4Thin.Kloning[i-1,j])); Nk7:=Gbr_4Thin.Kloning[i-1,j]-((Gbr_4Thin.Kloning[i1,j])*(Gbr_4Thin.Kloning[i-1,j+1])*(Gbr_4Thin.Kloning[i,j+1])); //zigmaNK:=Nk1+Nk3+Nk5+Nk7; konektivitas:=(Nk1)+(Nk3)+(Nk5)+(Nk7); //pembuktian EndPoint==============================// endpoint_counter:=0; if Gbr_4Thin.Kloning[i,j+1]=0 then //N1 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j+1]=0 then //N2 Begin
82
endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j]=0 then //N3 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j-1]=0 then //N4 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i,j-1]=0 then //N5 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j-1]=0 then //N6 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j]=0 then //N7 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j+1]=0 then //N8 Begin endpoint_counter:=endpoint_counter+1 End; //pembuktian EndPoint==============================// //pencocokan konektivitas=========================// if (konektivitas=1) and (endpoint_counter>1)then Begin Gbr_Buffer[i,j]:=1; Gbr_Buffer[i,j-1]:=0; //Gbr_Buffer[i,j+1]:=1; End;//akhir if2 //pencocokan konektivitas=========================// End//akhir If1 {Else Gbr_Buffer[i,j]:=0;} End//akhir for2 End;//akhir for1 //=========================M4_template_matching_===================/ /
83
//=========================operasi penghapusan pixel (mulai thinning) = set to white ==================// for i:=low(Gbr_Buffer) to High(Gbr_Buffer) do //baris Begin for j:=low(Gbr_Buffer[i]) to High(Gbr_Buffer[i]) do //kolom Begin if Gbr_Buffer[i,j]=1 then Begin count:=count+1; Gbr_4Thin.Kloning[i,j]:=1; End; if i=low(Gbr_Buffer) Then //ngeset paling tepi Begin Gbr_4Thin.Kloning[i,j]:=1; End; if i=High(Gbr_Buffer) Then //ngeset paling tepi Begin Gbr_4Thin.Kloning[i,j]:=1; End; if j=low(Gbr_Buffer[i]) Then //ngeset paling tepi Begin Gbr_4Thin.Kloning[i,j]:=1; End; if j=High(Gbr_Buffer[i]) Then //ngeset paling tepi Begin Gbr_4Thin.Kloning[i,j]:=1; End; End End; //=========================operasi penghapusan pixel (mulai thinning) ==================// if count>0 then Begin goto mulai_cocokan; End; Application.CreateForm(TView_Thin, View_Thin); View_Thin.Caption:='rekonstruksi Bitmap dari Array'; View_Thin.GBR.Picture.Bitmap:=Rekonstruksi(Gbr_4Thin); End; //akhir function check_thin function smoothing(var Gbr_4Thin:TBinData):TBinData; var //variabel local Gbr_Buffer : Array of array of byte; i, j,endpoint_counter :cardinal; konektivitas,Nk1,Nk3,Nk5,Nk7: integer; Begin setLength(Gbr_Buffer,Gbr_4Thin.Tinggi,Gbr_4Thin.Lebar); //t4 mencatat yang akan disetPutih for i:=low(Gbr_Buffer)+1 to High(Gbr_Buffer)-1 do //baris
84
Begin for j:=low(Gbr_Buffer[i])+1 to High(Gbr_Buffer[i])-1 do //kolom Begin Gbr_buffer[i,j]:=0; End End; for i:=low(Gbr_4Thin.Kloning)+1 to High(Gbr_4Thin.Kloning)-1 do //baris Begin for j:=low(Gbr_4Thin.Kloning[i])+1 to High(Gbr_4Thin.Kloning[i])-1 do //kolom Begin if Gbr_4Thin.Kloning[i,j]=0 Then Begin konektivitas:=0;Nk1:=0;Nk3:=0;Nk5:=0;Nk7:=0; Nk1:=Gbr_4Thin.Kloning[i,j+1]((Gbr_4Thin.Kloning[i,j+1])*(Gbr_4Thin.Kloning[i+1,j+1])*(Gbr_4Thin. Kloning[i+1,j])); Nk3:=Gbr_4Thin.Kloning[i+1,j]((Gbr_4Thin.Kloning[i+1,j])*(Gbr_4Thin.Kloning[i+1,j1])*(Gbr_4Thin.Kloning[i,j-1])); Nk5:=Gbr_4Thin.Kloning[i,j-1]-((Gbr_4Thin.Kloning[i,j1])*(Gbr_4Thin.Kloning[i-1,j-1])*(Gbr_4Thin.Kloning[i-1,j])); Nk7:=Gbr_4Thin.Kloning[i-1,j]-((Gbr_4Thin.Kloning[i1,j])*(Gbr_4Thin.Kloning[i-1,j+1])*(Gbr_4Thin.Kloning[i,j+1])); //zigmaNK:=Nk1+Nk3+Nk5+Nk7; konektivitas:=(Nk1)+(Nk3)+(Nk5)+(Nk7); //pembuktian EndPoint==============================// endpoint_counter:=0; if Gbr_4Thin.Kloning[i,j+1]=0 then //N1 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j+1]=0 then //N2 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j]=0 then //N3 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i+1,j-1]=0 then //N4 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i,j-1]=0 then //N5
85
Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j-1]=0 then //N6 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j]=0 then //N7 Begin endpoint_counter:=endpoint_counter+1; End; if Gbr_4Thin.Kloning[i-1,j+1]=0 then //N8 Begin endpoint_counter:=endpoint_counter+1; End; //pembuktian EndPoint==============================// //pencocokan konektivitas=========================// if (konektivitas=2) and (endpoint_counter<=2) then Begin Gbr_Buffer[i,j]:=2; End;//akhir if2 End;//akhir if1 //pencocokan konektivitas=========================// End//akhir for2 End;//akhir for1 for i:=low(Gbr_Buffer) to High(Gbr_Buffer) do //baris Begin for j:=low(Gbr_Buffer[i]) to High(Gbr_Buffer[i]) do //kolom Begin if Gbr_Buffer[i,j]=2 then Begin //count:=count+1; Gbr_4Thin.Kloning[i,j]:=1; End; if i=low(Gbr_Buffer) Then //ngeset paling tepi Begin Gbr_4Thin.Kloning[i,j]:=1; End; if i=High(Gbr_Buffer) Then //ngeset paling tepi Begin Gbr_4Thin.Kloning[i,j]:=1; End; if j=low(Gbr_Buffer[i]) Then //ngeset paling tepi Begin Gbr_4Thin.Kloning[i,j]:=1;
86
End; if j=High(Gbr_Buffer[i]) Then //ngeset paling tepi Begin Gbr_4Thin.Kloning[i,j]:=1; End; End //akhir dari for2 End;//akhir dari for1 Smoothing:=Gbr_4Thin; //hasil dari smoothing di parse keluar fungsi End;//akhir fungsi smoothing function acute_angle_emphasis(var gbr_msk:TBinData):TBinData; var Gbr_Buffer : Array of array of byte; i, j:cardinal; Begin setLength(Gbr_Buffer,gbr_msk.Tinggi,gbr_msk.Lebar); for i:=low(Gbr_Buffer)+2 to High(Gbr_Buffer)-2 do Begin for j:=low(Gbr_Buffer)+2 to High(gbr_Buffer)-2 do Begin {D template} {D1}if {/1/}(gbr_msk.Kloning[i-2,j-2]=0) and (gbr_msk.Kloning[i-2,j-1]=0) and (gbr_msk.Kloning[i-2,j]=1) and (gbr_msk.Kloning[i-2,j+1]=0) and (gbr_msk.Kloning[i-2,j+2]=0) and{/2/}(gbr_msk.Kloning[i-1,j-2]=0) and (gbr_msk.Kloning[i-1,j1]=0) and (gbr_msk.Kloning[i-1,j]=1) and (gbr_msk.Kloning[i1,j+1]=0) and (gbr_msk.Kloning[i-1,j+2]=0) and{/3/} (gbr_msk.Kloning[i,j-2]=0) and (gbr_msk.Kloning[i,j-1]=0) and (gbr_msk.Kloning[i,j]=0) and (gbr_msk.Kloning[i,j+1]=0) and (gbr_msk.Kloning[i,j+2]=0) and{/4/} (gbr_msk.Kloning[i+1,j-2]=0) and (gbr_msk.Kloning[i+1,j-1]=0) and (gbr_msk.Kloning[i+1,j]=0) and (gbr_msk.Kloning[i+1,j+1]=0) and (gbr_msk.Kloning[i+1,j+2]=0) and{/5/}(gbr_msk.Kloning[i+2,j-1]=0) and (gbr_msk.Kloning[i+2,j]=0) and (gbr_msk.Kloning[i+2,j+1]=0) then Begin Gbr_Buffer[i,j]:=0; End; {D2}if {/1/}(gbr_msk.Kloning[i-2,j-2]=0) and (gbr_msk.Kloning[i-2,j-1]=1) and (gbr_msk.Kloning[i-2,j]=1) and (gbr_msk.Kloning[i-2,j+1]=0) and (gbr_msk.Kloning[i-2,j+2]=0) and{/2/}(gbr_msk.Kloning[i-1,j-2]=0) and (gbr_msk.Kloning[i-1,j1]=0) and (gbr_msk.Kloning[i-1,j]=1) and (gbr_msk.Kloning[i1,j+1]=0) and (gbr_msk.Kloning[i-1,j+2]=0) and{/3/} (gbr_msk.Kloning[i,j-2]=0) and (gbr_msk.Kloning[i,j-1]=0) and (gbr_msk.Kloning[i,j]=0) and (gbr_msk.Kloning[i,j+1]=0) and (gbr_msk.Kloning[i,j+2]=0) and{/4/} (gbr_msk.Kloning[i+1,j-2]=0) and (gbr_msk.Kloning[i+1,j-1]=0) and (gbr_msk.Kloning[i+1,j]=0) and (gbr_msk.Kloning[i+1,j+1]=0) and (gbr_msk.Kloning[i+1,j+2]=0) and{/5/}(gbr_msk.Kloning[i+2,j-1]=0) and (gbr_msk.Kloning[i+2,j]=0) and (gbr_msk.Kloning[i+2,j+1]=0) then Begin
87
Gbr_Buffer[i,j]:=0; End; {D3}if {/1/}(gbr_msk.Kloning[i-2,j-2]=0) and (gbr_msk.Kloning[i-2,j-1]=0) and (gbr_msk.Kloning[i-2,j]=1) and (gbr_msk.Kloning[i-2,j+1]=1) and (gbr_msk.Kloning[i-2,j+2]=0) and{/2/}(gbr_msk.Kloning[i-1,j-2]=0) and (gbr_msk.Kloning[i-1,j1]=0) and (gbr_msk.Kloning[i-1,j]=1) and (gbr_msk.Kloning[i1,j+1]=0) and (gbr_msk.Kloning[i-1,j+2]=0) and{/3/} (gbr_msk.Kloning[i,j-2]=0) and (gbr_msk.Kloning[i,j-1]=0) and (gbr_msk.Kloning[i,j]=0) and (gbr_msk.Kloning[i,j+1]=0) and (gbr_msk.Kloning[i,j+2]=0) and{/4/} (gbr_msk.Kloning[i+1,j-2]=0) and (gbr_msk.Kloning[i+1,j-1]=0) and (gbr_msk.Kloning[i+1,j]=0) and (gbr_msk.Kloning[i+1,j+1]=0) and (gbr_msk.Kloning[i+1,j+2]=0) and{/5/}(gbr_msk.Kloning[i+2,j-1]=0) and (gbr_msk.Kloning[i+2,j]=0) and (gbr_msk.Kloning[i+2,j+1]=0) then Begin Gbr_Buffer[i,j]:=0; End; {D4}if {/1/}(gbr_msk.Kloning[i-2,j-2]=0) and (gbr_msk.Kloning[i-2,j-1]=1) and (gbr_msk.Kloning[i-2,j]=1) and (gbr_msk.Kloning[i-2,j+1]=0) and (gbr_msk.Kloning[i-2,j+2]=0) and{/2/}(gbr_msk.Kloning[i-1,j-2]=0) and (gbr_msk.Kloning[i-1,j1]=1) and (gbr_msk.Kloning[i-1,j]=1) and (gbr_msk.Kloning[i1,j+1]=0) and (gbr_msk.Kloning[i-1,j+2]=0) and{/3/} (gbr_msk.Kloning[i,j-2]=0) and (gbr_msk.Kloning[i,j-1]=0) and (gbr_msk.Kloning[i,j]=0) and (gbr_msk.Kloning[i,j+1]=0) and (gbr_msk.Kloning[i,j+2]=0) and{/4/} (gbr_msk.Kloning[i+1,j-2]=0) and (gbr_msk.Kloning[i+1,j-1]=0) and (gbr_msk.Kloning[i+1,j]=0) and (gbr_msk.Kloning[i+1,j+1]=0) and (gbr_msk.Kloning[i+1,j+2]=0) and{/5/}(gbr_msk.Kloning[i+2,j-1]=0) and (gbr_msk.Kloning[i+2,j]=0) and (gbr_msk.Kloning[i+2,j+1]=0) then Begin Gbr_Buffer[i,j]:=0; End; {D5}if {/1/}(gbr_msk.Kloning[i-2,j-2]=0) and (gbr_msk.Kloning[i-2,j-1]=0) and (gbr_msk.Kloning[i-2,j]=1) and (gbr_msk.Kloning[i-2,j+1]=1) and (gbr_msk.Kloning[i-2,j+2]=0) and{/2/}(gbr_msk.Kloning[i-1,j-2]=0) and (gbr_msk.Kloning[i-1,j1]=0) and (gbr_msk.Kloning[i-1,j]=1) and (gbr_msk.Kloning[i1,j+1]=1) and (gbr_msk.Kloning[i-1,j+2]=0) and{/3/} (gbr_msk.Kloning[i,j-2]=0) and (gbr_msk.Kloning[i,j-1]=0) and (gbr_msk.Kloning[i,j]=0) and (gbr_msk.Kloning[i,j+1]=0) and (gbr_msk.Kloning[i,j+2]=0) and{/4/} (gbr_msk.Kloning[i+1,j-2]=0) and (gbr_msk.Kloning[i+1,j-1]=0) and (gbr_msk.Kloning[i+1,j]=0) and (gbr_msk.Kloning[i+1,j+1]=0) and (gbr_msk.Kloning[i+1,j+2]=0) and{/5/}(gbr_msk.Kloning[i+2,j-1]=0) and (gbr_msk.Kloning[i+2,j]=0) and (gbr_msk.Kloning[i+2,j+1]=0) then Begin Gbr_Buffer[i,j]:=0; End; {U template}
88
{U1}if {/1/} (gbr_msk.Kloning[i-2,j-1]=0) and (gbr_msk.Kloning[i-2,j]=0) and (gbr_msk.Kloning[i-2,j+1]=0) and{/2/}(gbr_msk.Kloning[i-1,j-2]=0) and (gbr_msk.Kloning[i-1,j1]=0) and (gbr_msk.Kloning[i-1,j]=0) and (gbr_msk.Kloning[i1,j+1]=0) and (gbr_msk.Kloning[i-1,j+2]=0) and{/3/} (gbr_msk.Kloning[i,j-2]=0) and (gbr_msk.Kloning[i,j-1]=0) and (gbr_msk.Kloning[i,j]=0) and (gbr_msk.Kloning[i,j+1]=0) and (gbr_msk.Kloning[i,j+2]=0) and{/4/} (gbr_msk.Kloning[i+1,j-2]=0) and (gbr_msk.Kloning[i+1,j-1]=0) and (gbr_msk.Kloning[i+1,j]=1) and (gbr_msk.Kloning[i+1,j+1]=0) and (gbr_msk.Kloning[i+1,j+2]=0) and{/5/}(gbr_msk.Kloning[i+2,j-2]=0) and (gbr_msk.Kloning[i+2,j1]=0) and (gbr_msk.Kloning[i+2,j]=1) and (gbr_msk.Kloning[i+2,j+1]=0) and (gbr_msk.Kloning[i+2,j+2]=0) then Begin Gbr_Buffer[i,j]:=0; End; {U2}if {/1/} (gbr_msk.Kloning[i-2,j-1]=0) and (gbr_msk.Kloning[i-2,j]=0) and (gbr_msk.Kloning[i-2,j+1]=0) and{/2/}(gbr_msk.Kloning[i-1,j-2]=0) and (gbr_msk.Kloning[i-1,j1]=0) and (gbr_msk.Kloning[i-1,j]=0) and (gbr_msk.Kloning[i1,j+1]=0) and (gbr_msk.Kloning[i-1,j+2]=0) and{/3/} (gbr_msk.Kloning[i,j-2]=0) and (gbr_msk.Kloning[i,j-1]=0) and (gbr_msk.Kloning[i,j]=0) and (gbr_msk.Kloning[i,j+1]=0) and (gbr_msk.Kloning[i,j+2]=0) and{/4/} (gbr_msk.Kloning[i+1,j-2]=0) and (gbr_msk.Kloning[i+1,j-1]=0) and (gbr_msk.Kloning[i+1,j]=1) and (gbr_msk.Kloning[i+1,j+1]=0) and (gbr_msk.Kloning[i+1,j+2]=0) and{/5/}(gbr_msk.Kloning[i+2,j-2]=0) and (gbr_msk.Kloning[i+2,j1]=1) and (gbr_msk.Kloning[i+2,j]=1) and (gbr_msk.Kloning[i+2,j+1]=0) and (gbr_msk.Kloning[i+2,j+2]=0) then Begin Gbr_Buffer[i,j]:=0; End; {U3}if {/1/} (gbr_msk.Kloning[i-2,j-1]=0) and (gbr_msk.Kloning[i-2,j]=0) and (gbr_msk.Kloning[i-2,j+1]=0) and{/2/}(gbr_msk.Kloning[i-1,j-2]=0) and (gbr_msk.Kloning[i-1,j1]=0) and (gbr_msk.Kloning[i-1,j]=0) and (gbr_msk.Kloning[i1,j+1]=0) and (gbr_msk.Kloning[i-1,j+2]=0) and{/3/} (gbr_msk.Kloning[i,j-2]=0) and (gbr_msk.Kloning[i,j-1]=0) and (gbr_msk.Kloning[i,j]=0) and (gbr_msk.Kloning[i,j+1]=0) and (gbr_msk.Kloning[i,j+2]=0) and{/4/} (gbr_msk.Kloning[i+1,j-2]=0) and (gbr_msk.Kloning[i+1,j-1]=0) and (gbr_msk.Kloning[i+1,j]=1) and (gbr_msk.Kloning[i+1,j+1]=0) and (gbr_msk.Kloning[i+1,j+2]=0) and{/5/}(gbr_msk.Kloning[i+2,j-2]=0) and (gbr_msk.Kloning[i+2,j1]=0) and (gbr_msk.Kloning[i+2,j]=1) and (gbr_msk.Kloning[i+2,j+1]=1) and (gbr_msk.Kloning[i+2,j+2]=0) then Begin Gbr_Buffer[i,j]:=0; End; {U4}if {/1/} (gbr_msk.Kloning[i-2,j-1]=0) and (gbr_msk.Kloning[i-2,j]=0) and (gbr_msk.Kloning[i-2,j+1]=0) and{/2/}(gbr_msk.Kloning[i-1,j-2]=0) and (gbr_msk.Kloning[i-1,j1]=0) and (gbr_msk.Kloning[i-1,j]=0) and (gbr_msk.Kloning[i-
89
1,j+1]=0) and (gbr_msk.Kloning[i-1,j+2]=0) and{/3/} (gbr_msk.Kloning[i,j-2]=0) and (gbr_msk.Kloning[i,j-1]=0) and (gbr_msk.Kloning[i,j]=0) and (gbr_msk.Kloning[i,j+1]=0) and (gbr_msk.Kloning[i,j+2]=0) and{/4/} (gbr_msk.Kloning[i+1,j-2]=0) and (gbr_msk.Kloning[i+1,j-1]=1) and (gbr_msk.Kloning[i+1,j]=1) and (gbr_msk.Kloning[i+1,j+1]=0) and (gbr_msk.Kloning[i+1,j+2]=0) and{/5/}(gbr_msk.Kloning[i+2,j-2]=0) and (gbr_msk.Kloning[i+2,j1]=1) and (gbr_msk.Kloning[i+2,j]=1) and (gbr_msk.Kloning[i+2,j+1]=0) and (gbr_msk.Kloning[i+2,j+2]=0) then Begin Gbr_Buffer[i,j]:=0; End; {U5}if {/1/} (gbr_msk.Kloning[i-2,j-1]=0) and (gbr_msk.Kloning[i-2,j]=0) and (gbr_msk.Kloning[i-2,j+1]=0) and{/2/}(gbr_msk.Kloning[i-1,j-2]=0) and (gbr_msk.Kloning[i-1,j1]=0) and (gbr_msk.Kloning[i-1,j]=0) and (gbr_msk.Kloning[i1,j+1]=0) and (gbr_msk.Kloning[i-1,j+2]=0) and{/3/} (gbr_msk.Kloning[i,j-2]=0) and (gbr_msk.Kloning[i,j-1]=0) and (gbr_msk.Kloning[i,j]=0) and (gbr_msk.Kloning[i,j+1]=0) and (gbr_msk.Kloning[i,j+2]=0) and{/4/} (gbr_msk.Kloning[i+1,j-2]=0) and (gbr_msk.Kloning[i+1,j-1]=0) and (gbr_msk.Kloning[i+1,j]=1) and (gbr_msk.Kloning[i+1,j+1]=1) and (gbr_msk.Kloning[i+1,j+2]=0) and{/5/}(gbr_msk.Kloning[i+2,j-2]=0) and (gbr_msk.Kloning[i+2,j1]=0) and (gbr_msk.Kloning[i+2,j]=1) and (gbr_msk.Kloning[i+2,j+1]=1) and (gbr_msk.Kloning[i+2,j+2]=0) then Begin Gbr_Buffer[i,j]:=0; End; End End;
for i:=low(Gbr_Buffer) to High(Gbr_Buffer) do //baris Begin for j:=low(Gbr_Buffer[i]) to High(Gbr_Buffer[i]) do //kolom Begin if Gbr_Buffer[i,j]=2 then Begin //count:=count+1; gbr_msk.Kloning[i,j]:=1; End; if i=low(Gbr_Buffer) Then //ngeset paling tepi Begin gbr_msk.Kloning[i,j]:=1; End; if i=High(Gbr_Buffer) Then //ngeset paling tepi Begin gbr_msk.Kloning[i,j]:=1; End; if j=low(Gbr_Buffer[i]) Then //ngeset paling tepi Begin
90
gbr_msk.Kloning[i,j]:=1; End; if j=High(Gbr_Buffer[i]) Then //ngeset paling tepi Begin gbr_msk.Kloning[i,j]:=1; End; End //akhir dari for2 End;//akhir dari for1 //pasing keluar hasil dari AAE proses acute_angle_emphasis:=gbr_msk; End; end.
6. AboutBox.pas unit AboutBox; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Buttons, ExtCtrls, jpeg, StdCtrls; type TAbout = class(TForm) Masuk_Button: TSpeedButton; frame_image: TImage; Tentang: TGroupBox; Algoritma: TLabel; Logo_Uni: TImage; Label1: TLabel; Label2: TLabel; Label3: TLabel; Label4: TLabel; Label5: TLabel; Label6: TLabel; Label7: TLabel; Label8: TLabel; Label9: TLabel; procedure FormCreate(Sender: TObject); procedure Masuk_ButtonClick(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormShow(Sender: TObject); private { Private declarations } public { Public declarations } end; var
91
About: TAbout; implementation uses Main; {$R *.dfm} procedure TAbout.FormCreate(Sender: TObject); begin With About do Begin Caption:='Tentang Program'; Top:=round(Utama.Height div 50); position:=poDesktopCenter; End end; procedure TAbout.Masuk_ButtonClick(Sender: TObject); begin Self.Close; end; procedure TAbout.FormClose(Sender: TObject; var Action: TCloseAction); begin Utama.Enabled:=True; Action:=caFree; end; procedure TAbout.FormShow(Sender: TObject); begin Utama.Enabled:=False; end; end.
7. Bantuan.pas unit bantuan; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons; type Thelp_frm = class(TForm) Label1: TLabel; StaticText1: TStaticText; StaticText2: TStaticText;
92
StaticText3: TStaticText; StaticText4: TStaticText; StaticText5: TStaticText; StaticText6: TStaticText; StaticText7: TStaticText; StaticText8: TStaticText; SpeedButton1: TSpeedButton; StaticText9: TStaticText; StaticText10: TStaticText; StaticText11: TStaticText; StaticText12: TStaticText; StaticText13: TStaticText; StaticText14: TStaticText; StaticText15: TStaticText; StaticText16: TStaticText; StaticText17: TStaticText; StaticText18: TStaticText; StaticText19: TStaticText; StaticText20: TStaticText; StaticText21: TStaticText; procedure SpeedButton1Click(Sender: TObject); procedure FormShow(Sender: TObject); private { Private declarations } public { Public declarations } end; var help_frm: Thelp_frm; implementation uses Main; {$R *.dfm} procedure Thelp_frm.SpeedButton1Click(Sender: TObject); begin Utama.Enabled:=True; close; end; procedure Thelp_frm.FormShow(Sender: TObject); begin Utama.Enabled:=False; end; end.
8. Prop.pas unit Prop;
93
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Buttons, Menus, StdCtrls; type TPropertis = class(TForm) Tombol_Group: TGroupBox; Buka_Tombol: TSpeedButton; Proses_tombol: TSpeedButton; Prop_gambar: TGroupBox; Simpan_Tombol: TSpeedButton; Keluar_Tombol: TSpeedButton; About_Tombol: TSpeedButton; NmFL: TLabel; SzFL: TLabel; check_prepro: TCheckBox; procedure CreateParams ( var Params : TCreateParams);override; procedure FormCreate(Sender: TObject); procedure Buka_TombolClick(Sender: TObject); procedure Proses_tombolClick(Sender: TObject); procedure Simpan_TombolClick(Sender: TObject); procedure Keluar_TombolClick(Sender: TObject); procedure About_TombolClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var Propertis: TPropertis; implementation uses Main,AboutBox,Prev,Prev_Thin,fungsi3; {$R *.dfm} Procedure TPropertis.CreateParams( var Params : tCreateParams ) ; Begin Inherited CreateParams( Params ) ; Params.Style := Params.Style and (not Windows.WS_POPUPWINDOW); // dapat juga berisi Params.Style and (not WS_CAPTION) End; procedure TPropertis.FormCreate(Sender: TObject); begin With Propertis do
94
Begin Height:=round(Screen.Height div 5); Width:=Utama.Width - 20; Left:=8; Top:= Utama.Height - (Height + 50); Tombol_Group.Left:=5; Tombol_Group.Top:=2; Tombol_Group.Height:=Propertis.Height-15; Tombol_Group.Caption:=''; Buka_Tombol.Top:=10; Buka_Tombol.Left:=6; Buka_Tombol.Height:=Tombol_Group.Height-18; Buka_Tombol.Width:=Buka_Tombol.Height; Tombol_Group.Width:=round((Buka_Tombol.Width*5)+(Buka_Tombol.Left*6) +3); Proses_Tombol.Height:=Buka_Tombol.Height; Proses_Tombol.Width:=Buka_Tombol.Height; Proses_Tombol.Top:=Buka_Tombol.Top; Proses_Tombol.Left:=Buka_Tombol.Width+(Buka_Tombol.Left * 2 ); Simpan_Tombol.Height:=Proses_Tombol.Height; Simpan_Tombol.Width:=Proses_Tombol.Height; Simpan_Tombol.Top:=Proses_Tombol.Top; Simpan_Tombol.Left:=(Proses_Tombol.Width*2)+(Buka_Tombol.Left * 3 ); Keluar_Tombol.Height:=Proses_Tombol.Height; Keluar_Tombol.Width:=Proses_Tombol.Height; Keluar_Tombol.Top:=Proses_Tombol.Top; Keluar_Tombol.Left:=(Proses_Tombol.Width*3)+(Buka_Tombol.Left * 4 ); About_Tombol.Height:=Proses_Tombol.Height; About_Tombol.Width:=Proses_Tombol.Height; About_Tombol.Top:=Proses_Tombol.Top; About_Tombol.Left:=(Proses_Tombol.Width*4)+(Buka_Tombol.Left * 5 ); Prop_gambar.Left:= Tombol_Group.Width+(Tombol_Group.Left*2); Prop_gambar.Top:=Tombol_Group.Top; Prop_gambar.Height:=Tombol_Group.Height; Prop_gambar.Width:=Propertis.Width (Tombol_Group.Width+(Tombol_Group.Left*4)); check_prepro.Top:=Prop_gambar.Height-25; check_prepro.TabStop:=False; End; end; procedure TPropertis.Buka_TombolClick(Sender: TObject); var Nw,Nh :integer; FileHeader: TBitmapfileheader;// InfoHeader: TBitmapinfoheader;// FileBitmap: TFilestream;// begin if Utama.Buka_Gambar_Dialog.Execute Then
95
Begin FileBitmap := TFilestream.Create(Utama.Buka_Gambar_Dialog.FileName, fmOpenRead); FileBitmap.Read(FileHeader, SizeOf(FileHeader)); // membaca FileHeader dr Bitmap FileBitmap.Read(InfoHeader, SizeOf(InfoHeader)); // membaca InfoHeader dr Bitmap FileBitmap.Free; Nw:=InfoHeader.biWidth; Nh:=InfoHeader.biHeight; if Nw <> Nh Then Begin MessageDlg('Ukuran Panjang Dan Lebar File Tidak Sama!, Yang Anda Pilih : '+IntToStr(Nw)+' X '+IntToStr(Nh),mtWarning,[mbOK],0); End Else if Nw = Nh Then Begin Application.CreateForm(TView,View); //Form HArus Diberi nama Saat Run-Time View.GBR.Picture.LoadFromFile(Utama.Buka_Gambar_Dialog.FileName); Utama.Jalankan_proses.Enabled:=True; Utama.Ambil_Gambar.Enabled:=False;//tab Menu untuk ngambil gambar Propertis.Proses_tombol.Enabled:=True; Propertis.Buka_Tombol.Enabled:=False; Propertis.NmFL.Caption:='Nama File Yang Digunakan : '+ExtractFileName(Utama.Buka_Gambar_Dialog.FileName); Propertis.SzFL.Caption:= 'Dimensi File : '+IntToStr(Nw)+' Pixel'+' X ' + IntToStr(Nh)+' Pixel'; End; End end; procedure TPropertis.Proses_tombolClick(Sender: TObject); var cobaBit1,cobaBit2,cobaBit3:TBitmap; hasil,hasil_biner_smooth,hasil_after_aae:Fungsi3.TBinData; begin if FileExists(Utama.Buka_Gambar_Dialog.FileName)Then Begin if (check_prepro.Checked=True) Then Begin View.GBR.Picture.Bitmap.LoadFromFile(Utama.Buka_Gambar_Dialog.FileNa me); View.Name:='RGB_Pic'; cobaBit1:=View.GBR.Picture.Bitmap; View.Caption:='Format Gambar:Biner'; cobaBit2:=grayscaling(cobaBit1); //GbrTmp di fungsi grayscaling jangan di Free karena merupakan input untuk fungsi binerisasi cobaBit3:=binerisasi(cobaBit2); hasil:=Duplikasi(cobaBit3);//mengkloning nilai image ke array
96
hasil_biner_smooth:=smoothing(hasil); hasil_after_aae:=acute_angle_emphasis(hasil_biner_smooth); View.GBR.Picture.Bitmap:=Rekonstruksi(hasil); View.Caption:='Format Gambar:Biner'; Thinkan(hasil_after_aae); Propertis.Simpan_Tombol.Enabled:=True; Propertis.Proses_tombol.Enabled:=False; Utama.Jalankan_proses.Enabled:=False; End Else if (propertis.check_prepro.Checked=False) Then Begin View.GBR.Picture.Bitmap.LoadFromFile(Utama.Buka_Gambar_Dialog.FileNa me); View.Name:='RGB_Pic'; cobaBit1:=View.GBR.Picture.Bitmap; View.Caption:='Format Gambar:Biner'; cobaBit2:=grayscaling(cobaBit1); //GbrTmp di fungsi grayscaling jangan di Free karena merupakan input untuk fungsi binerisasi cobaBit3:=binerisasi(cobaBit2); hasil:=Duplikasi(cobaBit3);//mengkloning nilai image ke array View.GBR.Picture.Bitmap:=Rekonstruksi(hasil); View.Caption:='Format Gambar:Biner'; Thinkan(hasil); Propertis.Simpan_Tombol.Enabled:=True; Propertis.Proses_tombol.Enabled:=False; Utama.Jalankan_proses.Enabled:=False; end end else MessageDlg('File Belum DiBuka',mtInformation,[mbOK],1); end; procedure TPropertis.Simpan_TombolClick(Sender: TObject); begin if Utama.Simpan_Gambar_Dialog.Execute Then Begin Utama.Simpan_Gambar_Dialog.DefaultExt:= GraphicExtension(TBitmap); View_Thin.GBR.Picture.Bitmap.SaveToFile(Utama.Simpan_Gambar_Dialog.F ileName+'.'+Utama.Simpan_Gambar_Dialog.DefaultExt); End end; procedure TPropertis.Keluar_TombolClick(Sender: TObject); begin if MessageDlg('Apakah Anda yakin ingin Keluar?',mtConfirmation,[mbYes,mbNo],0) = mrYes Then Begin
97
Application.Terminate; End; end; procedure TPropertis.About_TombolClick(Sender: TObject); begin Application.CreateForm(TAbout,About); end; end.