Full-stack web application for real-time facial emotion recognition using deep learning. Detects 7 emotions through webcam with a CNN model trained on FER2013 dataset.
- Real-time emotion detection from webcam (1.5s intervals)
- 7 emotion classes: Angry 😠, Disgust 🤢, Fear 😨, Happy 😄, Sad 😢, Surprise 😮, Neutral 😐
- CNN model trained on 35,000+ FER2013 images
- Confidence scores for predictions
- Animated emoji overlay with pulse effects
- REST API with CORS support
Frontend: React 18, Vite, Axios, CSS3
Backend: Flask, TensorFlow 2.15, Keras, OpenCV, Flask-CORS
ML: CNN (4 conv blocks, BatchNorm, Dropout), 8M parameters
Dataset: FER2013 (48x48 grayscale images)
emotion-detection/
├── backend/
│ ├── app.py
│ ├── best_emotion_model.h5
│ ├── requirements.txt
│ └── .gitignore
├── frontend/
│ ├── src/
│ │ ├── App.jsx
│ │ ├── App.css
│ │ ├── main.jsx
│ ├── index.css
│ ├── index.html
│ ├── package.json
│ ├── package-lock.json
│ └── .gitignore
├── .gitignore
└── README.md
- Python 3.11
- Node.js 16+
- Webcam
cd backend
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
# Place best_emotion_model.h5 in backend/ directory
python app.pyBackend runs on http://localhost:5000
cd frontend
npm install
npm run devFrontend runs on http://localhost:5173
Open http://localhost:5173 and allow webcam access when prompted.
Base URL: http://localhost:5000
Request:
{
"image": "data:image/jpeg;base64,/9j/4AAQ..."
}Response:
{
"emotion": "Happy",
"confidence": 0.8523,
"probabilities": {
"Angry": 0.0234,
"Disgust": 0.0012,
"Fear": 0.0098,
"Happy": 0.8523,
"Sad": 0.0456,
"Surprise": 0.0521,
"Neutral": 0.0156
}
}Health check endpoint
Detailed system status
Architecture:
- Input: 48x48 grayscale images
- 4 Convolutional blocks with BatchNorm, MaxPooling, Dropout
- 2 Dense layers (512 → 256)
- Softmax output (7 classes)
- Total parameters: ~8 million
Training:
- Dataset: FER2013 (35,887 images)
- Split: 80% train, 10% val, 10% test
- Augmentation: Rotation, shift, flip, zoom
- Optimizer: Adam (lr=0.0001)
- Loss: Categorical Crossentropy
- Hardware: Kaggle GPU T4
- Training time: 30-40 minutes
- Test accuracy: 60-68%
- Inference time: 50-100ms per image
| Problem | Solution |
|---|---|
| Model not found | Place best_emotion_model.h5 in backend/ directory |
| CORS error | Install flask-cors: pip install flask-cors |
| Port 5000 in use | Change port in app.py: app.run(port=5001) |
| Webcam not working | Check browser permissions, use Chrome |
| Backend not responding | Verify Flask is running, check API_URL in App.jsx |
In frontend/src/App.jsx:
const CAPTURE_INTERVAL = 2000 // Change to 2 secondsIn frontend/src/App.css:
body {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.webcam-container {
border: 4px solid #YOUR_COLOR;
}- Retrain model with new classes
- Update
EMOTION_LABELSinbackend/app.py - Add emoji mapping in
frontend/src/App.jsx
- Size: 35,887 images (48x48 grayscale)
- Classes distribution:
- Happy: 8,989
- Neutral: 6,198
- Sad: 6,077
- Fear: 5,121
- Angry: 4,953
- Surprise: 4,002
- Disgust: 547 (imbalanced)
MIT License
Kaggle: @serhiikravchenko2009 GitHub: @Serhii2009 LinkedIn: serhii-kravchenko-b941272a6
⭐ If you found this project helpful, please consider giving it a star! Built with React, Flask & TensorFlow