Work · Vision

defect-inspector.

A few good photos and a new image go in. A score, a heatmap and the region that looks off come out.

12 November 2026 v1 · 0.1.0 Python 3.11+ MIT CI

Web demo on a metal surface: a score and a heatmap mark a scratch, and a region box is drawn on the area that looks off.
Web demo on a metal surface. Detection is PatchCore with a wide-resnet50 backbone. Image AUROC 1.000 on this surface; 12/12 defects flagged.

The problem

A few good photos, and a mark that is easy to miss.

Imagine a short line of parts and a handful of photos of good ones. An inspector looks at each new piece for a scratch, a dent, a stain. There are not enough labelled defects to train a classifier, and a miss is easy when the mark is small.

The useful result is not a model that “sees defects.” It is a score and a heatmap that mark the region that looks off, fitted from a few good samples and no defect labels.

What we built

A score and a heatmap, fitted from good samples only.

The pipeline is five steps. Detection does not need a language model. A few good photos are fitted with PatchCore, implemented here from the paper (wide-resnet50 patches, a greedy coreset memory bank, nearest-neighbour distance). A new image is scored against that bank; a heatmap and a box mark the region that looks off. Optionally, a vision-language model can label the region. You get a score, an overlay PNG, and JSON or CSV.

Pipeline: a few good photos are fitted with PatchCore; a new image is scored against that memory bank; a heatmap and a box mark the region that looks off; an optional vision-language model can label the region.
Detection runs locally. Region labels, if you ask for them, use a vision-language model — your API, or an open model from Hugging Face.
Left: a metal surface with a scratch, and the PatchCore heatmap highlighting it. Right: the same region described by a vision-language model.
Metal surface. Image AUROC 1.000, 12/12 defects flagged, 0/6 good images flagged. scripts/evaluate.py.
Web demo: a metal surface with a PatchCore heatmap highlighting a scratch.
Metal surface, PatchCore heatmap. Image AUROC 1.000, 12/12 defects flagged, 0/6 good images flagged.
Web demo on a stone surface, with a stain flagged on the heatmap.
Stone surface. Image AUROC 0.958; 11/12 defects flagged; 1/6 good images flagged.

A yes-or-no flag without a place on the image is a rumour. A score with a heatmap is a claim you can look at — from the box back to the scratch, and dismiss it if the box is wrong. That is the difference between a detector you still inspect by hand, and one that can actually help.

Results

35 of 36 defects flagged, on three surfaces.

On three surfaces — metal, fabric and stone — PatchCore with wide_resnet50_2 flagged 35 of 36 defects, with image AUROC 1.000, 1.000 and 0.958. Pixel AUROC was 0.993, 0.993 and 0.957. One good stone image was flagged (1/18 good test images). Fitting took 2.0–4.6 seconds on eight images; scoring took 0.04–0.05 seconds per image (detection only).

PatchCore detection results on three surfaces, 12 November 2026.
SurfaceImage AUROCPixel AUROCFlagged defectFlagged goodTop regionFit (s)s / image
metal 1.0000.99312/120/612/124.60.04
fabric 1.0000.99312/120/612/122.00.05
stone 0.9580.95711/121/610/112.30.04
All35/361/1834/352.0–4.60.04–0.05

Methodology. Three surfaces, 8 good training images, 6 good and 12 defective test images per surface (36 defective, 18 good, one defect per defective image). A defect is flagged when its score is above a threshold taken from the good training images. “Top region” counts flagged defects whose highest-scoring region overlaps the ground-truth mask. Backbone timm/wide_resnet50_2.tv_in1k, 12 November 2026. Detection timings are in docs/eval-detection.md. The raw table is in docs/eval.md. The script is scripts/evaluate.py; the samples are in samples/.

Region labels, scored with Qwen3-VL-2B-Instruct on the Hugging Face backend, were right on 29 of 34 flagged regions that hit the mask (12/12 metal, 8/12 fabric, 9/10 stone). The most common mistake on this set is calling a dent a spot. Labels are a description to help review, not a classification you can rely on.

Run it yourself

Three commands, then the demo.

Quickstart
git clone https://github.com/ModelShifts/defect-inspector
cd defect-inspector && python -m venv .venv && source .venv/bin/activate
pip install -e ".[demo]" && defect-inspector serve

On a CPU-only machine, install the CPU build of PyTorch first. Detection needs no language model. Add ".[hf]" or ".[api]" for optional region descriptions. Python 3.11 or newer.