Membuat Deteksi Plat Nomer Kendaraan Sederhana Dengan OpenCV (Python)

Reading Time: 9 minutes

Pada postingan sebelumnya, Saya telah menulis bagaimana cara membuat program pendeteksi dan penghitung koin sederhana dengan menggunakan OpenCV [lihat disini]. Nah, dengan menggunakan konsep yang hampir sama persis dengan postingan sebelumnya, kali in Saya akan berbagi kepada pembaca sekalian cara membuat program deteksi plat nomer kendaraan sederhana dengan menggunakan OpenCV. Sederhana yang dimaksud di sini adalah proses berhenti pada deteksi plat nomer saja, tidak sampai pembacaan angka dan huruf yang terdapat pada plat nomer tersebut. Untuk program pembacaan angka dan huruf yang terdapat pada plat nomer kendaraan akan menjadi bahasan berikutnya. Bagaimana cara membuat program deteksi plat nomer kendaraan sederhana ini? Apakah sulit? Mari kita simak postingan ini sampai akhir.

Sebelum kita beranjak ke pembuatan program, tentu kita ingin mengetahui terlebih dahulu “Apakah hasil akhir dari program ini?”. Ya karena program ini masih sangat sederhana, maka hasil akhir program ini tampak seperti tangkapan layar di bawah ini.

Hasil Akhir program pendeteksi plat nomer kendaraan

Ya, tampak pada tangkapan layar di atas, program yang dibuat sebatas hanya mendeteksi plat nomer kendaraan. Belum sampai pada tahap membaca huruf dan angka yang terdapat pada plat nomer tersebut. Namun tenang saja, topik selanjutnya akan saya bahas bagaimana cara membaca teks dengan menggunakan openCV.

Baik, setelah kita mengetahui keluaran dari program ini, saatnya kita mulai saja untuk membuatnya. Terlebih dahulu, kita persiapkan tool dan library yang diperlukan untuk mengembangkan program ini. Tool dan library yang saya gunakan adalah sebagai berikut.

  1. Python versi 2.7.18
  2. OpenCV versi 4.1.0.25
  3. Imutils versi 0.5.4
  4. PyCharm Community Edition

Setelah kita siapkan tool dan library yang diperlukan, kita siap untuk mengembangkan program pendeteksi plat nomer kendaraan ini. Di sini, saya asumsikan Anda sudah memahami penggunaan PyCharm ya, sehingga saya tidak perlu menjelaskan panjang lebar bagaimana cara membuat project baru di PyCharm.

Inisiasi

Pada bagian inisiasi ini kita mempersiapkan PyCharm kita sehingga siap untuk membuat program. Oleh karena itu, ikutilah langkah-langkah berikut ini.

Langkah Pertama, buatlah sebuah project baru dengan nama “pendeteksi-plat-nomer-kendaraan”.

Membuat Project “pendeteksi-plat-nomer-kendaraan”

Ingat, jangan lupa untuk menambahkan library opencv-python versi 4.1.0.25, dan imutils versi 0.5.4 ke dalam project.

Langkah Kedua, setelah project selesai dibuat, unduh gambar melalui tautan ini, dan letakkan di dalam project. Beri nama gambar yang diunduh: contohmobil.jpg.

Gambar Mobil yang berhasil diimport ke dalam project

Langkah Ketiga, buat script baru dengan nama pendeteksiplat.py ke dalam project. Sehingga hasil akhir dari tahap inisiasi ini adalah seperti tangkapan layar di bawah ini.

Hasil akhir tahap inisiasi

Selanjutnya, kita siap untuk membuat program pendeteksi plat nomer kendaraan sederhana.

Memuat Gambar Ke Dalam Program

Tahap berikutnya adalah memuat gambar yang sudah kita import di tahap sebelumnya ke dalam program. Untuk melakukannya ikuti langkah-langkah berikut ini.

Langkah pertama, import library openCV dan imutils ke dalam script. Ketikkan kode berikut ini.

import cv2 as cv
import imutils as im

Langkah kedua, Setelah kita mengimport kedua library tersebut, selanjutnya adalah memuat gambar tersebut. Fungsi yang digunakan adalah fungsi imread().

image = cv.imread('contohmobil.jpg')

Langkah ketiga, Selanjutnya kita coba tampilkan gambar yang sudah dimuat ke dalam program dengan kode berikut ini.

cv.imshow("Gambar Asli", image)

Langkah keempat, tambahkan fungsi waitKey() dan destroyAllWindows() untuk mengatur timing dan tampilan hasil program.

cv.waitKey(0)
cv.destroyAllWindows()

Langkah kelima, kita coba jalankan script yang sudah kita buat, dan kita lihat hasilnya.

Gambar berhasil dimuat ke dalam program

Ya, gambar berhasil dimuat ke dalam program. Namun gambar masih sangat besar bahkan tidak seluruh muka gambar dapat ditampilkan di dalam layar monitor. Oleh karena itu, kita akan melanjutkan ke tahap selanjutnya, yakni mengubah dimensi gambar.

SCRIPT AKHIR TAHAP MEMUAT GAMBAR KE DALAM PROGRAM

import cv2 as cv
import imutils as im

image = cv.imread('contohmobil.jpg')
cv.imshow("Gambar Asli", image)

cv.waitKey(0)
cv.destroyAllWindows()

Mengubah Dimensi Gambar

Pada tahap ini, kita akan mengubah gambar yang sudah dimuat di dalam program sehingga tidak terlalu besar ukurannya ketika ditampilkan di layar monitor. Untuk melakukannya ikut langkah-langkah berikut.

Langkah pertama, gunakan fungsi resize() dari library imutils. Sisipkan kode berikut ini di antara variabel image dan fungsi imshow().

image = im.resize(image, width=500)

Langkah kedua, ketika program kembali di jalankan, maka tampilannya akan berubah menjadi seperti tangkapan layar di bawah ini.

Muka gambar berhasil ditampilkan seluruhnya

SCRIPT AKHIR TAHAP MENGUBAH DIMENSI GAMBAR

import cv2 as cv
import imutils as im

image = cv.imread('contohmobil.jpg')
image = im.resize(image, width=500)
cv.imshow("Gambar Asli", image)

cv.waitKey(0)
cv.destroyAllWindows()

Setelah kita berhasil melakukan resize gambar, kini saatnya kita mengolah gambar tersebut sehingga dapat terdeteksi plat nomernya.

Mengubah Color Space ke Grayscale

Pada tahap ini, kita akan mengubah color space gambar ke mode grayscale. Tujuannya adalah, supaya proses analisis dapat lebih presisi karena tidak terganggu oleh warna yang bermacam – macam. Untuk itu ikuti langkah – langkah berikut ini untuk mengubah color space menjadi grayscale.

Langkah pertama, tambahkan fungsi cvtColor() dengan flags COLOR_BGR2GRAY yang disimpan pada sebuah variabel. Tambahkan kode berikut ini.

gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)

Langkah kedua, tambahkan fungsi imshow() untuk menampilkan hasil dari ubahan color space tersebut. Gunakan kode berikut ini.

cv.imshow("Gambar Grayscale", gray)

Langkah ketiga, jalankan script, maka akan tampil dua jendela yang menampilkan gambar asli dan gambar gray scale seperti tangkapan layar di bawah ini.

Dua jendela: gambar asli dan gambar grayscale

SCRIPT AKHIR TAHAP MENGUBAH COLOR SPACE KE GRAYSCALE

import cv2 as cv
import imutils as im

image = cv.imread('contohmobil.jpg')
image = im.resize(image, width=500)
cv.imshow("Gambar Asli", image)

gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
cv.imshow("Gambar Grayscale", gray)

cv.waitKey(0)
cv.destroyAllWindows()

Menambahkan Efek Blur Bilateral

Seperti pada postingan saya sebelumnya di sini. Efek blur ditambahkan pada gambar yang sudah selesai diubah color space nya menjadi grayscale. Hal ini dilakukan untuk meminimalisir kontur yang akan di baca pada tahap sebelumnya. Efek blur yang kita tambahkan pada program ini adalah efek blur bilateral atau sering disebut juga bilateral filter. Untuk menambahkan efek blur bilateral ini, gunakan kode berikut ini.

blur = cv.bilateralFilter(gray, 11, 17, 17)

Saya tidak akan menjelaskan parameter-parameter yang terdapat pada kode diatas, karena Saya akan menjelaskan tentang jenis-jenis filter blur beserta parameternya pada postingan yang lain. Setelah menambahkan fungsi bilateral di atas, kita tambahkan fungsi imshow() untuk menampilkan hasil dari penambahan efek filter bilateral tersebut.

cv.imshow("Bilateral Filter", blur)

Sehingga ketika kita jalankan script yang sudah ditambahkan kedua kode di atas, akan menghasilkan tampilan seperti tangkapan layar di bawah ini.

Hasil penambahan filter bilateral pada gambar yang sudah diubah colorspace-nya

SCRIPT AKHIR TAHAP MENAMBAHKAN EFEK BLUR BILATERAL

import cv2 as cv
import imutils as im

image = cv.imread('contohmobil.jpg')
image = im.resize(image, width=500)
cv.imshow("Gambar Asli", image)

gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
cv.imshow("Gambar Grayscale", gray)

blur = cv.bilateralFilter(gray, 11, 17, 17)
cv.imshow("Bilateral Filter", blur)

cv.waitKey(0)
cv.destroyAllWindows()

Mencari Garis Tepi Dari Obyek Pada Gambar

Tahap selanjutnya adalah kita mencoba mencari garis tepi dari obyek-obyek yang terdapat pada gambar. Untuk melakukan hal ini, kita menggunakan fungsi edge detection yakni fungsi canny(). Untuk melakukannya, ikuti langkah-langkah berikut ini.

Tahap pertama, tambahkan fungsi canny() pada gambar yang sudah diberikan efek filter bilateral pada tahap sebelumnya. Untuk itu gunakan kode berikut ini.

edgeDet = cv.Canny(blur, 170, 200)

Tahap kedua, seperti pada tahapan-tahapan sebelumnya kita coba tampilkan hasil dari deteksi tepi dari obyek-obyek yang ada di dalam gambar dengan menggunakan fungsi imshow().

cv.imshow("Canny Result", edgeDet)

Selanjutnya, kita coba jalankan program yang sudah kita tambahkan dua kode di atas.

Hasil gambar setelah tepi-tepi obyek dideteksi

Nah, dari tangkapan layar di atas, kini Anda dapat melihat plat nomer kendaraan mulai terlihat. Kini saaatnya kita mencoba mencari kontur dari plat nomer yang sudah mulai terdeteksi tersebut dan menggambarkan sesuatu di atasnya.

SCRIPT AKHIR TAHAP MENCARI GARIS TEPI DARI OBYEK PADA GAMBAR

import cv2 as cv
import imutils as im

image = cv.imread('contohmobil.jpg')
image = im.resize(image, width=500)
cv.imshow("Gambar Asli", image)

gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
cv.imshow("Gambar Grayscale", gray)

blur = cv.bilateralFilter(gray, 11, 17, 17)
cv.imshow("Bilateral Filter", blur)

edgeDet = cv.Canny(blur, 170, 200)
cv.imshow("Deteksi Tepi", edgeDet)

cv.waitKey(0)
cv.destroyAllWindows()

Mencari Kontur Dan Menggambarnya

Tahap berikutnya adalah mencari kontur dan menggambar sesuatu di atasnya. Seperti halnya postingan saya di sini, kita juga akan mencari kontur obyek yang dicari dan menggambarnya. Obyek yang akan kita cari adalah obyek berbentuk segi empat dengan berbagai bentuk / ukuran. Ukuran segi empat ini juga khas yakni simetris, sehingga kita bisa menyempitkan proses pencarian kontur ke segiempat yang simetris (meskipun dalam perspektif yang berbeda).

Untuk melakukan hal ini, pertama kita akan menggunakan fungsi findContours(). Dari fungsi ini kita bisa memperoleh kontur yang akan kita cari. Oleh karena itu, kita tambahkan kode berikut terlebih dahulu.

(cnts, _) = cv.findContours(edgeDet.copy(), cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)

Setelah kita memperoleh data dari kontur yang kita cari, sekarang kita coba urutkan data tersebut dengan menggunakan fungsi sorted(). Tambahkan kode berikut ini.

cnts = sorted(cnts, key = cv.contourArea, reverse = True)[:30]

Nah, setelah sampai di sini, saatnya kita menggambar area kontur yang sudah diseleksi. Namun kita tahu, bahwa menggambar rectangle bukanlah sesuatu hal yang mudah. Oleh karena itu, kita gunakan kode berikut ini untuk menggambar rectangle pada area kontur yang sudah diseleksi.

NumberPlateCnt = None

count = 0
for c in cnts:
        peri = cv.arcLength(c, True)
        approx = cv.approxPolyDP(c, 0.02 * peri, True)
        if len(approx) == 4:
            NumberPlateCnt = approx
            break

cv.drawContours(image, [NumberPlateCnt], -1, (0,255,0), 3)

Terakhir kita tambahkan fungsi imshow() untuk melihat hasilnya.

cv.imshow("Plat Nomer Yang Terdeteksi", image)

Saat kita jalankan program kita, maka akan menampilkan hasil seperti tangkapan layar di bawah ini.

Hasil dari menggambar rectangle pada kontur yang terdeteksi

Cukup menarik bukan? sekarang kita beralih ke tahap terakhir, yakni tahap menyimpan hasil analisis

SCRIPT AKHIR TAHAP MENCARI MENCARI KONTUR DAN MENGGAMBARNYA

import cv2 as cv
import imutils as im

image = cv.imread('contohmobil.jpg')
image = im.resize(image, width=500)
cv.imshow("Gambar Asli", image)

gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
cv.imshow("Gambar Grayscale", gray)

blur = cv.bilateralFilter(gray, 11, 17, 17)
cv.imshow("Bilateral Filter", blur)

edgeDet = cv.Canny(blur, 170, 200)
cv.imshow("Deteksi Tepi", edgeDet)

(cnts, _) = cv.findContours(edgeDet.copy(), cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnts = sorted(cnts, key = cv.contourArea, reverse = True)[:30]

NumberPlateCnt = None

count = 0
for c in cnts:
        peri = cv.arcLength(c, True)
        approx = cv.approxPolyDP(c, 0.02 * peri, True)
        if len(approx) == 4:
            NumberPlateCnt = approx
            break

cv.drawContours(image, [NumberPlateCnt], -1, (0,255,0), 3)
cv.imshow("Plat Nomer Yang Terdeteksi", image)

cv.waitKey(0)
cv.destroyAllWindows()

Menyimpan Gambar Hasil Deteksi

Pada tahap terakhir ini kita akan menyimpan hasil deteksi. Jadi setelah gambar dimuat ke dalam program, kemudian dilakukan berbagai tahap pengolahan citra, dan dapat memperlihatkan hasil tentu saja hasilnya ini harus dapat kita simpan. Oleh karena itu, kita tambahkan satu fungsi lagi yakni imwrite(). Fungsi ini diletakkan sebelum fungsi imshow() paling terakhir.

cv.imwrite('hasildeteksi.jpg', image)

Selanjutnya, setelah kita jalankan program, maka gambar hasil deteksi akan otomatis tersimpan di dalam direktori tempat kita menyimpan script untuk mendeteksi plat nomer kendaraan ini.

Gambar hasil deteksi tersimpan dengan nama hasildeteksi.jpg

Nah, sampai di sini sebenarnya program sudah selesai kita buat, Namun Saya ingin menambahkan satu tahapan paling terakhir, yakni merampingkan script program.

SCRIPT AKHIR TAHAP MENYIMPAN GAMBAR HASIL DETEKSI

import cv2 as cv
import imutils as im

image = cv.imread('contohmobil.jpg')
image = im.resize(image, width=500)
cv.imshow("Gambar Asli", image)

gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
cv.imshow("Gambar Grayscale", gray)

blur = cv.bilateralFilter(gray, 11, 17, 17)
cv.imshow("Bilateral Filter", blur)

edgeDet = cv.Canny(blur, 170, 200)
cv.imshow("Deteksi Tepi", edgeDet)

(cnts, _) = cv.findContours(edgeDet.copy(), cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnts = sorted(cnts, key = cv.contourArea, reverse = True)[:30]

NumberPlateCnt = None

count = 0
for c in cnts:
        peri = cv.arcLength(c, True)
        approx = cv.approxPolyDP(c, 0.02 * peri, True)
        if len(approx) == 4:
            NumberPlateCnt = approx
            break

cv.drawContours(image, [NumberPlateCnt], -1, (0,255,0), 3)
cv.imwrite('hasildeteksi.jpg', image)
cv.imshow("Plat Nomer Yang Terdeteksi", image)

cv.waitKey(0)
cv.destroyAllWindows()

Merampingkan Script Program

Sebenarnya, merampingkan script program juga tidak tepat juga. Karena pada tahapan ini, kita hanya akan menghapus seluruh fungsi imshow() dan hanya meninggalkan fungsi imshow() paling akhir saja, yakni fungsi untuk menampilkan gambar hasil deteksi. Sehingga script hasil akhir setelah kita rampingkan adalah sebagai berikut.

import cv2 as cv
import imutils as im

image = cv.imread('contohmobil.jpg')
image = im.resize(image, width=500)

gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)

blur = cv.bilateralFilter(gray, 11, 17, 17)

edgeDet = cv.Canny(blur, 170, 200)

(cnts, _) = cv.findContours(edgeDet.copy(), cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
cnts = sorted(cnts, key = cv.contourArea, reverse = True)[:30]

NumberPlateCnt = None

count = 0
for c in cnts:
        peri = cv.arcLength(c, True)
        approx = cv.approxPolyDP(c, 0.02 * peri, True)
        if len(approx) == 4:
            NumberPlateCnt = approx
            break

cv.drawContours(image, [NumberPlateCnt], -1, (0,255,0), 3)
cv.imwrite('hasildeteksi.jpg', image)
cv.imshow("Plat Nomer Yang Terdeteksi", image)

cv.waitKey(0)
cv.destroyAllWindows()

Sehingga, ketika kita jalankan program, program hanya akan menampilkan gambar hasil deteksi saja.

Program hanya menampilkan hasil deteksi saja.

Baik, sampai di sini, project saya anggap benar-benar selesai.. ^_^. Tunggu postingan saya selanjutnya yang akan lebih membahas lebih dalam tentang topik ini. Yakni membaca huruf dan angka yang terdapat pada plat nomer kendaraan yang berhasil dideteksi.


Demikian postingan saya tentang Membuat Deteksi Plat Nomer Kendaraan Sederhana Dengan OpenCV (Python). Semoga postingan ini bermanfaat bagi Anda yang ingin belajar tentang OpenCV. Apabila Anda masih menemukan kendala dalam membuat program ini, Anda dapat meninggalkan pertanyan di kolom komentar. Jika Anda ingin mencuplik sebagian teks dari artikel ini, Saya mohon jangan lupa sertakan sumber dan penulisnya.

Terima Kasih…. ^_^


DOWNLOAD

Please follow and like us:
Advertisements

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *