Facial Recognition Dengan Raspberry Pi dan OpenCV

· 7 menit untuk membaca
Facial Recognition
Facial Recognition

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.

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 berikut.

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

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.

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.

Pada artikel terpisah kita akan mencoba membuat proyek lain berbasis Computer Vision. Ikuti terus TeknoTut untuk belajar lebih banyak lagi.