Tutorial Membuat Aplikasi Deteksi Kantuk Pengemudi Berbasis Deep Learning di VPS Ubuntu
Pengantar
Deteksi kantuk pengemudi adalah salah satu contoh penerapan Artificial Intelligence, Computer Vision, dan Deep Learning yang cukup menarik untuk dipelajari. Dengan memanfaatkan kamera, aplikasi dapat membaca kondisi wajah pengguna, mendeteksi mata yang tertutup terlalu lama, mengenali tanda menguap, lalu memberikan peringatan ketika pengguna terindikasi mengantuk.
Pada tutorial ini, kita akan membuat aplikasi Deteksi Kantuk Pengemudi berbasis Deep Learning menggunakan Python, Flask, OpenCV, MediaPipe, JavaScript Camera API, Nginx, dan HTTPS. Aplikasi akan dijalankan di VPS Ubuntu dan dapat diakses melalui domain, misalnya:
https://ngantuk.pwhtutor.my.id
Tutorial ini cocok untuk Anda yang ingin belajar membuat aplikasi AI sederhana, proyek Computer Vision, sistem monitoring pengemudi, atau demo penerapan Deep Learning berbasis web.
Apa yang Akan Dibuat?
Kita akan membuat aplikasi web yang dapat mengakses kamera dari browser, lalu mengirim frame gambar ke server untuk dianalisis.
Alur kerjanya seperti ini:
Kamera HP/Laptop
→ Browser menangkap gambar wajah
→ Frame dikirim ke Flask Server
→ MediaPipe mendeteksi landmark wajah
→ Sistem menghitung kondisi mata dan mulut
→ Jika mata tertutup terlalu lama, status menjadi Mengantuk
→ Browser menampilkan status dan membunyikan alarm
Aplikasi ini menggunakan dua indikator utama:
EAR = Eye Aspect Ratio
MAR = Mouth Aspect Ratio
EAR digunakan untuk membaca kondisi mata. Jika nilai EAR kecil, berarti mata cenderung tertutup. MAR digunakan untuk membaca kondisi mulut. Jika nilai MAR besar, berarti mulut terbuka atau pengguna kemungkinan sedang menguap.
Prasyarat Server
Sebelum memulai, pastikan Anda sudah memiliki VPS yang siap digunakan.
Rekomendasi minimal VPS:
CPU : 4 Core
RAM : 4 GB atau lebih
Storage : 40 GB SSD
OS : Ubuntu 24.04
Akses : Root SSH
Domain : Opsional, tetapi disarankan untuk HTTPS
Untuk proyek ini, VPS CPU biasa sudah cukup karena aplikasi menggunakan MediaPipe Face Mesh dan OpenCV. Jika nanti ingin mengembangkan ke model deteksi yang lebih berat seperti YOLO, TensorFlow custom model, atau realtime multi-kamera, Anda bisa mempertimbangkan VPS dengan spesifikasi lebih besar atau GPU.
Bagi pengguna yang ingin langsung mencoba di server online, layanan Cloud VPS Plasawebhost dapat digunakan sebagai tempat instalasi aplikasi Python, Flask, Nginx, dan SSL. Dengan VPS, aplikasi tidak hanya berjalan di lokal laptop, tetapi juga bisa diakses dari browser HP atau perangkat lain melalui domain HTTPS.
Teknologi yang Digunakan
Pada tutorial ini kita menggunakan beberapa komponen berikut:
Python: Bahasa utama backend
Flask: Web framework ringan
OpenCV: Pemrosesan gambar
MediaPipe: Deteksi landmark wajah
NumPy: Pengolahan array gambar
JavaScript : Mengakses kamera browser
Nginx : Reverse proxy
Certbot SSL: HTTPS gratis Lets Encrypt
systemd : Menjalankan aplikasi otomatis
Kenapa menggunakan HTTPS? Karena browser modern, terutama di HP, umumnya hanya mengizinkan akses kamera jika halaman dibuka melalui HTTPS atau localhost.
1. Membuat Folder Project
2. Menyiapkan Virtual Environment Python
3. Membuat File Requirements
4. Membuat Backend Flask untuk Deteksi Kantuk
Buat file utama aplikasi
nano /home/driver-drowsiness/app.py
isi dengan kode berikut :
from flask import Flask, render_template, request, jsonify
import cv2
import numpy as np
import mediapipe as mp
import base64
import time
import math
app = Flask(__name__)
mp_face_mesh = mp.solutions.face_mesh
face_mesh = mp_face_mesh.FaceMesh(
static_image_mode=False,
max_num_faces=1,
refine_landmarks=True,
min_detection_confidence=0.5,
min_tracking_confidence=0.5
)
LEFT_EYE = [33, 160, 158, 133, 153, 144]
RIGHT_EYE = [362, 385, 387, 263, 373, 380]
closed_eye_start = None
yawn_start = None
DROWSY_TIME_THRESHOLD = 2.0
EAR_THRESHOLD = 0.22
MAR_THRESHOLD = 0.60
def euclidean_distance(p1, p2):
return math.dist(p1, p2)
def eye_aspect_ratio(landmarks, eye_points, width, height):
points = []
for idx in eye_points:
lm = landmarks[idx]
points.append((int(lm.x * width), int(lm.y * height)))
p1, p2, p3, p4, p5, p6 = points
vertical_1 = euclidean_distance(p2, p6)
vertical_2 = euclidean_distance(p3, p5)
horizontal = euclidean_distance(p1, p4)
if horizontal == 0:
return 0
ear = (vertical_1 + vertical_2) / (2.0 * horizontal)
return ear
def mouth_aspect_ratio(landmarks, width, height):
top = landmarks[13]
bottom = landmarks[14]
left = landmarks[78]
right = landmarks[308]
top_point = (int(top.x * width), int(top.y * height))
bottom_point = (int(bottom.x * width), int(bottom.y * height))
left_point = (int(left.x * width), int(left.y * height))
right_point = (int(right.x * width), int(right.y * height))
vertical = euclidean_distance(top_point, bottom_point)
horizontal = euclidean_distance(left_point, right_point)
if horizontal == 0:
return 0
mar = vertical / horizontal
return mar
def decode_base64_image(image_data):
try:
image_data = image_data.split(",")[1]
image_bytes = base64.b64decode(image_data)
np_arr = np.frombuffer(image_bytes, np.uint8)
frame = cv2.imdecode(np_arr, cv2.IMREAD_COLOR)
return frame
except Exception:
return None
@app.route("/")
def index():
return render_template("index.html")
@app.route("/detect", methods=["POST"])
def detect():
global closed_eye_start, yawn_start
data = request.get_json()
if not data or "image" not in data:
return jsonify({
"success": False,
"message": "No image received"
}), 400
frame = decode_base64_image(data["image"])
if frame is None:
return jsonify({
"success": False,
"message": "Invalid image"
}), 400
frame = cv2.flip(frame, 1)
height, width, _ = frame.shape
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
result = face_mesh.process(rgb_frame)
status = "Normal"
alert = False
detail = "Wajah terdeteksi normal"
ear_value = 0
mar_value = 0
current_time = time.time()
if result.multi_face_landmarks:
face_landmarks = result.multi_face_landmarks[0].landmark
left_ear = eye_aspect_ratio(face_landmarks, LEFT_EYE, width, height)
right_ear = eye_aspect_ratio(face_landmarks, RIGHT_EYE, width, height)
ear_value = round((left_ear + right_ear) / 2.0, 3)
mar_value = round(mouth_aspect_ratio(face_landmarks, width, height), 3)
if ear_value < EAR_THRESHOLD:
if closed_eye_start is None:
closed_eye_start = current_time
closed_duration = current_time - closed_eye_start
if closed_duration >= DROWSY_TIME_THRESHOLD:
status = "Mengantuk"
alert = True
detail = f"Mata tertutup {closed_duration:.1f} detik"
else:
status = "Mata Mulai Tertutup"
detail = f"Mata tertutup {closed_duration:.1f} detik"
else:
closed_eye_start = None
if mar_value > MAR_THRESHOLD:
if yawn_start is None:
yawn_start = current_time
yawn_duration = current_time - yawn_start
if yawn_duration >= 1.0:
status = "Menguap"
alert = True
detail = f"Terdeteksi menguap {yawn_duration:.1f} detik"
else:
yawn_start = None
else:
status = "Wajah Tidak Terdeteksi"
detail = "Pastikan wajah terlihat jelas oleh kamera"
closed_eye_start = None
yawn_start = None
return jsonify({
"success": True,
"status": status,
"alert": alert,
"detail": detail,
"ear": ear_value,
"mar": mar_value
})
@app.route("/health")
def health():
return jsonify({
"status": "ok",
"service": "driver-drowsiness"
})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5070, debug=True)
5. Membuat Tampilan Web Kamera
6. Menjalankan Aplikasi Secara Manual
7. Menyiapkan Domain dan HTTPS
8. Install Nginx dan Certbot
9. Membuat Virtual Host Nginx
10. Pasang SSL HTTPS
11. Membuat systemd Service
12. Menguji Aplikasi
13. Penjelasan EAR dan MAR
14. Mengatur Sensitivitas Deteksi
Kesimpulan
Dengan mengikuti tutorial ini, kita sudah berhasil membuat aplikasi Deteksi Kantuk Pengemudi berbasis Deep Learning yang berjalan di VPS Ubuntu dan dapat diakses melalui domain HTTPS.
Aplikasi ini membuktikan bahwa teknologi AI dan Computer Vision tidak harus selalu dimulai dari sistem yang rumit. Dengan Python, Flask, OpenCV, MediaPipe, dan VPS yang tepat, kita sudah bisa membuat sistem monitoring wajah sederhana yang dapat mendeteksi tanda-tanda kantuk dari kamera browser.
Jika ingin mengembangkan proyek ini lebih jauh, Anda bisa menambahkan fitur seperti rekaman log kantuk, capture otomatis, notifikasi WhatsApp, dashboard monitoring, deteksi wajah lebih dari satu orang, atau integrasi dengan sistem kendaraan.
Untuk kebutuhan deploy aplikasi AI, Flask, Python, Laravel, Node.js, maupun project berbasis server lainnya, penggunaan VPS akan lebih fleksibel dibanding hosting biasa. Dengan VPS, Anda memiliki kontrol penuh terhadap environment, dependency, service, port, Nginx, SSL, dan proses background seperti systemd. Layanan Cloud VPS Plasawebhost dapat menjadi pilihan untuk membangun dan menjalankan project AI sederhana sampai skala yang lebih serius.


