|
1 | | -# Driver Drowsiness Detection System |
| 1 | +<div align="center"> |
2 | 2 |
|
3 | | -## Introduction |
| 3 | +# 😴 Driver Drowsiness Detection — OpenCV + Keras CNN |
4 | 4 |
|
5 | | -This project focuses on building a Driver Drowsiness Detection System that monitors a driver's eye status using a webcam and alerts them if they appear drowsy. We utilize **OpenCV** for image capture and preprocessing, while a **Convolutional Neural Network (CNN)** model classifies whether the driver's eyes are 'Open' or 'Closed.' If drowsiness is detected, an alarm is triggered to alert the driver. |
| 5 | +[](https://www.python.org/) |
| 6 | +[](https://opencv.org/) |
| 7 | +[](https://keras.io/) |
| 8 | +[](https://www.pygame.org/) |
| 9 | +[]() |
| 10 | +[](../LICENSE.md) |
6 | 11 |
|
7 | | -## Project Overview |
| 12 | +> A **real-time driver drowsiness detection system** that uses **Haar Cascade classifiers** to locate the driver's eyes in every webcam frame and a **custom-trained CNN** (`cnnCat2.h5`) to classify each eye as **Open** or **Closed** — sounding a `pygame` alarm when drowsiness is detected. |
8 | 13 |
|
9 | | -### Steps in the Detection Process: |
10 | | -1. **Image Capture**: Capture the image using a webcam. |
11 | | -2. **Face Detection**: Detect the face in the captured image and create a Region of Interest (ROI). |
12 | | -3. **Eye Detection**: Detect the eyes from the ROI and feed them into the classifier. |
13 | | -4. **Eye Classification**: The classifier categorizes whether the eyes are open or closed. |
14 | | -5. **Drowsiness Score Calculation**: Calculate a score to determine if the driver is drowsy based on how long their eyes remain closed. |
| 14 | +[🔙 Back to Main Repository](https://github.com/shsarv/Machine-Learning-Projects) |
15 | 15 |
|
16 | | -## CNN Model |
| 16 | +</div> |
17 | 17 |
|
18 | | -The **Convolutional Neural Network (CNN)** architecture consists of the following layers: |
19 | | -- **Convolutional Layers**: |
20 | | - - 32 nodes, kernel size 3 |
21 | | - - 32 nodes, kernel size 3 |
22 | | - - 64 nodes, kernel size 3 |
23 | | -- **Fully Connected Layers**: |
24 | | - - 128 nodes |
25 | | - - Output layer: 2 nodes (with Softmax activation for classification) |
| 18 | +--- |
26 | 19 |
|
27 | | -### Activation Function: |
28 | | -- **ReLU**: Used in all layers except the output layer. |
29 | | -- **Softmax**: Used in the output layer to classify the eyes as either 'Open' or 'Closed.' |
| 20 | +## ⚠️ Safety Context |
30 | 21 |
|
31 | | -## Project Prerequisites |
| 22 | +> Drowsy driving causes thousands of road fatalities annually. This system provides a real-time, automated alert to combat driver fatigue using a lightweight CNN that runs entirely on a standard webcam feed. |
32 | 23 |
|
33 | | -### Required Hardware: |
34 | | -- A webcam for image capture. |
| 24 | +--- |
35 | 25 |
|
36 | | -### Required Libraries: |
37 | | -Ensure Python (version 3.6 recommended) is installed on your system. Then, install the following libraries using `pip`: |
| 26 | +## 📌 Table of Contents |
38 | 27 |
|
39 | | -```bash |
40 | | -pip install opencv-python |
41 | | -pip install tensorflow |
42 | | -pip install keras |
43 | | -pip install pygame |
| 28 | +- [About the Project](#-about-the-project) |
| 29 | +- [How It Works](#-how-it-works) |
| 30 | +- [CNN Model Architecture](#-cnn-model-architecture) |
| 31 | +- [Dataset](#-dataset) |
| 32 | +- [Haar Cascade Files](#-haar-cascade-files) |
| 33 | +- [Scoring & Alert Logic](#-scoring--alert-logic) |
| 34 | +- [Project Structure](#-project-structure) |
| 35 | +- [Getting Started](#-getting-started) |
| 36 | +- [Tech Stack](#-tech-stack) |
| 37 | +- [Known Limitations](#-known-limitations) |
| 38 | +- [References](#-references) |
| 39 | + |
| 40 | +--- |
| 41 | + |
| 42 | +## 🔬 About the Project |
| 43 | + |
| 44 | +This project detects driver drowsiness through a two-stage pipeline: |
| 45 | + |
| 46 | +1. **Detection** — OpenCV Haar Cascade classifiers locate the face and each eye (left, right) in every frame |
| 47 | +2. **Classification** — A custom-trained Keras CNN (`cnnCat2.h5`) classifies each eye ROI as **Open** or **Closed** |
| 48 | + |
| 49 | +A running score is incremented each frame when eyes are detected as closed. When the score crosses a threshold, `pygame` plays `alarm.wav` and a "**DROWSY**" warning is overlaid on the video feed. |
| 50 | + |
| 51 | +**What this project covers:** |
| 52 | +- Training a binary CNN classifier on a custom ~7,000-image eye dataset |
| 53 | +- Real-time face and eye detection with OpenCV Haar cascades |
| 54 | +- Score-based drowsiness logic (accumulate → threshold → alarm) |
| 55 | +- Alarm playback with `pygame.mixer` |
| 56 | + |
| 57 | +--- |
| 58 | + |
| 59 | +## ⚙️ How It Works |
| 60 | + |
| 61 | +``` |
| 62 | +Webcam Frame (live stream) |
| 63 | + │ |
| 64 | + ▼ |
| 65 | + Convert BGR → Grayscale |
| 66 | + │ |
| 67 | + ▼ |
| 68 | + Haar Cascade: Detect Face |
| 69 | + (haarcascade_frontalface_alt.xml) |
| 70 | + │ |
| 71 | + ▼ |
| 72 | + Haar Cascade: Detect Eyes from frame |
| 73 | + ├── Left Eye (haarcascade_lefteye_2splits.xml) |
| 74 | + └── Right Eye (haarcascade_righteye_2splits.xml) |
| 75 | + │ |
| 76 | + ▼ |
| 77 | + Crop Eye ROI → Resize → Normalize |
| 78 | + │ |
| 79 | + ▼ |
| 80 | + CNN Forward Pass (cnnCat2.h5) |
| 81 | + → Predict: ['Close', 'Open'] |
| 82 | + → rpred / lpred updated per frame |
| 83 | + │ |
| 84 | + ├── Both eyes Open → score decremented (min 0) |
| 85 | + │ |
| 86 | + └── Eye(s) Closed → score incremented |
| 87 | + │ |
| 88 | + └── score > threshold |
| 89 | + │ |
| 90 | + ▼ |
| 91 | + 🔔 pygame alarm.wav |
| 92 | + 📺 "DROWSY" on screen |
| 93 | + 🟥 Red border on frame |
| 94 | +``` |
| 95 | + |
| 96 | +--- |
| 97 | + |
| 98 | +## 🧠 CNN Model Architecture |
| 99 | + |
| 100 | +`model.py` defines and trains the CNN classifier. The trained weights are saved as `models/cnnCat2.h5`. |
| 101 | + |
| 102 | +``` |
| 103 | +Input: Eye ROI image (24 × 24 × 1, grayscale) |
| 104 | + │ |
| 105 | + ▼ |
| 106 | +Conv2D(32, 3×3) → ReLU → MaxPool(1,1) |
| 107 | +Conv2D(32, 3×3) → ReLU → MaxPool(1,1) |
| 108 | +Conv2D(64, 3×3) → ReLU → MaxPool(1,1) |
| 109 | + │ |
| 110 | + ▼ |
| 111 | +Flatten |
| 112 | +Dense(128) → ReLU |
| 113 | +Dropout(0.5) |
| 114 | +Dense(2) → Softmax |
| 115 | + │ |
| 116 | + ▼ |
| 117 | +Output: ['Close', 'Open'] |
| 118 | +``` |
| 119 | + |
| 120 | +**Training configuration:** |
| 121 | + |
| 122 | +| Parameter | Value | |
| 123 | +|-----------|-------| |
| 124 | +| Classes | 2 — `Close` / `Open` | |
| 125 | +| Input Size | 24 × 24 × 1 (grayscale) | |
| 126 | +| Optimizer | Adam | |
| 127 | +| Loss | Categorical Cross-Entropy | |
| 128 | +| Activation (hidden) | ReLU | |
| 129 | +| Activation (output) | Softmax | |
| 130 | +| Regularization | Dropout (0.5) | |
| 131 | + |
| 132 | +--- |
| 133 | + |
| 134 | +## 📊 Dataset |
| 135 | + |
| 136 | +| Property | Details | |
| 137 | +|----------|---------| |
| 138 | +| **Type** | Custom — captured via webcam script | |
| 139 | +| **Total Images** | ~7,000 eye images | |
| 140 | +| **Classes** | `Open` / `Close` | |
| 141 | +| **Conditions** | Various lighting conditions | |
| 142 | +| **Cleaning** | Manually cleaned to remove unusable frames | |
| 143 | + |
| 144 | +The dataset was created by writing a capture script that crops eye regions frame by frame and saves them to disk, labeled by folder (`Open/` or `Closed/`). It was then manually reviewed to remove noisy or ambiguous images. |
| 145 | + |
| 146 | +> **Want to train on your own data?** Run `model.py` against your own captured eye dataset following the same `Open/Close` folder structure. |
| 147 | +
|
| 148 | +--- |
| 149 | + |
| 150 | +## 📂 Haar Cascade Files |
| 151 | + |
| 152 | +Three XML classifiers are used from the `haar cascade files/` folder: |
| 153 | + |
| 154 | +| File | Purpose | |
| 155 | +|------|---------| |
| 156 | +| `haarcascade_frontalface_alt.xml` | Detects the driver's face bounding box | |
| 157 | +| `haarcascade_lefteye_2splits.xml` | Detects the left eye region within the frame | |
| 158 | +| `haarcascade_righteye_2splits.xml` | Detects the right eye region within the frame | |
| 159 | + |
| 160 | +These are pre-trained OpenCV Haar cascades — no training required. They are loaded in `drowsinessdetection.py` as: |
| 161 | + |
| 162 | +```python |
| 163 | +face = cv2.CascadeClassifier('haar cascade files/haarcascade_frontalface_alt.xml') |
| 164 | +leye = cv2.CascadeClassifier('haar cascade files/haarcascade_lefteye_2splits.xml') |
| 165 | +reye = cv2.CascadeClassifier('haar cascade files/haarcascade_righteye_2splits.xml') |
44 | 166 | ``` |
45 | 167 |
|
46 | | -### Other Project Files: |
47 | | -- **Haar Cascade Files**: Located in the "haar cascade files" folder, these XML files are necessary for detecting faces and eyes. |
48 | | -- **Model File**: The "models" folder contains the pre-trained CNN model `cnnCat2.h5`. |
49 | | -- **Alarm Sound**: The audio clip `alarm.wav` will play when drowsiness is detected. |
50 | | -- **Python Files**: |
51 | | - - `Model.py`: The file used to build and train the CNN model. |
52 | | - - `Drowsiness detection.py`: The main file that executes the driver drowsiness detection system. |
| 168 | +--- |
53 | 169 |
|
54 | | -## How the Algorithm Works |
| 170 | +## 🎯 Scoring & Alert Logic |
55 | 171 |
|
56 | | -### Step 1 – Image Capture |
57 | | -The webcam captures images in real-time using `cv2.VideoCapture(0)` and processes each frame. The frames are stored in a variable `frame`. |
| 172 | +The system uses a **running score counter** rather than a fixed-frame threshold: |
58 | 173 |
|
59 | | -### Step 2 – Face Detection |
60 | | -The image is converted to grayscale for face detection using a **Haar Cascade Classifier**. The faces are detected using `detectMultiScale()`, and boundary boxes are drawn around the detected faces. |
| 174 | +```python |
| 175 | +lbl = ['Close', 'Open'] # CNN output labels |
61 | 176 |
|
62 | | -### Step 3 – Eye Detection |
63 | | -Similar to face detection, eyes are detected within the ROI using another cascade classifier. The eye images are extracted and passed to the CNN model for classification. |
| 177 | +# Per frame: |
| 178 | +if rpred[0] == 0 and lpred[0] == 0: # Both eyes closed |
| 179 | + score += 1 |
| 180 | + cv2.putText(frame, "Closed", ...) |
| 181 | +else: # Eyes open |
| 182 | + score -= 1 |
| 183 | + cv2.putText(frame, "Open", ...) |
64 | 184 |
|
65 | | -### Step 4 – Eye Classification |
66 | | -The extracted eye images are preprocessed by resizing to 24x24 pixels, normalizing the values, and then passed into the CNN model (`cnnCat2.h5`). The model predicts whether the eyes are open or closed. |
| 185 | +score = max(score, 0) # Score never goes negative |
67 | 186 |
|
68 | | -### Step 5 – Drowsiness Detection |
69 | | -A score is calculated based on the status of both eyes. If both eyes are closed for an extended period, the score increases, indicating drowsiness. If the score exceeds a threshold, an alarm is triggered using the **Pygame** library. |
| 187 | +if score > 15: # Drowsiness threshold |
| 188 | + # Sound alarm |
| 189 | + mixer.Sound('alarm.wav').play() |
| 190 | + # Draw red border on frame |
| 191 | + thicc = min(thicc + 2, 16) |
| 192 | + cv2.rectangle(frame, (0,0), (width,height), (0,0,255), thicc) |
| 193 | +``` |
| 194 | + |
| 195 | +| Variable | Value | Meaning | |
| 196 | +|----------|:-----:|---------| |
| 197 | +| `score` threshold | **15** | Frames of closed eyes before alarm | |
| 198 | +| `rpred` / `lpred` | `0` = Closed, `1` = Open | CNN prediction per eye | |
| 199 | +| Border thickness `thicc` | Grows up to 16px | Visual urgency indicator | |
| 200 | + |
| 201 | +--- |
| 202 | + |
| 203 | +## 📁 Project Structure |
| 204 | + |
| 205 | +``` |
| 206 | +Drowsiness detection [OPEN CV]/ |
| 207 | +│ |
| 208 | +├── 📂 haar cascade files/ |
| 209 | +│ ├── haarcascade_frontalface_alt.xml # Face detector |
| 210 | +│ ├── haarcascade_lefteye_2splits.xml # Left eye detector |
| 211 | +│ └── haarcascade_righteye_2splits.xml # Right eye detector |
| 212 | +│ |
| 213 | +├── 📂 models/ |
| 214 | +│ └── cnnCat2.h5 # Trained CNN weights (download separately) |
| 215 | +│ |
| 216 | +├── drowsinessdetection.py # Main script — webcam loop + detection + alarm |
| 217 | +├── model.py # CNN model definition + training script |
| 218 | +├── alarm.wav # Alert sound file |
| 219 | +└── README.md # You are here |
| 220 | +``` |
| 221 | + |
| 222 | +> **Note:** `models/cnnCat2.h5` is not included in the repo due to GitHub file size limits. Download it from the Google Drive link in the project or train your own by running `model.py`. |
70 | 223 |
|
71 | | -## Execution Instructions |
| 224 | +--- |
72 | 225 |
|
73 | | -### Running the Detection System |
| 226 | +## 🚀 Getting Started |
74 | 227 |
|
75 | | -1. Open the command prompt and navigate to the directory where the main file `drowsiness detection.py` is located. |
76 | | -2. Run the script using the following command: |
| 228 | +### 1. Clone the repository |
77 | 229 |
|
78 | 230 | ```bash |
79 | | -python drowsiness detection.py |
| 231 | +git clone https://github.com/shsarv/Machine-Learning-Projects.git |
| 232 | +cd "Machine-Learning-Projects/Drowsiness detection [OPEN CV]" |
80 | 233 | ``` |
81 | 234 |
|
82 | | -The system will access the webcam and start detecting drowsiness. The real-time status will be displayed on the screen. |
| 235 | +### 2. Set up environment |
83 | 236 |
|
84 | | -## Summary |
| 237 | +```bash |
| 238 | +python -m venv venv |
| 239 | +source venv/bin/activate # Linux / macOS |
| 240 | +venv\Scripts\activate # Windows |
| 241 | + |
| 242 | +pip install -r requirements.txt |
| 243 | +``` |
85 | 244 |
|
86 | | -This Python project implements a **Driver Drowsiness Detection System** using **OpenCV** and a **CNN model** to detect whether the driver’s eyes are open or closed. When the eyes are detected as closed for a prolonged time, an alert sound is played to prevent potential accidents. This system can be implemented in vehicles or other applications to enhance driver safety. |
| 245 | +### 3. Download the trained model |
87 | 246 |
|
88 | | -## Future Enhancements |
| 247 | +The `cnnCat2.h5` model file must be placed in the `models/` folder. Download it from the link provided in the repository issues/releases, then: |
89 | 248 |
|
90 | | -- Improve the detection accuracy by training on a larger dataset. |
91 | | -- Implement real-time monitoring for multiple people. |
92 | | -- Add functionalities to detect other signs of drowsiness like head tilting or yawning. |
93 | | - |
94 | | -## Contributing |
| 249 | +```bash |
| 250 | +mkdir models |
| 251 | +# Place cnnCat2.h5 inside models/ |
| 252 | +``` |
95 | 253 |
|
96 | | -Feel free to contribute by submitting issues or pull requests. For major changes, please open an issue to discuss the proposed changes before submitting a PR. |
| 254 | +Or train your own model from scratch: |
97 | 255 |
|
| 256 | +```bash |
| 257 | +python model.py |
| 258 | +# Saves models/cnnCat2.h5 automatically |
| 259 | +``` |
98 | 260 |
|
99 | | -## Acknowledgments |
| 261 | +### 4. Run the detector |
100 | 262 |
|
101 | | -- [OpenCV Documentation](https://opencv.org/) |
| 263 | +```bash |
| 264 | +python drowsinessdetection.py |
| 265 | +``` |
| 266 | + |
| 267 | +- The webcam opens automatically |
| 268 | +- Eyes detected as closed → score increments |
| 269 | +- Score exceeds threshold → **alarm sounds + red border appears** |
| 270 | +- Press **`q`** to quit |
| 271 | + |
| 272 | +--- |
| 273 | + |
| 274 | +## 🛠️ Tech Stack |
| 275 | + |
| 276 | +| Layer | Technology | |
| 277 | +|-------|-----------| |
| 278 | +| Language | Python 3.7+ | |
| 279 | +| Computer Vision | OpenCV (`cv2`) | |
| 280 | +| Eye Detection | Haar Cascade Classifiers | |
| 281 | +| Deep Learning | Keras + TensorFlow backend | |
| 282 | +| Model | Custom CNN (`cnnCat2.h5`) | |
| 283 | +| Audio Alarm | Pygame (`pygame.mixer`) | |
| 284 | +| Numerical Processing | NumPy | |
| 285 | + |
| 286 | +--- |
| 287 | + |
| 288 | +## ⚠️ Known Limitations |
| 289 | + |
| 290 | +| Limitation | Detail | |
| 291 | +|-----------|--------| |
| 292 | +| **Lighting sensitivity** | Haar cascades and CNN accuracy drop under poor or uneven lighting | |
| 293 | +| **Glasses / sunglasses** | Frames and tinted lenses obstruct eye detection | |
| 294 | +| **Head pose** | Extreme angles may cause Haar cascade face/eye detection to fail | |
| 295 | +| **Single eye closure** | If only one eye closes (winking), score increments only partially | |
| 296 | +| **No yawn detection** | Fatigue from yawning is not measured — only eye closure | |
| 297 | + |
| 298 | +--- |
| 299 | + |
| 300 | +## 📚 References |
| 301 | + |
| 302 | +- [OpenCV Haar Cascade Documentation](https://docs.opencv.org/4.x/db/d28/tutorial_cascade_classifier.html) |
102 | 303 | - [Keras Documentation](https://keras.io/) |
103 | | -- [TensorFlow Documentation](https://www.tensorflow.org/) |
| 304 | +- [Pygame mixer Documentation](https://www.pygame.org/docs/ref/mixer.html) |
| 305 | + |
| 306 | +--- |
| 307 | + |
| 308 | +<div align="center"> |
| 309 | + |
| 310 | +Part of the [Machine Learning Projects](https://github.com/shsarv/Machine-Learning-Projects) collection by [Sarvesh Kumar Sharma](https://github.com/shsarv) |
| 311 | + |
| 312 | +⭐ Star the main repo if this helped you! |
104 | 313 |
|
105 | | ---- |
| 314 | +</div> |
0 commit comments