A modular, production-ready computer-vision system for inspecting Printed Circuit Boards, built on Python + OpenCV + YOLOv8 + Streamlit. It detects manufacturing defects, verifies them with classical CV, scores severity, renders a Pass/Fail verdict, generates a PDF report, and logs every inspection to a cloud (or local) database.
Designed to run today on a laptop for development/demo, and to move to
a Raspberry Pi or NVIDIA Jetson Nano inspection line later with minimal
changes — see docs/EDGE_DEPLOYMENT.md.
| Module | Status | File(s) |
|---|---|---|
| 1. Image Acquisition | ✅ | preprocessing/image_processor.py (ImageAcquisition) |
| 2. Preprocessing (resize/denoise/CLAHE/sharpen/RGB) | ✅ | preprocessing/image_processor.py (ImagePreprocessor) |
| 3. YOLOv8 Defect Detection | ✅ | detection/yolo_detector.py |
| 4. Hybrid OpenCV Verification | ✅ | analysis/hybrid_analyzer.py |
| 5. AI Analysis Panel | ✅ | analysis/defect_knowledge.py |
| 6. Pass/Fail Logic | ✅ | analysis/defect_knowledge.py |
| 7. PDF Report | ✅ | reports/pdf_generator.py |
| 8. Cloud Database (Firestore + SQLite fallback) | ✅ | database/db_client.py |
| 9. Streamlit Dashboard | ✅ | app.py, ui/components.py |
| Batch folder inspection | ✅ | built into app.py |
| Webcam live feed | 🧩 future-ready hook | capture/webcam_stream.py |
| YOLO training / dataset prep | ✅ | training/train_yolo.py, datasets/prepare_dataset.py |
| Edge deployment (RPi/Jetson) | 📄 guide provided | docs/EDGE_DEPLOYMENT.md |
The app runs immediately after pip install even before you train
a custom model — it auto-falls-back to a generic YOLOv8n checkpoint
(so the UI, preprocessing, OpenCV analysis, PDF report, and database
are all fully testable on day one) and to a local SQLite database if
Firebase isn't configured. Nothing hard-crashes on a missing model or
missing cloud credentials.
pcb_inspection_system/
├── app.py # Streamlit dashboard (entry point)
├── pipeline.py # Orchestrates all modules end-to-end
├── config.py # All tunables in one place
├── requirements.txt
├── .env.example
├── models/ # Trained YOLOv8 weights (best.pt) go here
├── preprocessing/
│ └── image_processor.py # Acquisition + resize/denoise/CLAHE/sharpen
├── detection/
│ ├── yolo_detector.py # YOLOv8 inference wrapper
│ └── annotator.py # Bounding-box drawing
├── analysis/
│ ├── hybrid_analyzer.py # Edge/contour/morphology/CC verification
│ └── defect_knowledge.py # Cause/recommendation + Pass/Fail logic
├── reports/
│ └── pdf_generator.py # ReportLab PDF report builder
├── database/
│ └── db_client.py # Firestore backend + SQLite fallback
├── ui/
│ └── components.py # Streamlit rendering helpers
├── capture/
│ └── webcam_stream.py # Phase 7: real-time webcam module
├── training/
│ └── train_yolo.py # YOLOv8 fine-tuning script
├── datasets/
│ └── prepare_dataset.py # DeepPCB -> YOLO format converter
├── docs/
│ ├── TRAINING_GUIDE.md
│ └── EDGE_DEPLOYMENT.md
├── tests/
│ └── test_pipeline_smoke.py # No-GPU, no-weights-required smoke tests
├── outputs/
│ ├── annotated/ # Saved annotated images
│ └── reports/ # Saved PDF reports
└── logs/ # Rotating application logs
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txtCPU-only machines: if
pip install torchis slow/fails, install the CPU wheel explicitly first:pip install torch --index-url https://download.pytorch.org/whl/cpu
cp .env.example .env
# edit .env -> USE_FIREBASE=true
# place your service account key at database/firebase_credentials.jsonIf you skip this step, the app automatically uses a local SQLite
database (database/local_inspections.db) — no setup required.
See docs/TRAINING_GUIDE.md for the full walkthrough. Short version:
python datasets/prepare_dataset.py --source datasets/deeppcb_raw --output datasets/yolo_format
python training/train_yolo.py --data datasets/pcb_defect.yaml --epochs 100 --auto-deployWithout this step, the app still runs using a generic YOLOv8n checkpoint (it just won't know PCB-specific defect classes yet).
streamlit run app.pyOpen the printed local URL. Upload a PCB image, click Inspect PCB, and review results in the right panel; download the PDF/annotated image from the left panel; browse history at the bottom.
pytest tests/ -v- Left panel: image source selector (upload / folder batch), PCB ID
- inspector name fields, Inspect button, PDF/image download buttons
- Right panel: original vs. annotated image, Pass/Fail banner with defect-severity metrics, defect table, AI analysis panel (cause + recommendation per defect)
- Bottom: inspection history table (from Firestore or SQLite), search-by-PCB-ID
missing_hole, mouse_bite, open_circuit, short_circuit, spur,
spurious_copper, missing_conductor — see config.DEFECT_SEVERITY
and config.DEFECT_KNOWLEDGE_BASE to adjust severity mapping or the
cause/recommendation text shown in the AI Analysis Panel.
Pass/Fail rule: any Critical-severity defect → FAIL, otherwise
PASS (configurable in analysis/defect_knowledge.py).
database/db_client.py is written as a swappable-backend façade.
Implement a MySQLBackend class with the same 4 methods as
SQLiteBackend/FirestoreBackend (save_inspection, get_history,
search_by_pcb_id), then wire it into InspectionDatabase.__init__.
config.MYSQL_CONFIG already has connection settings scaffolded.
See docs/EDGE_DEPLOYMENT.md for OS setup, ONNX/TensorRT/NCNN export
instructions, and a pre-flight checklist before going live on an
inspection line.
models/best.ptis not included — you must train it (dataset + training scripts are provided) or supply your own weights.- DeepPCB has no direct
missing_conductorclass; add your own labeled examples for full 7-class coverage (seedocs/TRAINING_GUIDE.md). - The webcam module (
capture/webcam_stream.py) ships as a standalone OpenCV loop plus a reusable frame-grabber class; wiring it into the Streamlit UI viastreamlit-webrtcfor in-browser live video is the natural next step once Phase 7 is prioritized. - Firebase is optional; SQLite fallback is intended for dev/offline use, not multi-line concurrent production without further hardening (connection pooling, retries) if you later scale to MySQL/Postgres.