Facial Recognition Dengan Raspberry Pi dan OpenCV
OpenCV kaya dengan library untuk Computer Vision dan Machine Learning. Salah satunya adalah pengenalan wajah. Dengan algoritma tertentu, mesin bisa mendeteksi dan mengenali wajah dari gambar atau video yang di sediakan. Untuk website besar sekelas Facebook atau Google mungkin sudah tidak asing lagi dengan pengenalan wajah ini. Google dan Facebook memiliki sistem pendeteksi dan pengenalan wajah yang cukup mumpuni.
Pada tutorial kali ini, kita akan mencoba membuat aplikasi pendeteksi wajah berbasiskan OpenCV. Kita akan membuat dataset dari foto dengan berbagai ekspresi agar sistem pengenalan wajah kita lebih akurat. Input gambar langsung dari kamera Raspberry Pi kita, sehingga kita bisa membuat pengenal wajah secara realtime.
Selanjutnya anda bisa mengembangkan pengenalan wajah ini menjadi lebih luas. Misalnya pendeteksi wajah penjahat, atau pendeteksi wajah sendiri untuk autentikasi. Dan sebetulnya lebih banyak pengembangannya, tergantung imajinasi kita tentunya.
Persiapan
Untuk persiapan, anda harus menyediakan Raspberry Pi 3 Model B+ yang sudah terinstall OpenCV dengan Virtual Environment. Untuk cara install OpenCV silahkan lihat artikel sebelumnya Install OpenCV 4 di Raspberry Pi. Anda juga harus mempersiapkan Pi Cam sebagai input (Lihat artikel Mempersiapkan Kamera Raspberry Pi). Akses SSH dan VNC mungkin di perlukan agar program bisa berjalan dengan baik. Pastikan pengaturan kamera sudah di enable di raspi-config.
1. Install Library yang di perlukan
Kita akan menginstaklan library tambahan untuk Python3 yaitu, dlib, face_recognition, dan imutils. Kita akan bekerja pada environment cv yang sebelumnya sudah kita buat.
workon cv
pip install dlib
pip install face_recognition
pip install imutils
Instalasi dlib lumayan cukup lama tergantung kecepatan internet dan kecepatan SD Card anda.
Apabila pada saat penginstallan face_recognition anda mendapatkan error seperti beriku
ERROR: THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE. If you have updated the package versions, please update the hashes. Otherwise, examine the package contents carefully; someone may have tampered with them.
face-recognition-models>=0.3.0 from https://www.piwheels.org/simple/face-recognition-models/face_recognition_models-0.3.0-py2.py3-none-any.whl#sha256=8d6b0af2e37a17120c3f13107974bc252142a4ffcb4e58eabdfcf26608e52c24 (from face_recognition):
Expected sha256 8d6b0af2e37a17120c3f13107974bc252142a4ffcb4e58eabdfcf26608e52c24
Got b1e8b8472604b9a2f139e51d8413a0c31716d2e5887f07eb8ea84aee894c5890
Coba lakukan penginstalan manual seperti di bawah ini.
wget https://www.piwheels.org/simple/face-recognition-models/face_recognition_models-0.3.0-py2.py3-none-any.whl
pip install face_recognition_models-0.3.0-py2.py3-none-any.whl
pip install --upgrade face_recognition
2.Programming
Untuk programming, kita akan menggunakan Python dengan memanfaatkan library yang sebelumnya sudah di Install. Ada 3 program utama python yang akan di buat. Yaitu face-encoding.py untuk mengencode semua wajah yang ada pada dataset. File yang kedua adalah face-recognition-img.py untuk mengenali wajah dengan input gambar. Dan yang ke 3 file face-recognition-video.py untuk mengenali wajah secara realtime dengan input video.
Struktur Direktori
Agar program yang akan dibuat rapi, kita harus menyusun direktori. Kita akan membuat direktori project di folder home Raspberry Pi. Semua project yang akan kita buat nantinya akan di simpan di bawah folder project tersebut.
cd ~
mkdir project
cd project
mkdir face-recognition
cd face-recognition
Selanjutnya kita akan bekerja di direktori ~/project/face-recognition. Project face-recognition ini akan membutuhkan folder dataset yang akan berisi foto wajah yang akan di deteksi. Masing-masing wajah yang berbeda akan di simpan dalam folder dengan nama masing-masing pemilik wajah.
cd ~/project/face-recognition
mkdir dataset
Source Code
Buat sebuah file dengan nama face-encoding.py pada direktori projek face-recognition, yaitu di ~/project/face-recognition.
nano face-encoding.py
Lalu isi dengan kode berikut.
# PENGGUNAAN
# python face-encoding.py --dataset dataset --encodings encodings.pickle --detection-method hog
# import library yang di perlukan
from imutils import paths
import face_recognition
import argparse
import pickle
import cv2
import os
# Parsing Argumen
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--dataset", required=True,
help="path to input directory of faces + images")
ap.add_argument("-e", "--encodings", required=True,
help="path to serialized db of facial encodings")
ap.add_argument("-d", "--detection-method", type=str, default="cnn",
help="face detection model to use: either `hog` or `cnn`")
args = vars(ap.parse_args())
# Ambil gambar dari folder dataset
print("[INFO] mendapatkan model wajah...")
imagePaths = list(paths.list_images(args["dataset"]))
# inisialiassi wajah yang di kenal
knownEncodings = []
knownNames = []
# loop di direktori gambar
for (i, imagePath) in enumerate(imagePaths):
# Ambil nama dari masing-masing folder
print("[INFO] Memproses gambar {}/{}".format(i + 1,
len(imagePaths)))
name = imagePath.split(os.path.sep)[-2]
# konversi ke RGB (OpenCV ordering) ke dlib ordering (RGB)
image = cv2.imread(imagePath)
rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# deteksi (x, y) koordinat dari kotak wajah
boxes = face_recognition.face_locations(rgb,
model=args["detection_method"])
# Pemrosesan Wajah
encodings = face_recognition.face_encodings(rgb, boxes)
# loop semua proses encoding
for encoding in encodings:
knownEncodings.append(encoding)
knownNames.append(name)
# dump the facial encodings + names to disk
print("[INFO] Memproses serialize encoding...")
data = {"encodings": knownEncodings, "names": knownNames}
f = open(args["encodings"], "wb")
f.write(pickle.dumps(data))
f.close()
Simpan file tersebut. Selanjutnya kita akan membuat file face-recognition-video.py pada direktori yang sama.
nano face-recognition-video.py
Masukan kode berikut:
# PENGGUNAAN
# python face-recognition-video.py --cascade haarcascade_frontalface_default.xml --encodings encodings.pickle
# import library yang di perlukan
from imutils.video import VideoStream
from imutils.video import FPS
import face_recognition
import argparse
import imutils
import pickle
import time
import cv2
# Parsing Argumen
ap = argparse.ArgumentParser()
ap.add_argument("-c", "--cascade", required=True,
help = "path to where the face cascade resides")
ap.add_argument("-e", "--encodings", required=True,
help="path to serialized db of facial encodings")
args = vars(ap.parse_args())
# load pendeteksi wajah dari file cascade OpenCV
print("[INFO] loading encodings + face detector...")
data = pickle.loads(open(args["encodings"], "rb").read())
detector = cv2.CascadeClassifier(args["cascade"])
# Nyalakan Kamera
print("[INFO] Memulai Stream dari Pi Camera...")
vs = VideoStream(src=0).start()
time.sleep(2.0)
# Penghitung FPS (Frame per Second)
fps = FPS().start()
# loop dari semua frame yang di dapat
while True:
# dapatkan frame, dan resize ke 500pixel agar lebih cepat
frame = vs.read()
frame = imutils.resize(frame, width=500)
# Konversi ke grayscale dan konversi ke RGB
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# deteksi wajah dari frame grayscale
rects = detector.detectMultiScale(gray, scaleFactor=1.1,
minNeighbors=5, minSize=(30, 30),
flags=cv2.CASCADE_SCALE_IMAGE)
# Tampilkan kotak di wajah yang dideteksi
boxes = [(y, x + w, y + h, x) for (x, y, w, h) in rects]
encodings = face_recognition.face_encodings(rgb, boxes)
names = []
# loop di semua wajah yang terdeteksi
for encoding in encodings:
matches = face_recognition.compare_faces(data["encodings"],
encoding)
name = "Unknown"
# check apakah ada wajah yang di kenali
if True in matches:
matchedIdxs = [i for (i, b) in enumerate(matches) if b]
counts = {}
for i in matchedIdxs:
name = data["names"][i]
counts[name] = counts.get(name, 0) + 1
name = max(counts, key=counts.get)
names.append(name)
# loop di semua wajah yang sudah di kenali
for ((top, right, bottom, left), name) in zip(boxes, names):
# tampilkan nama di wajah yang di kenali
cv2.rectangle(frame, (left, top), (right, bottom),
(0, 255, 0), 2)
y = top - 15 if top - 15 > 15 else top + 15
cv2.putText(frame, name, (left, y), cv2.FONT_HERSHEY_SIMPLEX,
0.75, (0, 255, 0), 2)
# Tampilkan gambar di layar
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
# tunggu tombol 1 untuk keluar
if key == ord("q"):
break
# update FPS
fps.update()
# tampilkan info FPS
fps.stop()
print("[INFO] elasped time: {:.2f}".format(fps.elapsed()))
print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))
# cleanup
cv2.destroyAllWindows()
vs.stop()
Jika sudah selesai, simpan file tersebut. Saat ini kita sudah memiliki 2 file python di direktori project ini.
Download file haarcascade
Selanjutnya kita akan membutuhakn file haarcascade bawaan dari OpenCV. Dalam kasus ini kita membutuhkan file haarcascade_frontalface_default.xml. File haarcascade merupakan clasiffier untuk mentraining object. Dalam hal ini kita akan mendapatkan gambar wajah saja dari foto yang di simpan di folder dataset atau yang langsung di ambil dari kamera. Kita akan mendownloadnya langsung dari github dan menyimpan di direktori project kita.
wget https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml
OK, sampai saat ini kita sudah selesai untuk tahap coding. Selanjutnya kita akan mencoba untuk membuat model.
3.Training Model
Pada tahap ini kita akan mengumpulkan foto-foto wajah yang akan di simpan di folder dataset. Anda bisa menggunakan foto wajah anda sendiri untuk ujicoba. Dalam percobaan kali ini saya akan membuat model saya dan teman saya. Buat direktori dengan nama masing-masing model yang akan di train.
cd ~/project/face-recognition/dataset/
mkdir yanwar
mkdir nunut
mkdir ferdy
Simpan foto masing masing di direktori yang sesuai. Foto bisa di ambil dari facebook, atau langsung dari kamera respberry anda dengan perintah raspistill. Simpan foto dengan berbagai ekspresi. Semakin banyak foto yang di simpan, akan semakin akurat pendeteksian wajah nantinya.
Setelah selesai menyimpan foto di masing masing direktori, selanjutnya kita akan melakukan encoding ke file pickle dengan script face-encoding.py yang telah kita buat. Jalan perintah berikut di direktori project anda.
cd ~/project/face-recognition/
python face-encoding.py --dataset dataset --encodings encodings.pickle --detection-method hog
Tunggu hingga proses encoding selesai. Setelah selesai anda akan menemukan file baru di direktori anda dengan nama encodings.pickle.
Contoh struktur direktori yang sudah jadi adalah seperti di bawah ini.
(cv) pi@raspberrypi:~/project/face-recognition $ tree
.
├── dataset
│ ├── Ferdy
│ │ ├── 001.jpg
│ │ ├── 002.jpg
│ │ ├── 003.jpg
│ │ ├── 004.jpg
│ │ ├── 005.jpg
│ │ ├── 006.jpg
│ │ ├── 007.jpg
│ │ └── 008.jpeg
│ ├── Nunut
│ │ ├── 001.jpg
│ │ ├── 002.jpg
│ │ ├── 003.jpg
│ │ ├── 004.jpg
│ │ └── 005.jpg
│ └── Yanwar
│ ├── 001.jpg
│ ├── 002.jpg
│ ├── 003.jpg
│ ├── 004.jpg
│ ├── 005.jpg
│ ├── 006.jpg
│ └── 007.jpg
├── encodings.pickle
├── face-encoding.py
├── face-recognition-video.py
└── haarcascade_frontalface_default.xml
Jalankan Program
Setelah proses encoding selesai, program pendeteksi wajah anda siap digunakan. Jalankan perintah berikut di direktori utama project anda.
python face-recognition-video.py --cascade haarcascade_frontalface_default.xml --encodings encodings.pickle
Tunggu hingga muncul video di layar. Coba untuk menghadap ke kamera, dan lihat apa yang terjadi. Untuk menjalankan program ini, anda harus menggunakan monitor di Raspberry Pi anda. Atau, anda bisa menggunakan VNC. Lihat artikel Cara Install Raspberry Pi secara Headless untuk cara mengaktifkan VNC.
Hasilnya kira-kira seperti pada video di bawah ini. Seperti yang anda lihat, hasilnya kurang akurat. Ini mungkin karena encoding menggunakan metode HOG, metode CNN (Convolutional Neural Network) tidak bisa dilakukan pada mesin Raspberry Pi. Selanjutnya kita akan mencoba dengan metode CNN menggunakan Server.
Kesimpulan
Proyek Facial Recognition yang kita buat masih merupakan proyek yang sederhana. Namun proyek ini merupakan pintu masuk ke dunia Computer Vision yang lebih luas lagi. Kami mengharapkan ide-ide baru akan muncul setelah berhasil membuat proyek ini.