This repository implements a video analytics pipeline for vehicle detection, tracking, and license plate recognition.
The project is designed with a modular inference backend, allowing vehicle detection to run using either PyTorch or OpenVINO.
The primary goal of this project is to demonstrate correct and practical integration of OpenVINO into an existing computer-vision pipeline, with a focus on deployment, runtime selection, and system-level reasoning.
- Vehicle detection using YOLOv8
- Vehicle tracking using SORT
- License plate detection and OCR
- CSV and JSON event logging
- Switchable inference backend:
- PyTorch (baseline)
- OpenVINO (optimized inference)
Video Input
↓
Vehicle Detection (YOLOv8)
↓
Vehicle Tracking (SORT)
↓
License Plate Detection
↓
OCR
↓
CSV / JSON Output
- Vehicle detection:
- PyTorch YOLOv8 (default)
- OpenVINO YOLOv8 (optional, runtime-switchable)
- License plate detection:
- PyTorch YOLO (currently)
Only the vehicle detection stage is executed via OpenVINO in this prototype.
- A pretrained YOLOv8 vehicle detection model
- Converted to OpenVINO IR format
- Executed using:
AUTO:GPU,CPU
📊 Performance Observations
On a local CPU-only setup, the following behavior was observed:
1.PyTorch YOLOv8n shows similar or slightly lower end-to-end latency
2.This is expected because:
- YOLOv8n is a lightweight model
- PyTorch uses MKL / oneDNN optimizations on CPU
- License plate detection and OCR still run in PyTorch
pip install -r requirements.txt
pip install openvino
uvicorn main:app --reload
or
python main.py
Download video : https://drive.google.com/file/d/1D_OLOY5hkPcQfv93_3PZYAzyuvJsbLke/view?usp=drive_link
{"frame_nmr": 0, "car_id": 3.0, "car_bbox": [752, 1370, 1430, 1982], "license_plate": {"bbox": [986, 1788, 1181, 1840], "bbox_score": 0.5806435942649841, "text": "IN41JMR", "text_score": 0.24334674029814932}, "timestamp": {"ms": 0.0, "utc": "2025-12-16T15:42:08.830317+00:00"}}
{"frame_nmr": 0, "car_id": 4.0, "car_bbox": [2198, 1157, 2783, 1735], "license_plate": {"bbox": [2411, 1565, 2581, 1624], "bbox_score": 0.48309609293937683, "text": "MU51KSU", "text_score": 0.14795953771009374}, "timestamp": {"ms": 0.0, "utc": "2025-12-16T15:42:08.830317+00:00"}}
{"frame_nmr": 1, "car_id": 3.0, "car_bbox": [752, 1370, 1430, 1982], "license_plate": {"bbox": [987, 1788, 1181, 1840], "bbox_score": 0.5870230197906494, "text": "NA13MPU", "text_score": 0.17951069297607156}, "timestamp": {"ms": 16.666666666666668, "utc": "2025-12-16T15:42:09.355912+00:00"}}
{"frame_nmr": 1, "car_id": 4.0, "car_bbox": [2198, 1157, 2782, 1735], "license_plate": {"bbox": [2411, 1565, 2581, 1624], "bbox_score": 0.48742157220840454, "text": "MU51KSV", "text_score": 0.13863040322459963}, "timestamp": {"ms": 16.666666666666668, "utc": "2025-12-16T15:42:09.355912+00:00"}}
{"frame_nmr": 2, "car_id": 3.0, "car_bbox": [746, 1374, 1424, 1988], "license_plate": {"bbox": [973, 1786, 1187, 1841], "bbox_score": 0.6532045006752014, "text": "IN41JNR", "text_score": 0.20114248419174732}, "timestamp": {"ms": 33.333333333333336, "utc": "2025-12-16T15:42:09.589507+00:00"}}
{"frame_nmr": 2, "car_id": 4.0, "car_bbox": [2203, 1166, 2784, 1741], "license_plate": {"bbox": [2416, 1568, 2578, 1629], "bbox_score": 0.5552865862846375, "text": "NU51KV", "text_score": 0.17770964841238598}, "timestamp": {"ms": 33.333333333333336, "utc": "2025-12-16T15:42:09.589507+00:00"}}
{"frame_nmr": 3, "car_id": 3.0, "car_bbox": [744, 1379, 1422, 1996], "license_plate": {"bbox": [973, 1796, 1185, 1846], "bbox_score": 0.5080745220184326, "text": "NA1?NRU", "text_score": 0.6018769475707695}, "timestamp": {"ms": 50.0, "utc": "2025-12-16T15:42:09.818160+00:00"}}
frame_nmr,car_id,car_bbox,license_plate_bbox,license_plate_bbox_score,license_number,license_number_score,timestamp_ms,timestamp_utc
0,3.0,"[752, 1370, 1430, 1982]","[986, 1788, 1181, 1840]",0.5806435942649841,IN41JMR,0.24334674029814932,0.0,2025-12-16T15:42:08.830317+00:00
0,4.0,"[2198, 1157, 2783, 1735]","[2411, 1565, 2581, 1624]",0.48309609293937683,MU51KSU,0.14795953771009374,0.0,2025-12-16T15:42:08.830317+00:00
1,3.0,"[752, 1370, 1430, 1982]","[987, 1788, 1181, 1840]",0.5870230197906494,NA13MPU,0.17951069297607156,16.666666666666668,2025-12-16T15:42:09.355912+00:00
1,4.0,"[2198, 1157, 2782, 1735]","[2411, 1565, 2581, 1624]",0.48742157220840454,MU51KSV,0.13863040322459963,16.666666666666668,2025-12-16T15:42:09.355912+00:00
2,3.0,"[746, 1374, 1424, 1988]","[973, 1786, 1187, 1841]",0.6532045006752014,IN41JNR,0.20114248419174732,33.333333333333336,2025-12-16T15:42:09.589507+00:00
2,4.0,"[2203, 1166, 2784, 1741]","[2416, 1568, 2578, 1629]",0.5552865862846375,NU51KV,0.17770964841238598,33.333333333333336,2025-12-16T15:42:09.589507+00:00
3,3.0,"[744, 1379, 1422, 1996]","[973, 1796, 1185, 1846]",0.5080745220184326,NA1?NRU,0.6018769475707695,50.0,2025-12-16T15:42:09.818160+00:00
- Convert license plate detector to OpenVINO
- Measure per-stage inference latency
- Evaluate GPU / NPU execution
- Add batch and multi-stream inference
- Deploy on AI PC hardware
📚 Third-Party Components
- YOLOv8 by Ultralytics (pretrained model)
- COCO dataset (used for pretrained model training)
- SORT (Simple Online and Realtime Tracking) by Alex Bewley et al.
All third-party components are used in accordance with their respective licenses.
This project is intended as a learning and experimentation platform for:
- OpenVINO inference integration
- Runtime backend abstraction
- System-level performance reasoning
It is structured to be easily extensible for GSoC and open-source contributions.
