01 / 05 · cluster k=0
A YOLOv8 I fine-tuned finds plates at 0.94 mAP50; OCR reads them and a local LLM sums them up.
Reading a plate from a car photo is really two problems: where is the plate, and what does it say. An off-the-shelf detector doesn't know what a plate is, and raw OCR happily reads text that isn't one. I wanted both steps in a single end-to-end pipeline that filters out false positives.
I fine-tuned a pretrained YOLOv8 on a labelled 474-image Kaggle dataset for 50 epochs. Each detected box is trimmed slightly to cut edge noise, read with Tesseract OCR, and validated by a regex against the Turkish plate format (2 digits, 1–3 letters, 2–4 digits). A 0.5 confidence threshold and the regex together remove false positives. The LLM gets no deterministic job: the regex owns format checking, and qwen2.5 only summarises the city behind the province code in plain language.
On the validation set the model reaches 0.94 precision, 0.85 recall and 0.94 mAP50. On the stricter mAP50-95, which averages tighter IoU thresholds, it scores 0.56. The whole flow, from photo upload to city name, runs end to end in a Streamlit app.
Photo upload
YOLOv8 plate detection
Crop + Tesseract OCR
Regex format check
Province code → city, LLM summary
Streamlit UI
Python · YOLOv8 · OpenCV · Tesseract OCR · Ollama · Streamlit
474 images is a small sample, so performance can shift with lighting, angle and distance. OCR can stumble on decorative fonts or plates with symbols, and the small LLM occasionally invents details beyond the province code. This is a learning and portfolio project; the next step toward production is a much larger, more varied dataset.