A production-grade client-server object detection pipeline built with YOLOv8, FastAPI, and WebSockets. Webcam frames are streamed from the client to the server, processed through YOLOv8 inference, and returned as annotated frames β all with sub-second latency.
- π₯ Live webcam streaming β real-time capture via OpenCV
- π§ YOLOv8 inference β powered by Ultralytics (swap
yolov8nβs/m/lfreely) - β‘ Low-latency WebSocket pipeline β bidirectional async communication
- π Frame skip + JPEG compression β efficient bandwidth usage
- π§΅ Thread-pool inference β parallel processing with
ThreadPoolExecutor - π Live HUD overlay β FPS, latency, inference time, object count
- π Auto-reconnect β client recovers from dropped connections automatically
- π Multi-client ready β session-based architecture, each client isolated
- π Graceful shutdown β press
Qto cleanly stop the client
βββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββ
β CLIENT β β SERVER β
β β β β
β Webcam β OpenCV Capture β β FastAPI + Uvicorn β
β β β Frame β β β
β JPEG Encode + Base64 β βββββββΊ β WebSocket Receiver β
β β β β β β
β WebSocket Send (async) β β asyncio.Queue (buffer) β
β β β β β
β Display Thread β ββββββ β ThreadPoolExecutor β
β β βAnnotatedβ β β
β HUD Overlay + cv2.imshow β Frame β YOLOv8 Inference β Annotate β
β β β β β
β β β JPEG Encode + Base64 β Send β
βββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββ
- Client opens webcam and captures frames at up to 30 FPS
- Every Nth frame is JPEG-compressed and Base64-encoded
- Encoded frame is sent via WebSocket to the server with a timestamp
- Server buffers frames in a per-client async queue (drops oldest on overflow)
ThreadPoolExecutorruns YOLOv8 inference on each frame- Annotated frame is encoded and sent back with detection metadata
- Client decodes and displays the result with a live HUD overlay
real-time-object-detection/
β
βββ server.py # FastAPI + WebSocket server with YOLOv8 inference
βββ client.py # Async WebSocket client with capture + display
βββ yolov8n.pt # YOLOv8 nano model weights (swap for larger models)
βββ requirements_server.txt # Server-side Python dependencies
βββ requirements_client.txt # Client-side Python dependencies
βββ README.md
git clone https://github.com/your-username/real-time-object-detection-streaming.git
cd real-time-object-detection-streamingpython -m venv venv
# Windows
venv\Scripts\activate
# macOS / Linux
source venv/bin/activateServer:
pip install -r requirements_server.txtClient (can be a different machine on the same network):
pip install -r requirements_client.txtpython server.pyServer starts at:
ws://localhost:8765/ws/stream
http://localhost:8765/health
http://localhost:8765/stats
python client.pyA window opens showing the webcam feed with live bounding boxes and HUD overlay. Press Q or ESC to quit.
| Variable | Default | Description |
|---|---|---|
SERVER_URI |
ws://localhost:8765/ws/stream |
Server WebSocket address |
CAMERA_INDEX |
0 |
Webcam device index |
CAPTURE_WIDTH / HEIGHT |
640 x 480 |
Capture resolution |
TARGET_FPS |
30 |
Webcam capture rate |
SEND_EVERY_N |
2 |
Send every Nth frame (higher = less bandwidth) |
JPEG_QUALITY |
75 |
Compression quality before sending (0β100) |
RECONNECT_DELAY |
3.0 |
Seconds to wait before reconnecting |
| Variable | Default | Description |
|---|---|---|
MODEL_NAME |
yolov8n.pt |
YOLO model file (n/s/m/l/x) |
CONFIDENCE_THRESHOLD |
0.45 |
Minimum detection confidence |
IOU_THRESHOLD |
0.45 |
Non-max suppression IoU threshold |
MAX_QUEUE_SIZE |
10 |
Frame buffer per client |
INFERENCE_WORKERS |
2 |
Parallel inference threads |
JPEG_QUALITY |
80 |
Annotated frame encode quality |
| Method | Endpoint | Description |
|---|---|---|
GET |
/health |
Server status, connected clients, model info |
GET |
/stats |
Per-client stats: frames processed, avg inference time, uptime |
WS |
/ws/stream |
WebSocket stream endpoint for clients |
{
"status": "ok",
"clients": 1,
"model": "yolov8n.pt",
"workers": 2
}{
"a3f1bc2d": {
"frames_received": 412,
"frames_processed": 410,
"frames_dropped": 2,
"total_inference_ms": 8540.3,
"uptime_s": 38.2,
"avg_inference_ms": 20.83
}
}The client overlays a live heads-up display on the video window:
| Metric | Description |
|---|---|
β LIVE / β OFFLINE |
WebSocket connection status |
Send FPS |
Frames sent per second to server |
Recv FPS |
Annotated frames received per second |
Latency |
Rolling average round-trip time (ms) |
Inference |
Server-side YOLOv8 inference time (ms) |
Objects |
Number of detections in current frame |
Sent / Rcvd |
Total frame counters |
Skip / Quality |
Active send-every-N and JPEG quality settings |
| Technique | Benefit |
|---|---|
Frame skipping (SEND_EVERY_N) |
Reduces bandwidth without stalling |
| JPEG compression | Shrinks payload size significantly |
asyncio.Queue with overflow drop |
Prevents server memory buildup |
ThreadPoolExecutor for inference |
Keeps async loop non-blocking |
| Single-slot frame buffer on client | Always sends the latest frame, not stale ones |
| Rolling latency average | Smooth HUD metrics, no jitter |
| Layer | Technology |
|---|---|
| ML Inference | YOLOv8 (Ultralytics) |
| Server Framework | FastAPI + Uvicorn |
| Client Vision | OpenCV |
| Communication | WebSockets (bidirectional) |
| Concurrency | asyncio + threading + ThreadPoolExecutor |
| Encoding | JPEG + Base64 over JSON |
Replace yolov8n.pt with any variant for a speed/accuracy tradeoff:
| Model | Size | Speed | Accuracy |
|---|---|---|---|
yolov8n.pt |
~6 MB | β‘ Fastest | Good |
yolov8s.pt |
~22 MB | Fast | Better |
yolov8m.pt |
~50 MB | Moderate | High |
yolov8l.pt |
~87 MB | Slower | Very High |
yolov8x.pt |
~137 MB | Slowest | Best |
Update MODEL_NAME in server.py accordingly.
- π₯οΈ Browser-based frontend (WebRTC or canvas-based client)
- π₯ GPU acceleration with CUDA / TensorRT
- π Load-balanced multi-server deployment
- πΉ Video file input support (not just webcam)
- πΎ Detection logging and analytics dashboard
- βοΈ Cloud deployment (AWS / GCP / Azure)
Camera not opening:
Cannot open camera 0
Try CAMERA_INDEX = 1 or check if another app is using the webcam.
Connection refused:
Make sure server.py is running before starting the client.
YOLO not installed fallback:
If ultralytics is missing, the server runs a DummyDetector and overlays a warning on frames. Fix with:
pip install ultralyticsSlow inference:
Switch to a smaller model (yolov8n.pt) or reduce CAPTURE_WIDTH/CAPTURE_HEIGHT in the client config.
Veda β B.Tech AI & ML Student
This project is intended for educational and research purposes.