Detecting Data Quality Issues by Identifying Outliers

March 2020 | Dios Kurniawan

In my previous post on Data Quality Framework, I discussed about the concept of DQ (data quality) Test Point. The idea is to detect data quality issues by probing the data. In these DQ Test Points, DQ metrics are extracted, calculated and then compared against a baseline. 

To bolster the DQ metrics, a method called outlier detection is added to the DQ Test Points. This is a pretty simple check to see abnormalities in the data by looking for outliers. Outliers are, as you must have guessed, values which are very different from most of the population. For example, if most of Telkomsel subscribers make 5-6 voice calls per day, then those who place 100 voice calls per day are clear outliers. Outliers can be legitimate as in the previous example, but they can also be invalid or unwanted data. For example a person whose age is 250 years is certainly an invalid data, something that we want to erase from our datasets.

Most outliers are hidden inside the dataset. There are almost always outliers, but when we see a lot of them in our tables, or a sudden change in the number of outliers, we can see it as a sign of a potential data quality issue. It is important to remove outliers because they generally have negative effect on analysis and training a predictive model.

To identify outliers, one of the most common methods is to calculate the distribution of the data using Inter-quartile Range (IQR). In the simplest words, IQR is the area of the data which represents the “middle” values where half (50%) of the data belongs. Anything that falls beyond a certain distance from the IQR will be marked as outliers.  According to “Tukey’s Rule” (named after John Tukey, an American mathematician), the distance is 1.5 x IQR (see diagram below).

To perform the computation, first we will have to sort all rows in the dataset from the lowest to the highest value, then divide the data into four equal parts (hence the name “quartile”). The boundary for the first 25% of the data is called Q1 and the last 25% is called Q3. To get the IQR, subtract Q3 from Q1. After that, find the “min” and “max” limits by calculating 1.5 x IQR from Q1 and Q3, respectively. Once you have these “min” and “max” numbers, you can start counting the outliers which values are less than “min” and more than “max”. There you get your outliers.

Finding IQR like above is a computationally heavy process, especially when involving large number of rows. Luckily, our friend Spark has provided us with the tool for this. Using approxQuantile() function which allows us to compute IQR without going through the whole dataset, and this can be done quite easily. You may want to see the snippet of the PySpark code as shown below:

To give an example of how it works, this script was run on one of the tables in the ABT schema, with around 5 million records. Outliers are gathered from all numerical columns. The script produced the following statistics:

As we can see, the percentage of outliers is generally small. Anything under 2% will be considered normal. However, in the above example, there are some particular columns which have large percentage of outliers, even up to 15%. This is something worth investigating as this can lead to potential quality problems. 

What’s Next?

At the moment the IT Data Quality team is working on putting the outliers count in our BI DQ Dashboard (see below) alongside with other DQ metrics. By comparing the outliers statistics with historical data, we may be able to detect issues before they present a problem in the consumers side.

The method mentioned above is far from perfect. It only captures outliers in one dimension, which is called univariate outliers. To get outliers which lie in two or more dimensions, called multivariate outliers, different methods employing ML techniques must be prepared. Stay tuned for more posts on this matter. Our journey to improve data quality in BI keeps going on!

Personal Data Protection

February 2020 | Dios Kurniawan

Indonesian lawmakers will soon ratify the new law on personal data protection, called Undang-undang Perlindungan Data Pribadi (UU PDP). At the heart of this new law is a stringent safeguard measure on privacy rights. Personal data protection is part of human rights, and the law carries heavy criminal penalties for fraud and misuse of personal data. There is a criminal sanction of 7 years in prison or a fine of 70 billion Rupiah (!) for anyone involved in unlawful use of personal data.

If you run a business and you regularly collect customer’s data, remember that the personal data belongs to your customers. The ownership remains with your customers even though the data sits on your system’s hard drive. In order for you to process the data, the customers must give explicit consent. Without it, you are breaking the law. 

So what constitutes a personal data? According the latest draft of the law, there are two types of personal data:

  1. General Personal Data, that is, data which could easily identify who someone is. This includes full name, gender, nationality, passport number and NIK (national ID number). Birth date, home address, work address, photographs also belong to this category.
  2. Specific Personal Data, that is, sensitive data which could harm someone if it falls into the wrong hands. This category of personal data requires different kind of protection. This includes medical information, biometrics, genetics, political views, financial data, religion and family information. Credit card number, bank account information, mother’s name, geolocation data are also categorized as specific personal data.

What about phone numbers and e-mail addresses? There can be multiple interpretation of the law with regard to this, but it is safe to consider that phone numbers and e-mails are not categorized as personal data. They fall into the category of pseudonym data, which is a type of data that requires additional data before it can be used to identify someone. Although not explicitly mandated by law, to protect the customers, phone numbers and email addresses must also be protected.

For us who work in the field of big data analytics, what are the do’s and don’ts when it comes to handling customer’s data? Just remember that by law, we are personally responsible for our actions. Here is a few guideline for you:

  1. Treat customer data with respect. The data is not yours.
  2. Do not touch specific/sensitive personal data unless you have a very strong reason to do so. Avoid making analysis based on this category of data.
  3. Protect personal data with encryption in the physical level.
  4. Each time you need to deliver data, a report, or to grant table access to your users, check to make sure there is no personal data within. If you are transferring data to an external party, be certain you have the legal clearance before doing so. Ask for written evidence. 
  5. Never reveal customer’s personal data to friends, relatives or family members. Never.
  6. Destroy customer’s personal data when they are no longer our customers (that is, they have churned).

In the age of big data, those who own data hold the power. The famous quote “along with great power comes great responsibility” perfectly describes the situation.

Pengenalan Gambar

Januari 2020 | Dios Kurniawan

**NOTE: This article is part of my upcoming book and is still written in Bahasa Indonesia. I will provide the English version as soon as possible **

Di jaman sekarang, gambar dan video digital ada di mana-mana. Ponsel yang ada di tangan hampir setiap orang modern saat ini bisa dengan mudahnya bisa mengambil foto dan sekejap mengirimkannya melalui jaringan nirkabel ke mana pun di dunia, termasuk melalui media sosial. Begitu juga dengan video digital yang saat ini bisa dibuat oleh siapapun bahkan oleh anak-anak, diunggah dan diunduh dengan bebas di platform video seperti Youtube. Kamera CCTV juga dengan rajin 24 jam sehari merekam aktivitas orang-orang di hampir semua tempat publik. Dunia telah dibanjiri oleh gambar digital.

Kita tahu bahwa perangkat lunak komputer pada umumnya tidak akan kesulitan untuk membuat index pencarian dokumen teks dalam jumlah yang besar sekalipun, namun untuk gambar digital tidak demikian. Agar dapat membuat index untuk pencarian gambar, perangkat lunak harus dapat terlebih dahulu “melihat” isi dokumen gambar dan menemukan obyek-obyek di dalamnya.

Bagi manusia, hal ini adalah hal yang bisa dilakukan secara naluriah dengan cepat. Kita tidak perlu waktu lama untuk bisa mengenali benda-benda yang ada dalam sebuah foto, atau wajah-wajah orang di dalam suatu video. Tidak demikian dengan komputer. Salah satu tantangan terberat membuat perangkat lunak komputer yang bisa mengenali obyek di dalam gambar adalah fakta bahwa hingga kini kita masih belum benar-benar bisa memahami (apalagi menirukan) bagaimana sesungguhnya cara kerja manusia mengenali obyek yang diterima oleh indera matanya.

Walaupun kemampuan manusia mengenali obyek masih menjadi misteri, sejak beberapa dekade terakhir berbagai metode pendekatan telah ditemukan dan teknologi untuk pengenalan obyek dalam gambar digital juga masih terus berkembang. Bila kita tertarik untuk menggeluti bidang ini, maka hampir pasti kita harus mempelajari suatu yaitu cabang ilmu yang disebut Computer Vision (CV).  CV adalah upaya manusia membuat perangkat lunak komputer yang bisa mengenali obyek di dalam gambar digital. Ini berbeda dengan metode image processing (pengolahan citra) yang biasa dimanfaatkan untuk memanipulasi gambar digital, namun tidak bertujuan memahami isi gambar.

Sebagai sebuah cabang ilmu, CV banyak beririsan dengan Machine Learning. Beragam algoritma Machine Learning yang sudah kita bahas di buku ini juga tidak sedikit dipergunakan di dalam CV. Serupa dengan metode supervised learning lainnya, CV dalam penggunaan praktis juga memerlukan proses training.

OpenCV

Dalam bab ini, kita akan mencoba membuat penerapan praktis CV untuk mengambil informasi dari gambar diam dan gambar bergerak atau video. Untuk itu kita akan memanfaatkan OpenCV, sebuah library open source yang menyediakan banyak fungsi CV yang menarik untuk dieksplorasi. OpenCV dapat dipakai dengan beragam bahasa pemrograman seperti C++, Java, Perl dan tentu saja bahasa favorit kita yaitu Python.

OpenCV dapat diunduh dengan bebas dari situs https://opencv.org. Instruksi untuk instalasi tersedia di sana. Bila Anda mempergunakan Anaconda, prosesnya instalasinya juga mudah. Caranya dengan menjalankan perintah di bawah ini di sebuah terminal (pastikan Anda tersambung ke internet):

conda create -name ComputerVision python=3.7
conda install -c menpo opencv
source activate ComputerVision

Perhatikan bahwa contoh di atas mempergunakan Python versi 3.7, gantilah dengan versi Python yang terpasang di komputer Anda apabila berbeda.

import cv2

Setelah itu kita bisa memakai OpenCV di program python kita dengan mengimpornya:

Bila tidak ada pesan error, artinya Anda sudah siap untuk mengikuti pembahasan selanjutnya, yaitu pendeteksian obyek dalam gambar digital yang akan kita coba bangun sebagai sebuah contoh kasus.

Pendeteksian Wajah

Anda pasti pernah mengalami ketika Anda mengunggah foto di platform media sosial misalnya Facebook, secara otomatis Facebook akan membuat tanda gambar kotak di wajah-wajah orang yang muncul di foto tersebut dan menawarkan kepada Anda untuk men-tag-nya sebagai teman-teman Anda. Ini adalah contoh penerapan nyata Machine Learning untuk facial detection (pendeteksian wajah). Lebih jauh lagi, Facebook juga menerapkan facial recognition (pengenalan wajah) sehingga bisa menampilkan nama-nama teman-teman Anda yang ada di dalam sebuah foto.

Di bab ini kita akan mencoba untuk membuat sebuah program untuk memecahkan tantangan yang pertama yaitu pendeteksian wajah. Sebuah file gambar (dalam format JPEG atau PNG) akan dibaca oleh program dan kemudian semua wajah yang muncul di gambar akan ditandai dengan simbol kotak. Untuk program kedua kita akan mempergunakan video sebagai input program.

Program kita bertujuan melakukan pendeteksian – bukan pengenalan – sehingga kita belum mempedulikan siapa pemilik wajah yang ada di dalam gambar. Proses deteksi akan menghasilkan lokasi koordinat tempat wajah (atau wajah-wajah) yang berhasil dideteksi. Seterusnya terserah kita untuk melakukan proses lebih lanjut, misalnya untuk dilakukan pengenalan siapa individu yang wajahnya muncul di gambar.

Ada beberapa metode untuk pengenalan obyek di dalam gambar, salah satunya adalah algoritma pengenalan obyek berbasis Haar Cascade (diambil dari nama ahli matematika dari Hongaria, Alfred Haar). Algoritma Haar Cascade akan dipergunakan dalam contoh program kita sebagai classifier, yaitu suatu bentuk khusus dari predictive model untuk klasifikasi. Tidak hanya untuk wajah, obyek yang dicoba dikenali bisa berupa anggota tubuh lain (misal hidung, mata, mulut) atau benda apapun asalkan kita bisa menyediakan training dataset-nya.

Algoritma ini ditemukan oleh dua orang periset bernama Paul Viola dan Michael Jones yang dituangkan dalam paper ilmiah mereka di tahun 2001, sehingga seringkali algoritma ini disebut juga dengan algoritma Viola-Jones. Mereka memberikan ide yang bertujuan untuk menghasilkan metode pendeteksian obyek yang cepat sehingga cocok untuk penggunaan secara real-time. Algoritma ini bisa dipakai untuk mengenali beragam obyek, namun face detection memang merupakan fokus utamanya.

Pembahasan detail mengenai teori dan cara kerja algoritma pendeteksian obyek berbasis Haar Cascade berada di luar lingkup artikel ini, namun secara singkat perlu dipahami bahwa algoritma memerlukan training dataset berupa sampel positif (gambar obyek yang ingin dideteksi, dalam kasus kita adalah wajah orang) dan sampel negatif (tidak berisi gambar obyek yang ingin dideteksi).

OpenCV menyediakan fasilitas untuk memuat file dalam format JPG atau PNG beserta label lokasi obyek di dalam gambar untuk dijadikan training dataset. Agar algoritma dapat bekerja efektif, sampel positif dan negatif untuk training dataset harus tersedia dalam jumlah yang besar, ratusan bahkan ribuan gambar. Adapun begitu, untuk keperluan pendeteksian wajah, kabar baiknya adalah kita tidak harus membuat training dataset sendiri, karena OpenCV sudah menyediakan training dataset yang bisa langsung dipakai. Kita akan bahas ini kemudian.

Bagaimana caranya agar komputer bisa mengenali gambar? Kita tentu sudah memahami bahwa gambar digital sebenarnya adalah sekumpulan titik yang disebut pixel. Satu file gambar digital bisa memiliki jutaan pixel yang disusun dalam baris dan kolom layaknya sebuah tabel. Sebuah gambar yang dihasilkan oleh sebuah kamera digital dengan resolusi standar 1920 x 1080 memiliki lebih dari dua juta pixel. Gambar dengan resolusi yang sangat tinggi bisa memiliki sampai 30 juta pixel.

Karena komputer hanya bisa bekerja dengan angka, maka setiap pixel harus diwakili oleh sebuah angka. Angka ini menunjukkan intensitas cahaya yang biasanya berada dalam jangkauan nol hingga 255, dengan angka nol berarti gelap total atau hitam. Untuk gambar berwarna, ada tiga angka seperti ini untuk setiap pixel, masing-masing mewakili komponen warna merah, hijau dan biru (sering disebut RGB, red-green-blue). Adapun begitu, algoritma pengenalan obyek tidak memerlukan informasi warna, sehingga kita kesampingkan dulu hal ini. Gambar berwarna justru harus terlebih dahulu diubah menjadi gambar tanpa warna (sering disebut grayscale).

Tentunya tidak efisien bila jutaan pixel harus diolah secara satu per satu. Itu sebabnya cara kerja algoritma pengenalan obyek adalah dengan mengolah sekumpulan pixel yang membentuk elemen gambar seperti garis, sudut-sudut, atau bentuk-bentuk lain. Inilah yang dijadikan feature bagi proses training.

Bila kita perhatikan sebuah gambar wajah, wilayah di sekitar mata nampak lebih gelap dibanding wilayah sekitar pipi. Begitu juga batang hidung nampak lebih cerah dibandingkan wilayah sekitar mata. Angka-angka intensitas cahaya dalam gabungan beberapa pixel bila dikumpulkan dengan ciri lainnya bisa dipakai sebagai feature untuk pengenalan wajah.

Memproses File Gambar

Di bagian ini kita akan membuat program demonstrasi deteksi wajah dengan masukan sebuah file gambar dalam format JPEG atau PNG. Langkah pertama adalah impor modul OpenCV (versi yang digunakan buku ini adalah versi 2.4).

Selanjutnya kita buka sebuah file JPEG atau PNG dengan perintah imread() dari OpenCV. Anda bisa mempergunakan gambar apa saja yang berisi setidaknya satu gambar wajah seseorang. Untuk contoh kali ini, kita pergunakan foto almarhum Presiden Soeharto yang diperoleh dari Wikipedia. Foto ini harus diubah menjadi grayscale dengan fungsi cvtColor() karena seperti sudah disinggung sebelumnya, algoritma pengenalan obyek tidak memerlukan informasi warna:

import cv2 as cv
foto = cv.imread('presiden1.jpg')
foto_gray = cv.cvtColor(foto, cv.COLOR_BGR2GRAY)

Sebelum melangkah lebih jauh, kita uji terlebih dahulu dengan menampilkan foto grayscale ini ke layar. Ini dilakukan dengan perintah imshow(). Fungsi waitKey() perlu ditambahkan untuk membuat program menunggu pengguna komputer menekan sembarang tombol keyboard agar program tidak langsung berakhir. Fungsi destroyAllWindows() dipanggil untuk mengakhiri program dan membersihkan layar dari semua window di layar.

cv.imshow("Foto", foto_gray)
cv.waitKey(0)
cv.destroyAllWindows()

Setelah foto siap, langkah berikutnya adalah kita aktifkan class pendeteksi obyek, yang di dalam OpenCV diberi nama CascadeClassifier. Seperti kita ketahui, pendeteksian wajah memerlukan training dataset berupa sebuah file XML. Untungnya, di dalam paket OpenCV telah tersedia training dataset standar yang berisikan ribuan sampel-sampel wajah yang bisa kita pakai. Ini cukup untuk eksperimen pertama kita di sini, adapun demikian training dataset ini tidak sepenuhnya lengkap dan tidak selalu berhasil mendeteksi wajah orang misalnya dari ras atau suku tertentu yang belum ada sampelnya. Dalam kasus seperti itu, kita harus membuat training dataset sendiri. Ini akan kita bicarakan di bagian lain artikel ini.

Training dataset standar yang disediakan OpenCV berada di file bernama haarcascade_frontalface_alt.xml. Lokasi file XML ini ada di folder /data/haarcascades/ di tempat Anda memasang OpenCV di komputer Anda (bila tidak bisa ditemukan, file XML ini juga bisa diunduh dari situs OpenCV). Perintah berikut akan memuat CascadeClassifier ke dalam variabel cc_wajah dengan menyertakan file XML yang disebut di atas:

cc_wajah = cv.CascadeClassifier('/data/haarcascade_frontalface_alt.xml')
if cc_wajah.empty():
    raise IOError('File XML tidak ditemukan!')

Pastikan bahwa file XML bisa sudah ada dan bisa diakses, sebab bilamana tidak, program akan berhenti dengan pesan error file tidak bisa ditemukan. Pada titik ini kita sudah siap untuk menjalankan pendeteksian wajah. Kita panggil method/fungsi detectMultiScale dengan memasukkan foto grayscale yang sudah kita persiapkan sebelumnya:

hasil = cc_wajah.detectMultiScale(foto_gray, scaleFactor=1.1, minNeighbor=5)

Apa arti parameter scaleFactor=1.1 di atas? Ini adalah konstanta yang bila kita ubah, apabila semakin tinggi angkanya maka proses deteksi akan lebih cepat namun demikian melemahkan kehandalannya (semakin kecil kemungkinan deteksi berhasil). Secara umum, Anda bisa bereksperimen dengan mengubah-ubah angka ini dari 1,0 hingga 3,0 dan perhatikan efeknya terhadap akurasi dan kecepatan proses deteksi.

Parameter kedua yaitu minNeighbor=5 juga menentukan akurasi deteksi. Semakin rendah nilai ini, semakin besar kemungkinan obyek yang bukan wajah dideteksi sebagai wajah (false positive yang tinggi), sebaliknya bila nilainya tinggi, semakin besar kemungkinan ada wajah lolos dari deteksi (false negative yang tinggi). Anda bisa bereksperimen dengan angka ini untuk mendapatkan akurasi yang sesuai.

Setelah perintah di atas dijalankan, akan terbentuk sebuah List (variabel hasil) yang berisi kumpulan wajah yang berhasil terdeteksi di dalam gambar. Bila program tidak berhasil mendeteksi adanya waja, variabel hasil akan kosong. Mari kita lihat isinya, apakah kosong atau berisi nilai:

print(hasil)
[[137 106 177 177]]

Terlihat bahwa proses deteksi wajah telah berhasil dan tidak kosong. Karena variabel hasil adalah sebuah List, dari sini kita bisa menghitung ada berapa orang yang wajahnya terdeteksi di dalam gambar dengan menampilkan jumlah elemen dalam List:

jumlah_wajah = len(hasil)
print("Terdeteksi", jumlah_wajah, "orang di dalam gambar")

Untuk setiap obyek (wajah) yang terdeteksi, akan diwakili oleh empat angka (posisi sumbu x, posisi sumbu y, lebar dan tinggi) yang membentuk wilayah berupa persegi panjang di dalam gambar. Keempat angka ini bisa kita ambil dari List sebagai variabel x,y, w dan h, kemudian kita visualkan berupa persegi panjang dengan bantuan fungsi rectangle() yang disediakan OpenCV.

x =(hasil[0][0])
y =(hasil[0][1])
w =(hasil[0][2])
h =(hasil[0][3])
cv.rectangle(foto, (x,y), (x+w,y+h), color=(0,255,0), thickness=6)

Hasil deteksi wajah selain ditampilkan ke layar dengan fungsi imshow() juga disimpan ke sebuah file dengan fungsi imwrite(). Agar program tidak langsung berakhir, fungsi waitKey() dipergunakan untuk menunggu pengguna komputer menekan sembarang tombol di keyboard sebelum program berlanjut ke perintah selanjutnya. Fungsi destroyAllWindows() membersihkan memori layar dengan menutup semua window. Bila program berikut dijalankan, hasilnya akan muncul di layar:

cv.imshow("Foto", foto)
cv.imwrite('hasil_deteksi.jpg', foto)
cv.waitKey(0)
cv.destroyAllWindows()

Program kita sukses mendeteksi wajah Presiden Soeharto. Perhatikan bahwa parameter thickness=6 menentukan tebal garis (bila Anda rasa garis kotak terlalu tebal, angka ini bisa dikurangi). Parameter color=(0,255,0) menghasilkan kotak berwarna hijau karena ketiga angka tersebut mewakili nilai warna RGB dengan R (red) = 0, G (green) = 255 dan B (blue) = 0. Anda bisa ubah warna ini misalnya menjadi warna merah dengan membuat R=255, G=0 dan B=0.

Contoh gambar di atas hanya berisikan wajah satu orang saja. Bagaimana bila ada lebih dari satu orang di dalam gambar? Seperti sudah dijelaskan sebelumnya, variabel hasil adalah sebuah List yang berisi seluruh wajah yang berhasil dideteksi. Agar lebih jelas, kita ganti file gambar dengan gambar berisi lebih dari satu orang. Kita ambil foto lain sebagai contoh yang berisikan tokoh-tokoh penting (foto dapat diunduh dari lokasi ini).

Sebelum kita lanjutkan, program harus diubah dengan mempergunakan for-loop untuk mengakses semua informasi wajah dari List yang dihasilkan oleh proses deteksi, kemudian masing-masing ditandai dengan gambar kotak:

import cv2 as cv
cc_wajah = cv.CascadeClassifier('haarcascade_frontalface_alt.xml')
if cc_wajah.empty():
   raise IOError('File XML tidak bisa ditemukan!')
foto = cv.imread('tokoh1.jpg')
foto_gray = cv.cvtColor(foto, cv.COLOR_BGR2GRAY)
hasil = cc_wajah.detectMultiScale(foto_gray, scaleFactor=1.2, minNeighbors=5)
print("Terdeteksi ", len(face_rects), " orang di dalam gambar:")
for (x,y,w,h) in hasil:
    cv.rectangle(foto, (x,y), (x+w,y+h), color=(0,255,0), thickness=5)
cv.imshow('Deteksi Wajah', foto)
cv.imwrite('hasil_deteksi.jpg', foto)
cv.waitKey(0)
cv.destroyAllWindows()

Video

Agar lebih menarik lagi, kita akan mencoba membuat program yang melakukan proses deteksi wajah dengan masukan berupa video, sehingga proses deteksi berjalan terus tanpa henti. Untuk mudahnya, kita akan mempergunakan webcam yang hampir selalu ada di setiap laptop. OpenCV menyediakan class untuk menangkap video yaitu VideoCapture(). Webcam diwakili oleh angka nol sebagai parameter saat mengaktifkan kelas ini.

Secara garis besar tidak ada perubahan pada program Python yang sudah kita buat, hanya kita ganti masukan gambar dari pembacaan file menjadi pembacaan video yang dilaksanakan oleh fungsi read() di dalam suatu while-loopyang menangkap satu frame di setiap iterasi dan diulang terus. Agar program dapat kita hentikan, user bisa menekan tombol ESC (kode 27) untuk membuat program keluar dari while-loop tersebut.

Satu catatan penting adalah untuk menulis dan menjalankan program ini disarankan tidak mempergunakan Jupyter Notebook, namun mempergunakan Python interpreter seperti IPython karena fungsi video sulit ditampilkan di Jupyter Notebook.

import cv2 as cv
cc_wajah = cv.CascadeClassifier('haarcascade_frontalface_alt.xml')
if cc_wajah.empty():
    raise IOError('File XML tidak bisa ditemukan!')
webcam1 = cv.VideoCapture(0)
while True:
    ret, frame = webcam1.read()
    frame = cv.resize(frame, None, fx=0.8, fy=0.8, interpolation=cv.INTER_AREA)
    frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    hasil = cc_wajah.detectMultiScale(frame_gray, 1.1, 5)
    for (x,y,w,h) in hasil:
        cv.rectangle(frame, (x,y), (x+w,y+h), (0,255,0), 5)
    cv.imshow('Face Detection', frame)
    tombol = cv.waitKey(1)
    if tombol == 27:
        break
webcam1.release()
cv.destroyAllWindows()

Perhatikan bahwa kita menambahkan fungsi resize() dengan tujuan memperkecil ukuran gambar video menjadi 80% saja. Anda bisa ubah nilai ini sesuai kebutuhan.

Anda juga bisa mengganti webcam dengan file video, atau bisa juga dengan kamera IP / CCTV sebagai sumber video. Syaratnya, kamera tersebut mendukung protokol streaming RSTP atau HTTP. Dalam buku ini penulis mempergunakan kamer IP merk “TP-Link” yang bisa diakses melalui HTTP. Untuk itu kita ganti panggilan ke VideoCapture() dengan alamat IP dari kamera yang ingin kita akses, seperti contoh di bawah ini:

webcam1 = cv.VideoCapture('http://admin:pwd@192.168.1.112/?action=stream')

Melatih Pengenalan Obyek

Tidak terbatas pada pendeteksian wajah, kita bisa melatih CascadeClassifier dengan obyek-obyek lain, misalnya logo, mobil, hewan dan sebagainya. Syaratnya, kita harus menyiapkan training dataset berupa sebanyak-banyaknya sampel positif berupa gambar obyek yang ingin kita deteksi dan juga sebanyak-banyaknya sampel negatif.

Untuk keperluan training, OpenCV menyediakan dua program yaitu opencv_createsamples dan opencv_traincascade. Keduanya ada di folder tempat OpenCV dipasang di disk Langkah pertama dalam proses training adalah memanfaatkan program opencv_createsamples untuk menghasilkan sampel positif berbentuk file berekstensi .vec yang kemudian dipergunakan untuk training oleh program opencv_traincascade.

Sampel positif yang diperlukan harus mencakup berbagai variasi posisi, sudut kemiringan, atau variasi latar belakang. Ini diperlukan untuk memperkuat kemungkinan pendeteksian berhasil.

Kita ingat bahwa algoritma berbasis Haar Cascade memanfaatkan perbedaan intensitas cahaya di dalam gambar sebagai dasar penentuan feature. Oleh karena itu gambar sampel obyek yang kita persiapkan haruslah obyek yang memang memiliki banyak sudut atau lekukan yang kontras perbedaan intensitas terang-gelapnya. Gambar yang sedikit garis kontrasnya, terlalu terang atau terlalu gelap akan kurang baik dijadikan sampel.

Semua file gambar yang berisi sampel positif harus didaftarkan dalam sebuah file text, yang berisikan semua file JPEG atau PNG beserta informasi lokasi obyek dalam gambar (berupa wilayah kotak persegi empat). File text tersebut isinya berformat sebagai berikut:

Contohnya kita buat sebuah file bernama obyek1.txt yang isinya seperti di bawah:

Penentuan lokasi wilayah kotak memang memerlukan proses manual, biasanya dengan perangkat pengolah gambar. Di sinilah diperlukan tenaga dan waktu yang tidak sedikit.

Bila sampel sudah siap, program opencv_createsamples bisa dipanggil dengan menyertakan parameter seperti berikut:

opencv_createsamples -info obyek1.txt -w 50 -h 50 -vec obyek1.vec

Parameter pertama -info menentukan file yang berisikan informasi sampel positif yang sudah kita buat. Parameter -w dan -h menentukan lebar dan tinggi sampel (dalam pixel). Keluaran program ini adalah file obyek1.vec yang berformat biner, dan akan dipergunakan untuk proses training.

Setelah sampel positif didapatkan, berikutnya kita harus persiapkan juga sampel negatif. Cara yang paling tepat adalah mempergunakan gambar yang persis dengan sampel positif namun obyek yang kita hendak deteksi dihilangkan dari gambar. Bila kita ingin mendeteksi buah apel di meja, maka sampel positifnya adalah foto meja beserta buah apel, sedangkan sampel negatifnya adalah meja tanpa buah apel.

Selain itu ada aturan tidak baku yaitu jumlah sampel negatif harus lebih banyak dari sampel positif, setidaknya dua kali lipat lebih banyak. Bila ada 1.000 sampel positif, maka perlu disediakan setidaknya 2.000 sampel negatif.

Semua file gambar sampel negatif harus diletakkan di satu folder terpisah, dan nama-namanya didaftarkan dalam sebuah file text. Karena tidak ada obyek yang perlu dikenali, maka kita tidak perlu menentukan wilayah persegi empat seperti di sampel positif.

Proses training dilakukan dengan memanggil program opencv_traincascade, dengan parameter seperti berikut ini:

opencv_traincascade -data /home/diosk/samples -vec obyek1.vec -bg neg-filepaths.txt -precalcValBufSize 2048 -precalcIdxBufSize 2048 -numPos 100 -numNeg 1000 -nstages 20 -minhitrate 0.999 -maxfalsealarm 0.5 -w 20 -h 20 -nonsym -baseFormatSave

Parameter -data menentukan folder tempat file sampel berada. Parameter -numPos adalah jumlah sampel positif (dalam contoh ini ada 100) dan -numNeg adalah jumlah sampel negatif (dalam contoh ini ada 1000). Parameter lainnya dapat diubah-ubah dengan eksperimen untuk mendapatkan hasil terbaik. Hasil keluaran program ini adalah sebuah file bernama cascade.XML yang kemudian bisa dipakai untuk program pendeteksian.

Membuat training dataset memang sebuah proses yang tidak ringan, karena umumnya diperlukan ratusan hingga ribuan sampel positif dan negatif. Mengerjakannya dengan tangan satu-per-satu akan memerlukan waktu sangat lama. Ada trik sederhana yaitu mempergunakan kamera video untuk merekam obyek yang sama dari berbagai sudut dan pencahayaan, kemudian dengan perangkat lunak video editor kita ambil frame yang diperlukan. Dengan cara ini, kita bisa mendapat puluhan bahkan ratusan sampel positif dalam sekali pengambilan gambar.

Kesimpulan

Computer Vision adalah cabang ilmu yang masih terus berkembang dan sangat menarik untuk dipelajari. Selain Haar Cascade, ada classifier lain yang cukup sering dipergunakan yaitu Local Binary Pattern (LBP). Berikut adalah perbandingan keunggulan dan kelemahan masing classifier:

Teknologi pendeteksian dan pengenalan wajah meskipun terus berkembang, penerapannya di dunia nyata sering mendapat sorotan tajam karena rentan disalahgunakan. Tidak seperti teknologi pengenalan biometrik lain misalnya sidik jari, pengenalan wajah bisa dilakukan dari jauh tanpa kontak fisik, tanpa seijin orang yang sedang diidentifikasi.

Bayangkan bila wajah Anda ditangkap kamera di jalanan dan perusahaan periklanan tertentu memanfaatkan identitas Anda untuk mengirimkan iklan tanpa ijin Anda. Kepolisian bisa menangkap seorang warga atas tuduhan kriminal berdasarkan pengenalan wajah yang dihasilkan komputer, yang kita tahu belum 100% akurat. Dalam kasus yang lebih ekstrim, Pemerintah China dikabarkan mepergunakan teknologi ini untuk keperluan politis, misalnya mengawasi etnik minoritas tertentu di wilayahnya. Itu sebabnya Microsoft di bulan Juni 2019 menghapus jutaan file wajah dari databasenya yang bernama MS-Celeb atas dasar kurangnya regulasi pemerintah yang mengatur penggunaan teknologi facial recognition.

Computer Vision memang bidang yang menarik untuk didalami, adapun begitu kita harus memanfaatkannya dengan penuh kehati-hatian. Pastikan kita tidak mengganggu privacy orang lain ketika kita memanfaatkan identitasnya untuk keperluan pembuatan model Machine Learning.