Identifikasi dan Pengenalan Citra Pelat Nomor Kendaraan dengan Metode Histogram Matching dan Template Matching Yuandri Trisaputra G64120004 R. Achmad Satriadi W. G64120055 Muhammad Zulfikar G64120062 Aiman Fakhri G64120090 Ammar Imron Muhammad G64120099 Departemen Ilmu Komputer Fakultas Matematika dan Ilmu Pengetahuan Alam Institut Pertanian Bogor
Pendahuluan Latar Belakang Saat ini sistem parkir yang biasa diterapkan di sebagian besar wilayah Indonesia adalah sistem parkir manual yang pencatatan nomor polisi kendaraan bermotor dilakukan dengan cara memasukkan nomor polisi kendaraan bermotor ke dalam komputer yang kemudian diproses untuk dicetak dan dihitung waktu parkirnya. Beberapa dari sistem parkir yang ada sudah mulai menggunakan kamera untuk menangkap gambar dari pelat nomor polisi kendaraan bermotor. Namun, pengambilan gambar tersebut hanya sebatas database berupa image saja. Faktor manusia juga bisa menyebabkan kesalahan pencatatan nomor kendaraan bermotor dan tentu saja hal ini akan memengaruhi lamanya proses pelayanan dari sistem parkir yang ada. Pengenalan pola merupakan pengelompokan data numerik dan simbolik (termasuk citra) secara otomatis oleh komputer agar suatu objek dalam citra dapat dikenali dan diinterpretasi, yang juga merupakan tahapan selanjutnya atau analisis dari pengolahan citra. Pengenalan pola dapat dimanfaatkan untuk menerapkan identifikasi pelat nomor secara otomatis yang sangat berguna bagi kehidupan seharihari, misalnya manajemen tempat parkir, monitoring lalu lintas, pengaturan tiket, dan pembayaran jalan tol. Oleh karena itu, proyek ini akan menerapkan pemrosesan citra untuk mengidentifikasi dan mengenali pelat nomor secara otomatis. Rumusan Masalah Rumusan masalah dalam proyek ini adalah bagaimana mengidentifikasi dan mengenali karakter yang ada pada pelat nomor.
Tujuan Tujuan dalam proyek ini adalah menerapkan pemrosesan citra yang dapat mengenali dan mengidentifikasi pelat nomor kendaraan di Indonesia. Ruang Lingkup Ruang lingkup dalam proyek ini, yaitu: 1. Citra pelat nomor yang digunakan adalah citra pelat nomor yang berwarna hitam, kuning, putih dan merah.
Tinjauan Pustaka Chi Square Chikuadrat (χ²) adalah uji statistik yang biasa digunakan untuk membandingkan data observasi dengan data yang diharapkan untuk menguji suatu hipotesis. chi square merupakan salah satu jenis uji komparatif non parametris yang dilakukan pada dua variabel, di mana skala data kedua variabel adalah nominal. (Apabila dari 2 variabel, ada 1 variabel dengan skala nominal maka dilakukan uji chisquare dengan merujuk bahwa harus digunakan uji pada derajat yang terendah). Euclidean Distance Euclidean distance adalah panjang dari garis lurus yang menghubungkan posisi dua buah objek. Secara umum diketahui bahwa jarak terpendek antara dua titik adalah garis lurus antara kedua titik tersebut. Model matematis Euclidean distance dapat dirumuskan dalam persamaan 1 dan 2 sebagai berikut:
w adalah indeks template karakter, nilai F train ke j,w merupakan matriks data citra yang dihasilkan dari bagian ke j, dengan j ∈ 1…m dan m adalah banyaknya bagian. F uji merupakan matriks dari citra input. Hasil pengukuran kemiripan yang didapat adalah d=min(dv). (Yulida et al. 2013)
Template Matching Template matching method digunakan untuk mengikuti objek atau pattern yang ingin dicari sebagai data input citra. Template matching mengenali potongan dengan korelasi tertinggi sebagai target untuk dibandingkan (Bae et al 2008). Nilai korelasi pada proyek ini menggunakan jarak euclidean.
Histogram Matching Histogram matching adalah proses di mana serangkaian waktu, gambar, atau data yang lebih tinggi skalar dimensi dimodifikasi sehingga histogram yang cocok dengan yang lain (referensi) dataset. Sebuah aplikasi umum ini adalah untuk mencocokkan gambar dari dua citra. (Paul Bourke 2011).
Metode Data Data yang digunakan pada proyek ini adalah data citra pelat nomor mobil sebanyak 26 citra yang dibagi menjadi 4 kelas yaitu pelat hitam, merah, putih dan kuning dengan pembagian masingmasing 15, 4, 3, dan 4. Tahapan Tahapantahapan yang dilakukan pada proyek ini dapat dilihat pada gambar 1.
Gambar 1 Tahapan proyek Akuisisi Citra Pada tahap awal dilakukan akuisisi citra untuk mendapatkan citra digital. Citra digital diambil dari internet. Kemudian dikelompokkan dalam beberapa kategori berdasarkan warna pelat nomor yaitu hitam, merah, putih, dan kuning.
Praposes Citra Setelah citra dikumpulkan, tahapan selanjutnya dilakukan praproses. Praproses citra yang dilakukan antara lain, segmentasi citra menjadi citra yang hanya mengandung pelat nomor saja, setelah itu dilakukan penyamaan ukuran citra pelat nomor menjadi 220 x 60 pixels. Kemudian citra dibuat menjadi citra biner dan diterapkan teknik morfologi citra opening dan citra keabuan. Citra biner digunakan untuk pengenalan karakter sedangkan citra keabuan untuk identifikasi jenis pelat nomor. Identifikasi Jenis Pada tahapan ini dilakukan identifikasi jenis kendaraan berdasarkan warna menggunakan histogram matching. Metode dalam tahapan ini dapat dilihat pada gambar 2.
Gambar 2 Metode Identifikasi Jenis Setiap data citra keabuan dicari histogramnya. Kemudian, histogram citra pelat nomor dari input pengguna dilakukan histogram matching dengan histogram data citra menggunakan perbandingan chisquare. Hasil perhitungan
perbandingan chisquare untuk setiap data citra dicari nilai minimumnya. Nilai minimum berarti citra tersebut mirip terhadap data citra yang ada dalam database. Setelah nilai minimum diperoleh, input citra pelat nomor dapat diidentifikasi menjadi jenis yang sesuai dengan kategori/jenis yang mirip pada data citra tersebut. Pengenalan Nomor Pada tahapan ini dilakukan pengenalan nomor kendaraan berdasarkan menggunakan template matching. Metode dalam tahapan ini dapat dilihat pada gambar 3.
Gambar 3 Metode Pengenalan Nomor Template Matching Hasil praproses input citra yang dalam bentuk citra biner dibagi menjadi ukuran yang sama besar yaitu 22 x 40 pixels. Citra biner diinvers untuk pelat nomor yang berwarna kuning dan merah. Kemudian, citra dibagibagi mulai dari sisi kiri hingga ke kanan dengan perpindahan 5 pixels. Setelah itu, citra tersebut dicocokkan dengan seluruh citra karakter/huruf menggunakan jarak euclidean. Citra karakter yang digunakan mempunyai background hitam dengan karakter berwarna putih. Data citra karakter diambil dari potongan karakter pada pelat nomor dan font karakter pelat nomor. Kemudian dicari nilai minimum dari hasil
jarak euclidean. Nilai minimum tersebut yang menjadi prediksi karakter yang ada dalam pelat nomor. Evaluasi Pada tahapan ini akan dievaluasi mengenai hasil pengenalan karakter beserta identifikasi jenis pelat nomor. Evaluasi dapat dilihat langsung dari hasil output yang diberikan. Lingkungan Pengembangan Proyek ini dilakukan dengan menggunakan perangkat keras dan perangkat lunak sebagai berikut: 1. Perangkat keras berupa laptop dengan spesifikasi sebagai berikut: ● Intel® Core™ i3 GHz ● RAM 6 GB ● Harddisk 500 GB ● Monitor ● Mouse dan keyboard 2. Perangkat lunak: ● Sistem operasi Windows 10 ● Code editor Notepad++ dan Codeblocks ● Library Opencv 2.4.9
Pembahasan Data Data yang diambil dari internet menggunakan google image. Citra pelat
nomor diambil sebanyak 26 citra yang dibagi menjadi 4 kelas yaitu pelat hitam (dapat dilihat pada gambar 4), merah (dapat dilihat pada gambar 5), putih (dapat dilihat pada gambar 6) dan kuning (dapat dilihat pada gambar 6) dengan pembagian masingmasing 15, 4, 3, dan 4. Sebanyak 1 citra diambil dari masingmasing kelas yang akan digunakan sebagai input citra.
Gambar 4 Contoh Citra dengan Pelat Nomor Warna Hitam
Gambar 5 Contoh Citra dengan Pelat Nomor Warna Merah
Gambar 6 Contoh Citra dengan Pelat Nomor Warna Putih
Gambar 7 Contoh Citra dengan Pelat Nomor Warna Kuning Praproses Citra Praproses yang dilakukan pada data citra yaitu mengambil bagian pelat nomor, kemudian mengubah ukuran citra menjadi 220 x 60 pixels. Kemudian citra dibuat menjadi citra biner dan citra keabuan. Citra biner hasil morfologi opening digunakan untuk pengenalan karakter sedangkan citra keabuan untuk identifikasi jenis pelat nomor. Hasil praproses citra dapat dilihat pada Gambar 8. Gambar 8 Contoh Hasil Praproses Citra
Identifikasi Jenis Pelat Nomor Identifikasi jenis pelat nomor dilakukan untuk mengetahui jenis pelat nomor input citra. Jenis pelat nomor tersebut yaitu pelat hitam, merah, putih, dan kuning. Pada tahapan ini digunakan citra keabuan dari hasil praproses. Contoh identifikasi jenis citra input (Gambar 9) sebagai berikut:
Gambar 9 Input Citra
Gambar 10 Citra Keabuan Dari citra keabuan (Gambar 10) kemudian dicari histogramnya kemudian dibandingkan dengan histogram data citra menggunakan chisquare. Hasil chisquare dapat dilihat pada Tabel 1. Tabel 1 Nilai chisquare antar histogram No
Nama File
Jenis Pelat
Nilai chisquare antar histogram
1
1.jpg
Hitam
35.8
2
2.jpg
Hitam
4.6
3 4
3.jpg 4.jpg
Hitam Hitam
2.2 19.9
5
5.jpg
Hitam
445.8
6 7
6.jpg 7.jpg
Hitam Hitam
8.8 4.1
8
8.jpg
Hitam
20.1
9 10
9.jpg 10.jpg
Hitam Hitam
0.9 3.7
11
11.jpg
Hitam
66.7
12
12.jpg
Hitam
1.9
13 14
13.jpg 14.jpg
Hitam Hitam
1.6 3.0
15
k1.jpg
Kuning
2.8
16 17
k2.jpg p1.jpg
Kuning Putih
0.5 145.8
18
p2.jpg
Putih
109.7
19
m1.jpg
Merah
34.4
20
m2.jpg
Merah
57.9
Dari tabel 1 terlihat nilai minimum terdapat pada nomor 16 dengan nilai 0.5 dengan jenis kuning. Oleh hal itu, input citra diidentifikasikan menjadi jenis warna kuning. Potongan program untuk identifikasi jenis dapat dilihat pada Lampiran 1. Pengenalan Nomor Pelat Pengenalan nomor pelat menggunakan citra biner dan template matching. Template yang digunakan adalah citra karakter dengan ukuran 22 x 40 pixels dengan latar belakang hitam dan warna karakternya adalah putih seperti Gambar 11 dan representasi dalam bentuk matriks seperti gambar 12. Selain itu, template juga menggunakan potongan karakter yang berada pada pelat nomor. Seluruh template yang digunakan sebanyak 279 citra.
Gambar 11 Contoh Template Citra Karakter
Gambar 12 Representasi Karakter 0 dalam Matriks Setelah itu citra biner dibagibagi mulai dari sisi kiri hingga ke kanan dengan perpindahan 5 pixels dengan ukuran yang sama seperti ukuran citra karakter. Representasi matriks citra biner dapat dilihat pada Gambar 13. Pembagian citra menjadi blokblok citra seperti gambar 14.
Gambar 13 Contoh Representasi Matriks Citra Biner
Gambar 14 Contoh Pembagian Citra Pada setiap bagianbagian citra tersebut dilakukan template matching. Template matching dilakukan hanya pada bagian yang border matriks tidak mengandung nilai 1. Dari Gambar 14, nomor (2) yang hanya dapat dilakukan template matching. Hasil template matching yang menjadi prediksi karakter yang ada dalam pelat nomor. Potongan program untuk melakukan pengenalan citra dapat dilihat pada Lampiran 2. Evaluasi Evaluasi dilakukan dengan melihat hasil identifikasi jenis dan pengenalan nomor. Evaluasi menggunakan 4 citra sebagai input yang merupakan 1 citra dari masingmasing jenis. Citra input yang digunakan dapat dilihat pada Gambar 15. Sedangkan hasil identifikasi dan pengenalan nomor dapat dilihat pada tabel 2. Gambar 15. Citra Input
Tabel 2. Hasil Evaluasi No
Identi Pengen fikasi alan Jenis Nomor
Evaluasi
Citra
1
Benar
Output
Salah
Citra
2
Benar
Output
TB J1T711 4J1 PQQ Benar
Citra Output
Salah
27833 X7KX
Citra
4 Output
K 11424 J
Salah
3
06J 67063 JF
Benar
Salah
Berdasarkan hasil evaluasi, semua citra input dapat diidentifikasi jenis kendaraan dengan benar. Sedangkan untuk pengenalan nomor pelat untuk semua citra input tidak akurat. Hal ini dapat disebabkan oleh template karakter yang digunakan atau penggunaan step/perpindahan pixels dalam pembagian citra dalam blokblok belum tepat.
Kesimpulan dan Saran Kesimpulan Kesimpulan dalam proyek ini adalah pemrosesan citra dapat diterapkan untuk mengidentifikasi dan mengenali pelat nomor kendaraan di Indonesia. Identifikasi jenis kendaraan menggunakan histogram matching, sedangkan pengenalan nomor pelat menggunakan template matching. Pada proyek ini, identifikasi jenis kendaraan memberikan hasil yang baik, sedangkan pengenalan nomor pada pelat tidak memberikan hasil yang baik. Saran Saran yang dapat diberikan untuk proyek ini adalah: 1. Menggunakan banyak citra untuk setiap kelas. 2. Memperbanyak template untuk setiap karakter. 3. Menggunakan teknik lain untuk pengenalan nomor pada pelat kendaraan.
Daftar Pustaka Bae SJ, Taek LS. 2008. Image Tracking Algorithm using Template Matching and PSNFm. International Journal of Control, Automation, and, Systems. 6(3):414423. Yulida S, Kusumawardhan A, Setijono H. 2013. PERANCANGAN SISTEM PENGENALAN PLAT NOMOR KENDARAAN MENGGUNAKAN METODE PRINCIPAL COMPONENT ANALYSIS . JURNAL TEKNIK POMITS. 2(1):5. doi:23373539.
Lampiran
Lampiran 1 Potongan Program untuk Identifikasi Jenis Kendaraan int n_citra = 22; int n_hitam = 14; int n_kuning = 3; int n_putih = 3; int n_merah = 2; int numBins = 256; float range[] = {0,255}; float *ranges[] = {range}; float comp[n_citra][2]; float temp; int argmin = 0; //input citra char namafile[100]; cout << "Nama file : ";
cin >> namafile; cout << "Jenis pelat/kendaraan : "; IplImage* img2 = cvLoadImage(namafile,1); plate(namafile); //membuat histogram untuk citra input CvHistogram *hist2 = cvCreateHist(1, &numBins, CV_HIST_ARRAY, ranges, 1); cvClearHist(hist2); IplImage* img_gray2 = cvCreateImage(cvGetSize(img2), IPL_DEPTH_8U, 1); cvSplit(img2, img_gray2, NULL, NULL, NULL); //cvShowImage("Grayscale",img_gray2); cvCalcHist(&img_gray2, hist2, 0, 0); cvNormalizeHist(hist2,2); IplImage* img[n_citra]; CvHistogram *hist[n_citra]; IplImage* img_gray[n_citra]; //menghitung histogram untuk setiap citra for (int num=0; (num
comp[num][1] = cvCompareHist(hist[num],hist2,CV_COMP_CHISQR); if (num
comp[num][1]) { temp = comp[num][1]; argmin = num; } } int tipe_biner; if (comp[argmin][0]==1) {cout << "Pelat Nomor Hitam atau Kendaraan Pribadi" << endl; tipe_biner = 1; } else if (comp[argmin][0]==2) {cout << "Pelat Nomor Kuning atau Angkutan Umum" << endl; tipe_biner = 2; } else if (comp[argmin][0]==3) {cout << "Pelat Nomor Putih" << endl; tipe_biner = 2; } else if (comp[argmin][0]==4) {cout << "Pelat Nomor Merah" << endl; tipe_biner = 1; } cvClearHist(hist2);
Lampiran 2 Potongan Program untuk Pengenalan Nomor //membuat template karakter int jum_char = 279; int width = 22; int height = 40; IplImage* imgk[jum_char]; CvMat *mat[jum_char]; CvScalar scal; float matrix[jum_char][width][height]; float trans[jum_char][height][width]; for (int num=0; (num<jum_char); num++) { char filename[100]; sprintf(filename,"./char/char (%d).jpg",num); imgk[num] = cvLoadImage(filename,CV_LOAD_IMAGE_GRAYSCALE); cvThreshold(imgk[num], imgk[num], 150, 255, CV_THRESH_BINARY); mat[num] = cvCreateMat(imgk[num]>height,imgk[num]>width,CV_32FC1); //cout << filename << endl; cvConvert(imgk[num], mat[num]); //system("pause"); } //matrix template for (int num=0;num< jum_char;num++) { for(int i=0;i<mat[num]>width;i++) { for(int j=0;j<mat[num]>height;j++) { scal = cvGet2D(mat[num],j,i); matrix[num][i][j] = scal.val[0]; trans[num][j][i] = matrix[num][i][j]; } } } //end template //citra binary threshold IplImage* image1 = cvLoadImage(namafile);
IplImage* imGray = cvCreateImage(cvGetSize(image1),IPL_DEPTH_8U,1); cvCvtColor(image1, imGray, CV_RGB2GRAY); IplImage* im_bw = cvCreateImage(cvGetSize(image1),IPL_DEPTH_8U,1); if(tipe_biner==1) { cvThreshold(imGray, im_bw, 150, 255, CV_THRESH_BINARY); } else cvThreshold(imGray, im_bw, 100, 255, CV_THRESH_BINARY_INV); cvShowImage("Biner", im_bw); cv::moveWindow("Biner",712,100); cvErode(im_bw, im_bw, NULL, 1); cvDilate(im_bw, im_bw, NULL, 1); cvShowImage("Opening",im_bw); cv::moveWindow("Opening",500,190); CvMat *matb; CvScalar scalb; matb = cvCreateMat(im_bw>height,im_bw>width,CV_32FC1); float transb[matb>height][matb>width]; float matrixb[matb>width][matb>height]; cvConvert(im_bw, matb); for(int i=0;i<matb>width;i++) { for(int j=0;j<matb>height;j++) { scalb = cvGet2D(matb,j,i); matrixb[i][j] = scalb.val[0]; transb[j][i] = matrixb[i][j]; } } //end biner cout << "Nomor polisi : ";// << endl; //template matching float d[jum_char]; float sum_square; float kode[height][width]; //float out[height][width]; int width_plate = 220; int width_block = 5; int height_block = 4; string hasil_no = "";
for(int it=0; it<=(width_platewidth)/width_block; it++){ int frame_width = it*width_block; for(int i=height_block;i
int cek_border_kiri;int cek_border_atas; int cek_border_kanan;int cek_border_bawah; for (int num=0; num<jum_char; num++){ sum_square = 0; cek_border_kiri = 0; cek_border_kanan = 0; cek_border_atas = 0; cek_border_bawah = 0; for(int i=0;i<mat[num]>height;i++) { for(int j=0;j<mat[num]>width;j++) { if(kode[i][0]==1&&kode[i][1]==1) cek_border_kiri = 1; if(kode[i][mat[num]>width]==1&&kode[i][mat[num]>width1]==1) cek_border_kanan = 1; //if(kode[0][j]==1) cek_border_atas = 1; //if(kode[mat[num]>height][j]==1) cek_border_bawah = 1; if ((int)trans[num][i][j]==255) { sum_square += (1kode[i][j])*(1kode[i][j]); //printf("1"); } else { sum_square += (0kode[i][j])*(0kode[i][j]); //printf("0"); } } //printf("\n"); } //system("pause"); d[num] = sqrt(sum_square);
//cout << num << " " << d[num] << endl; } temp = d[0]; argmin = 0; for(int num=1; num<jum_char; num++) { if (temp > d[num]) { temp = d[num]; argmin = num; } } //cout << d[argmin] << " "; if (cek_border_kiri==0 && cek_border_kanan==0 && cek_border_atas==0 && cek_border_bawah==0){ //printf("%d ",it); if (argmin<10) hasil_no += "0"; else if (argmin<20) hasil_no += "1"; else if (argmin<30) hasil_no += "2"; else if (argmin<40) hasil_no += "3"; else if (argmin<50) hasil_no += "4"; else if (argmin<60) hasil_no += "5"; else if (argmin<70) hasil_no += "6"; else if (argmin<80) hasil_no += "7"; else if (argmin<90) hasil_no += "8"; else if (argmin<100) hasil_no += "9"; else if (argmin<110) hasil_no += "A"; else if (argmin<120) hasil_no += "B"; else if (argmin<127) hasil_no += "C"; else if (argmin<130) hasil_no += "D"; else if (argmin<137) hasil_no += "E"; else if (argmin<146) hasil_no += "F"; else if (argmin<156) hasil_no += "G"; else if (argmin<161) hasil_no += "H"; else if (argmin<164) hasil_no += "I"; else if (argmin<168) hasil_no += "J"; else if (argmin<178) hasil_no += "K"; else if (argmin<181) hasil_no += "L"; else if (argmin<187) hasil_no += "M"; else if (argmin<193) hasil_no += "N"; else if (argmin<202) hasil_no += "O"; else if (argmin<214) hasil_no += "P"; else if (argmin<227) hasil_no += "Q"; else if (argmin<232) hasil_no += "R"; else if (argmin<238) hasil_no += "S"; else if (argmin<249) hasil_no += "T"; else if (argmin<255) hasil_no += "U"; else if (argmin<263) hasil_no += "V"; else if (argmin<266) hasil_no += "W"; else if (argmin<269) hasil_no += "X"; else if (argmin<273) hasil_no += "Y"; else if (argmin<275) hasil_no += "Z"; else hasil_no += " "; } } cout << hasil_no << endl; //end template matching