Aplikasi desktop Python untuk deteksi jenis plastik secara realtime dari webcam menggunakan PyTorch dan OpenCV dengan bbox tracking stabil.
- Create and activate a virtual environment:
# Create virtual environment
python3 -m venv venv
#ensure u use python 3.14 to avoid error
#and make sure u have the c++ or c compiler installed for numpy
# Activate virtual environment
# On macOS/Linux:
source venv/bin/activate
# On Windows:
# venv\Scripts\activate- Install dependencies:
pip install -r requirements.txtRun the desktop application with camera loop (command line interface):
python app.pyNote: Make sure the virtual environment is activated before running the application.
Tekan ESC untuk keluar dari aplikasi.
Run the desktop application with PyQt5 GUI (realtime detection with modern interface):
python app_gui.pyFeatures:
- ๐จ Modern GUI dengan PyQt5
- ๐น Realtime video preview
- ๐ค Live plastic classification
- โป๏ธ Recycling recommendations in Indonesian
- ๐ FPS counter
- ๐ฏ Bounding box visualization
Tekan ESC atau tombol "Keluar" untuk menutup aplikasi.
Run the web-based UI with API backend:
- Start the Flask API backend:
python api.pyThe API will run on http://localhost:5001 (port 5001 karena 5000 conflict dengan AirPlay di macOS)
- Open the web interface:
Open web/index.html in your browser, or serve it with:
cd web
python -m http.server 8000Then visit http://localhost:8000/index.html
Web Features:
- ๐ธ Upload images or use webcam for classification
- ๐ค AI classification with confidence scores
- โป๏ธ Recycling recommendations
- ๐จ Modern, responsive UI (Bahasa Indonesia)
- ๐ฑ Mobile-friendly
Note: Web app menggunakan "capture photo" mode, bukan realtime detection. Untuk realtime detection, gunakan Desktop GUI (app_gui.py).
- Realtime bbox detection: Deteksi objek plastik menggunakan OpenCV contours (tanpa YOLO)
- Stable tracking: CSRT tracker untuk bbox yang stabil dan smooth
- ROI classification: Crop ROI dari bbox โ klasifikasi dengan ResNet18
- Inference throttling: Inference hanya setiap N frames (default: setiap 3 frames)
- Smooth overlay: Bbox, label, confidence, dan rekomendasi ditampilkan realtime
- FPS counter: Monitor performa aplikasi
- CPU-friendly: Optimized untuk CPU, CUDA opsional
- Stabil: Didesain untuk running >10 menit tanpa masalah
- Modern PyQt5 Interface: GUI yang clean dan professional
- Realtime Video Preview: Live camera feed dengan bbox overlay
- Live Classification: Deteksi dan klasifikasi plastik secara realtime
- Information Panel: Tampilan hasil, confidence score, dan rekomendasi
- FPS Monitor: Real-time FPS counter
- Keyboard Shortcuts: ESC untuk keluar
- Smooth Animations: Transisi yang halus dan responsive
- Image Upload: Upload gambar plastik untuk klasifikasi
- Webcam Capture: Ambil foto langsung dari webcam
- AI Classification: Identifikasi jenis plastik dengan confidence score
- Recycling Guide: Rekomendasi daur ulang untuk setiap jenis plastik
- Responsive Design: Works on desktop and mobile devices
- Real-time Processing: Fast classification with visual feedback
Webcam โ Bbox Detection (contours) โ CSRT Tracker โ ROI Crop โ
ResNet18 Classifier (throttled) โ Overlay/Display (bbox + label + recommendation)
Browser (Upload/Camera) โ Flask API โ ResNet18 Classifier โ JSON Response โ
Web UI Display (Label + Confidence + Recommendations)
- app.py: Original CLI-based realtime detection (OpenCV display)
- vision/bbox_detector.py: Deteksi bbox menggunakan Canny edges + contours
- vision/bbox_tracker.py: CSRT/KCF tracker untuk stabilisasi bbox
- vision/smoothing.py: EMA smoothing untuk bbox dan confidence
- ml/classifier.py: ResNet18 classifier dengan FP32 enforcement
- ui/camera_loop.py: Main camera loop logic (used by app.py)
- api.py: Flask REST API endpoint untuk image classification
- web/index.html: React-based web UI (single file, no build required)
Classify a plastic item from an uploaded image.
Request:
- Method:
POST - Content-Type:
multipart/form-data - Body:
image(file)
Response:
{
"label": "PET",
"confidence": 0.95
}Check if the API is running.
Response:
{
"status": "ok"
}The application uses a ResNet18 model trained for 4-class plastic classification. The model file should be located at models/plastitrace.pth.
Classes: HDPE, PET, PP, PS
plastitrace_desktop/
โโโ app.py # Entry point (Desktop CLI)
โโโ app_gui.py # Entry point (Desktop GUI - PyQt5)
โโโ api.py # Flask API backend (Web App)
โโโ requirements.txt
โโโ models/
โ โโโ plastitrace.pth
โโโ ml/
โ โโโ config.py # Constants & recommendations
โ โโโ classifier.py # PyTorch ResNet18 classifier
โ โโโ preprocess.py # Image preprocessing
โโโ vision/
โ โโโ bbox_detector.py # Contour-based bbox detection
โ โโโ bbox_tracker.py # CSRT/KCF tracker wrapper
โ โโโ smoothing.py # EMA smoothing
โโโ ui/
โ โโโ camera_loop.py # Camera loop logic (for app.py)
โโโ utils/
โ โโโ softmax.py # Softmax utility
โโโ web/
โโโ index.html # Web UI (React + Tailwind)
Default settings in app.py and app_gui.py:
min_area=2000: Minimum bbox area untuk detectioninference_interval=3: Run inference setiap 3 framesredetect_interval=30: Re-detect bbox setiap 30 frames (untuk koreksi drift)
Default settings in api.py:
- Host:
0.0.0.0 - Port:
5001(changed from 5000 to avoid AirPlay conflict on macOS) - Debug:
True(set toFalsefor production) - CORS: Enabled for all origins (restrict in production)
Web UI (index.html):
- API URL:
http://localhost:5001/api/classify
Aplikasi menampilkan rekomendasi daur ulang dalam Bahasa Indonesia:
- HDPE: Umumnya bisa didaur ulang. Bilas dan masukkan ke sampah daur ulang plastik keras.
- PET: Botol minum plastik. Bilas, lepas label bila memungkinkan, buang ke sampah daur ulang.
- PP: Wadah makanan/kantong tertentu. Bila bersih, daur ulang; jika tidak ada fasilitas, buang sebagai residu.
- PS: Styrofoam/foam. Sulit didaur ulang; hindari pembakaran, buang ke sampah residu.
Error: "No OpenCV tracker available"
- Install opencv-contrib-python:
pip install opencv-contrib-python
Error: "No module named 'PyQt5'" (GUI only)
- Install PyQt5:
pip install PyQt5
Low FPS or slow inference
- Reduce
inference_intervalinapp.pyorapp_gui.py - Use smaller input images
- Enable CUDA if available
Camera not detected
- Check if camera is already in use by another application
- Try changing
camera_indexfrom 0 to 1 in the code - Check camera permissions in System Preferences (macOS)
Error: "Port 5001 is in use"
- Change port in
api.py:app.run(host='0.0.0.0', port=5002, debug=True) - Update API URL in
web/index.htmlto match new port
Error: "Cannot access camera"
- Grant browser permission to access camera
- Use HTTPS (required for webcam on some browsers)
- Check if camera is already in use
Error: "Failed to classify image"
- Make sure Flask API is running on
http://localhost:5001 - Check API logs for errors
- Verify model file exists at
models/plastitrace.pth
CORS errors
- Ensure flask-cors is installed:
pip install flask-cors - Check browser console for specific CORS errors
macOS AirPlay Receiver conflict (Port 5000)
- Disable AirPlay Receiver in System Settings โ General โ AirDrop & Handoff
- OR use port 5001 (already configured in api.py)
| Feature | Desktop CLI | Desktop GUI | Web App |
|---|---|---|---|
| Realtime Detection | โ Yes | โ Yes | โ No (capture only) |
| Modern UI | โ No | โ Yes | โ Yes |
| Installation | Easy | Easy | Medium |
| Performance | Excellent | Excellent | Good |
| Mobile Support | โ No | โ No | โ Yes |
| Best For | Development/Testing | End Users (Desktop) | Web Access/Mobile |
Recommendation:
- Development/Debugging: Use
app.py(CLI) - Desktop Users: Use
app_gui.py(PyQt5 GUI) - RECOMMENDED - Web/Mobile Access: Use Web App (
api.py+web/index.html)
- Package with PyInstaller for distribution:
pip install pyinstaller
pyinstaller --onefile --windowed app_gui.pyFor production deployment:
- Set Flask to production mode:
- Change
debug=Truetodebug=Falseinapi.py - Use a production WSGI server like Gunicorn:
- Change
pip install gunicorn
gunicorn -w 4 -b 0.0.0.0:5001 api:app-
Configure CORS properly:
- Restrict allowed origins in
api.py - Don't use
CORS(app)with no parameters in production
- Restrict allowed origins in
-
Serve static files:
- Use Nginx or Apache to serve
web/index.html - Configure reverse proxy to Flask API
- Use Nginx or Apache to serve
-
Security considerations:
- Add rate limiting
- Implement file size limits for uploads
- Validate file types
- Use HTTPS
[Your License Here]
[Your Team/Contributors Here]
- โจ Added PyQt5 GUI desktop application (
app_gui.py) - ๐ Added web interface with React UI
- ๐ง Fixed port conflict with macOS AirPlay (port 5001)
- ๐ฎ๐ฉ Full Bahasa Indonesia support in all interfaces
- ๐ Updated documentation
- ๐ฏ Initial release with CLI desktop app
- ๐ค ResNet18 classification
- ๐น CSRT bbox tracking