03 / case study / Aug 2025 – Dec 2025
AI print inspection system
A camera system that checks printed tickets on a real press and says which check failed.
Python · PyTorch · YOLOv8 · OpenCV · NumPy · ONNX
The short version
Nissha Medical Technologies prints tickets on its EXT705 press, 21 to a photograph. A camera system on the line already marks each photograph good or bad. Our four-person team built a second system that makes the same call from the same photograph in about 80 milliseconds, and says which check failed, so every rejection can be explained.
What is being checked
Printed across the tickets are small dark rectangles called Q-blocks. Nobody reads them. They are reference marks, like the register marks in the margin of a newspaper, and they are the first thing to go wrong: faint, missing or shifted. So the system checks the marks, not the tickets. A photograph should hold 14 or 21 of them, depending on the layout.
How it works
- Find the blocks. A YOLOv8 model, trained on 240 labelled photographs, draws a box around each block. On its validation photographs it scored 0.995 mAP50, the standard score for this kind of model.
- Count them. The right number, 14 or 21, or the photograph fails.
- Check each one. Is it crisp enough to be sure of, and is there enough ink in it? The pass marks were measured from good print, then tuned by hand until good print passed.
- Say why. Every rejection lists the checks it failed.
What we found
The obvious system counts the blocks. On 2,315 photographs, counting caught 18 of the 2,123 bad ones. Nearly every bad photograph had all its blocks, just too faint: 2,105 of them failed on ink. Counting alone would have passed over two thousand of them and looked like it was working.
In the final run, all 192 good photographs passed and all 2,123 bad ones were caught, matching the line's camera every time.
Built twice, on purpose
One version uses classical image processing with OpenCV: explicit steps, no GPU, and you can see exactly why it decided. The other uses the trained model. When the lighting changed between photo sets, the classical version started rejecting good photographs, though it still caught every bad one. Having both let us show the client the trade rather than argue about it.
What it does not show yet
All 2,123 bad photographs came from one hour on one night, so this shows the system catches that batch's fault, not every fault. The good photographs it was scored on are the ones its pass marks were tuned on. A fair test needs good and bad print from many runs, kept apart from the tuning.
It was handed over as a folder watcher with a live screen. Connecting it to the press, so it can stop a bad run, was designed, starting with a phase where it decides but rejects nothing, and not built.
What I'd do next
Run it beside the existing camera on live print for a few weeks, and score both against a person's call on every photograph where they disagree.