Drowsiness Detection System for Drivers
A project that uses OpenCV to detect a driver's drowsiness via webcam. If drowsiness is detected, it
sends a signal to an Arduino which displays a warning on a 16*2 LCD, sounds a buzzer for 10
seconds, and stops a motor controlled by a relay.
Python Code (OpenCV for Drowsiness Detection)
import cv2
import dlib
from scipy.spatial import distance as dist
import serial
import time
arduino = serial.Serial('COM3', 9600)
face_detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
def eye_aspect_ratio(eye):
A = dist.euclidean(eye[1], eye[5])
B = dist.euclidean(eye[2], eye[4])
C = dist.euclidean(eye[0], eye[3])
ear = (A + B) / (2.0 * C)
return ear
EAR_THRESHOLD = 0.3
EAR_CONSEC_FRAMES = 48
frame_counter = 0
drowsy = False
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if not ret:
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_detector(gray)
for face in faces:
landmarks = predictor(gray, face)
landmarks = [(landmarks.part(i).x, landmarks.part(i).y) for i in range(68)]
left_eye = landmarks[36:42]
right_eye = landmarks[42:48]
left_ear = eye_aspect_ratio(left_eye)
right_ear = eye_aspect_ratio(right_eye)
ear = (left_ear + right_ear) / 2.0
if ear < EAR_THRESHOLD:
frame_counter += 1
if frame_counter >= EAR_CONSEC_FRAMES:
if not drowsy:
drowsy = True
print("Drowsiness Detected!")
arduino.write(b'1')
else:
frame_counter = 0
drowsy = False
arduino.write(b'0')
cv2.imshow("Frame", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Arduino Code
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int buzzerPin = 8;
const int motorPin = 7;
const int relayPin = 6;
void setup() {
lcd.begin(16, 2);
lcd.print("System Ready");
pinMode(buzzerPin, OUTPUT);
pinMode(motorPin, OUTPUT);
pinMode(relayPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0) {
char received = Serial.read();
if (received == '1') {
lcd.clear();
lcd.print("Pay Attention!");
digitalWrite(motorPin, LOW);
digitalWrite(relayPin, LOW);
digitalWrite(buzzerPin, HIGH);
delay(10000);
digitalWrite(buzzerPin, LOW);
} else if (received == '0') {
lcd.clear();
lcd.print("All Clear");
digitalWrite(motorPin, HIGH);
digitalWrite(relayPin, HIGH);
}
}
}
Notes
- Update the 'COM3' port in the Python code to match your Arduino's port.
- Ensure the 'shape_predictor_68_face_landmarks.dat' file is in the same directory or provide the
correct path.
- Tune the EAR_THRESHOLD and EAR_CONSEC_FRAMES values based on your requirements.