top of page

How to Build a Production-Grade Visual Defect Detection System for Manufacturing

3 hours ago
7 min read

A convincing factory inspection demo is easy to make: train a classifier, upload a product image, and display defective or normal. A production inspection system is harder. It must cope with illumination changes, camera movement, unseen normal variation, uncertain scores, traceability, model drift, and the very different costs of a false reject and a defect escape.



This tutorial builds a small but complete reference implementation. We will generate aligned metal-plate images, learn normal appearance, calibrate separate pass and reject thresholds, localize anomalies, expose the model through FastAPI, test the failure path, and package it in a non-root Docker image. The companion repository is at examples/industrial-visual-defect-detection.



The data are deliberately synthetic so the workflow can run locally. The results in this article show that the pipeline works; they do not claim real-factory accuracy.



Technology stack: Python, NumPy, Pillow, FastAPI, Pydantic, Pytest, Docker, and GitHub Actions.





What we are building



The service receives the identifier of an inspection image and returns:



{
  "sample_id": "test-defect-000",
  "model_version": "normal-appearance-zscore-v1",
  "anomaly_score": 16.638508,
  "decision": "reject",
  "hotspot_fraction": 0.01178,
  "bounding_box": [33, 37, 68, 51]
}


These values come from the verified deterministic tutorial run. The important design choice is the decision policy:


  • Pass: sufficiently similar to qualified normal data.


  • Review: uncertain; a trained operator or downstream rule decides.


  • Reject: clearly anomalous under the calibrated policy


The tutorial does not connect the result to a line-stop or reject actuator. That requires a separate controls and safety design.




Why industrial visual inspection is a strong AI engineering problem



The World Economic Forum reports unusually broad expected AI adoption in advanced manufacturing, while NIST's 2026 smart-manufacturing roadmap identifies AI/ML capabilities, trustworthy integration, validation, and operational deployment as active needs. NIST also maintains manufacturing work on detection and segmentation of defects. These are signals that the opportunity is not only “use a model”; it is to engineer a reliable measurement and decision system around the model. See the WEF industry analysis, NIST smart-manufacturing roadmap, and NIST defect detection research.



For a realistic public benchmark after this tutorial, MVTec AD provides more than 5,000 high-resolution images across 15 object and texture categories, with defect-free training data and anomalous test images plus pixel-level annotations. Read its terms before use: MVTec AD dataset.



Prerequisites



  • Python 3.11 or newer


  • Docker Desktop or another Docker engine for the container step


  • Git


  • About 500 MB of free space


Clone or copy the companion project, then enter it:



cd examples/industrial-visual-defect-detection
python -m venv .venv


Activate the environment:



.venv\Scripts\Activate.ps1


On macOS or Linux:



source .venv/bin/activate


Install the locked tutorial dependencies:



python -m pip install --requirement requirements-dev.txt




Step 1: Define the inspection contract before the model



Write down the operational contract first:


  1. What part family and surface are in scope?


  2. Which defect families matter—scratches, dents, stains, missing features, contamination?


  3. What is the acceptable false-accept rate for each severity?


  4. Can uncertain parts wait for manual review?


  5. What must happen when the camera, model, or network is unavailable?


These answers determine the data and architecture. A cosmetic inspection can often tolerate review latency. A safety-critical component may require redundant measurements and a conservative fail-safe state.



The sample uses a three-way decision rather than pretending every score is certain. This is a simple form of selective automation: automate high-confidence cases and expose ambiguity.





Step 2: Generate leakage-resistant tutorial data



Run:



python scripts/generate_dataset.py


The script creates 160 images:



Split

Normal

Defective

Purpose

Train

60

0

Learn qualified normal appearance

Calibration

20

20

Select pass and reject thresholds

Test

30

30

Final untouched evaluation



Scratch, dent, and stain defects receive pixel masks so localization can be measured. In a real project, do not randomly split near-duplicate video frames. Keep production batches, suppliers, shifts, lines, or time windows together; otherwise the test set can leak almost identical conditions from training.



The manifest records every sample and its split:



sample_id,split,label,is_defect,defect_type,image_path,mask_path
train-normal-000,train,normal,0,none,...
cal-defect-000,calibration,defect,1,scratch,...




Step 3: Learn normal appearance



Many factories have abundant normal parts but few representative defects. A normal-only baseline is therefore a useful first approach.



For each aligned training image, the sample code:


  1. Converts it to grayscale and resizes it to 128 × 128.


  2. Standardizes brightness per image.


  3. Computes the mean and standard deviation at each pixel.


  4. Scores a new image using the absolute per-pixel z-score.


  5. Smooths the anomaly map and uses its 99.5th percentile as the image score.


Run training:



python scripts/train.py


The model is intentionally understandable. It is not a replacement for PatchCore, PaDiM, feature-pyramid methods, segmentation networks, or a vision transformer when the production data require them. It gives us a transparent baseline and an end-to-end system to improve.





Step 4: Calibrate pass, review, and reject thresholds



The training set estimates normal appearance; it must not also be the final evaluation set. scripts/train.py scores the separate calibration set and chooses:


  • a pass threshold from the high end of calibration-normal scores;


  • a reject threshold by evaluating candidate score cutoffs on calibration normal and defect examples;


  • the range between them as the manual-review band.


The current deterministic run produced:



pass_threshold   1.462732
reject_threshold 11.524766
pixel_threshold  5.0


In production, select thresholds from business cost and confidence intervals, not F1 alone. A defect escape may cost a field failure; a false reject may cost inspection capacity. Track both and document who approved the operating point.





Step 5: Evaluate decisions and localization



Run:



python scripts/evaluate.py


The verified tutorial run on 60 held-out synthetic images produced:



Metric

Result

Defect escalation recall

100.0%

Auto-pass precision

100.0%

Auto-reject precision

100.0%

Normal auto-pass rate

93.33%

Mean localization IoU

87.71%

Decision counts

28 pass, 2 review, 30 reject


This is a pipeline smoke test on simple generated data—not a benchmark. Notice what the three-way policy communicates better than accuracy: no generated defect was automatically passed, while two normal cases were safely routed for review.



The anomaly map also lets us compare predicted hotspot pixels with the generated defect mask. In a factory evaluation, localization quality is useful for operator trust and root-cause analysis, but a visually plausible heatmap is not proof that the model learned the right causal feature.




Step 6: Test the normal and failure paths



Run the complete test suite:



python -m pytest


The tests verify:


  • the review band is non-empty;


  • a normal demo part passes;


  • a defective part is escalated and localized;


  • the held-out evaluation contains no synthetic false accepts;


  • health, readiness, success, and unknown-sample API behavior.


The unknown-sample test matters. Production services must fail explicitly rather than silently scoring the wrong or missing image.





Step 7: Serve the model through FastAPI



Set the source path and start Uvicorn:



$env:PYTHONPATH="src"
uvicorn factory_vision.api:app --host 0.0.0.0 --port 8080


Then verify readiness:



curl http://localhost:8080/readyz


Expected structure:



{
  "status": "ready",
  "model": "normal-appearance-zscore-v1",
  "demo_samples": 3
}


Inspect a sample:



curl -X POST http://localhost:8080/v1/inspect \
  -H "Content-Type: application/json" \
  -d '{"sample_id":"test-defect-000"}'


Use test-normal-001, test-defect-000, or test-defect-001. The tutorial endpoint intentionally accepts an allow-listed demo ID. A production API would accept an authenticated object reference or image payload, validate size and encoding, enforce timeouts, and retain a traceable content hash.





Step 8: Build a production-conscious container



Train the artifact first, then build:



docker build -t factory-vision:1.0.0 .
docker run --rm -p 8080:8080 factory-vision:1.0.0


The Dockerfile uses a multi-stage Python image, copies a virtual environment into the runtime stage, runs as UID/GID 10001, exposes only port 8080, and includes a health check. In a delivery pipeline, also generate an SBOM, scan dependencies and the image, sign the image, pin it by digest, and promote the same digest across environments.





Step 9: Add CI without retraining on production data



The GitHub Actions workflow performs:



checkout → install → generate tutorial data → train → evaluate → test → docker build


This is suitable for a public reproducible sample. In production, large or sensitive data should stay in governed storage; CI should reference an immutable dataset version and usually validate or package a previously approved model artifact instead of training from mutable operational data on every commit.



Step 10: Design the real factory integration



A production path usually adds the following components:



Image acquisition gate



Validate trigger timing, pose, field of view, blur, saturation, illumination, occlusion, and expected part identity before inference. Route invalid captures to recapture or review; do not treat them as normal.



Traceability



Persist the inspection ID, part or batch ID, image hash, capture configuration, preprocessing version, model version, threshold-policy version, score, decision, latency, and operator disposition.



Human review



Show the original image and bounded anomaly overlay, require a structured reason code, and feed confirmed outcomes into a governed dataset—not directly into an online model.



Monitoring



Monitor input-quality failures, score distributions, review rate, confirmed escapes, false rejects, per-line segments, latency, queue depth, and resource saturation. Drift is an investigation signal, not an automatic retraining command.



Release safety



Shadow new models on live traffic, compare them with the approved version, apply segment-specific acceptance criteria, use canary rollout where the system architecture permits, and keep a tested rollback path. Follow a risk-management framework such as the NIST AI Risk Management Framework.





Common mistakes



Optimizing only overall accuracy


A 99% score can hide rare but costly defect escapes. Report defect-family recall, false-accept rate, false-reject rate, review load, and confidence intervals by production segment.



Training on uncontrolled images


More images do not compensate for unstable optics. Camera, lens, fixture, and illumination are part of the ML system.



Removing the review band to improve throughput


This transfers uncertainty into silent errors. First measure review causes, improve data or acquisition, and change thresholds through an approved process.



Treating a heatmap as an explanation


A hotspot is a diagnostic aid. Validate it against masks, interventions, known confounders, and operator feedback.



Connecting the demo directly to a PLC


Do not use this sample as a safety control. Define fail-safe states and validate the entire controls chain with responsible engineering teams.





Where to take the project next


  1. Replace the synthetic generator with an approved MVTec AD category or a governed plant dataset.


  2. Add image-quality and alignment models.


  3. Compare the baseline with pretrained feature embeddings and a segmentation method.


  4. Add dataset and model registries, signed artifacts, and staged promotion.


  5. Build a reviewer UI and measure reviewer agreement.


  6. Run line-by-line and time-based validation before any operational action.





How Codersarts can help

Codersarts can help manufacturing and product teams scope an inspection use case, design a data-collection study, build computer-vision baselines, establish production evaluation, implement MLOps and monitoring, and provide dedicated AI engineering expertise. The engagement can begin as a feasibility assessment and progress to a governed pilot without presenting a model demo as production readiness.




Product

Link

Description

Codersarts

Coding and mentorship platform

Build

Build SaaS, MVPs, and products

Labs

Product development and solutions

AI

AI solutions and development

Dev

Developer tutorials and resources





References



 
 
 

Comments


bottom of page