Building an Automated Visual Inspection System with NVIDIA Jetson and YOLOv8

Visual inspection is one of the most common — and most expensive — tasks in manufacturing. Humans get tired, miss defects, and cost money per hour. An AI vision system running on NVIDIA Jetson runs 24/7, never blinks, and can inspect hundreds of products per minute with consistent accuracy. This guide shows you how to build one.

What can AI visual inspection detect?

  • Surface defects: scratches, dents, cracks, discolouration, contamination
  • Assembly errors: missing components, misaligned parts, wrong orientation
  • Dimensional deviations: parts outside tolerance using calibrated measurement
  • Label and print quality: missing labels, misprints, barcode failures
  • Packaging integrity: seal failures, incorrect fill levels, damaged packaging

System architecture overview

A complete inspection system has four components working together:

  • Camera: captures high-resolution images of each product as it passes
  • Lighting: consistent, controlled illumination to eliminate shadows and reflections
  • Jetson AI board: runs the YOLOv8 model and makes pass/fail decisions in real time
  • Actuator: a relay, air jet, or robotic arm that rejects failed products automatically

Step 1 — Collect training data

A custom inspection model needs images of your specific product. Aim for at least 200–500 images of each defect class, captured under the same lighting and camera angle you will use in production.

Tools to annotate your dataset:

  • Roboflow — browser-based annotation, free tier available
  • Label Studio — open source, self-hosted
  • CVAT — open source from Intel, excellent for bounding boxes

Step 2 — Train your YOLOv8 model

from ultralytics import YOLO

model = YOLO("yolov8s.pt")   # start from small pretrained model

model.train(
    data   = "inspection_dataset/data.yaml",
    epochs = 150,
    imgsz  = 640,
    batch  = 16,
    device = 0,
    # Augmentation — critical for robust inspection models
    hsv_h  = 0.01,   # minimal colour shift (lighting is controlled)
    hsv_s  = 0.3,
    fliplr = 0.5,    # horizontal flip for symmetrical products
    degrees= 5       # small rotation for slight misalignment
)

print(f"Best mAP: {model.metrics.box.map}")

Step 3 — Export and deploy to Jetson

# On your training machine (GPU)
model.export(format="engine", half=True, imgsz=640)

# Copy to Jetson
# scp runs/detect/train/weights/best.engine user@jetson-ip:/home/user/models/

Step 4 — Build the inspection loop with GPIO rejection

from ultralytics import YOLO
import cv2, Jetson.GPIO as GPIO, time

REJECT_PIN   = 18          # GPIO pin connected to rejection actuator
CONFIDENCE   = 0.75        # minimum confidence to flag as defect
DEFECT_CLASS = 0           # class index for "defect" in your dataset

GPIO.setmode(GPIO.BOARD)
GPIO.setup(REJECT_PIN, GPIO.OUT, initial=GPIO.LOW)

model = YOLO("models/inspection_best.engine", task="detect")
cap   = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()
    if not ret: break

    results = model(frame, verbose=False)
    defect_found = False

    for box in results[0].boxes:
        if int(box.cls) == DEFECT_CLASS and float(box.conf) > CONFIDENCE:
            defect_found = True
            # Draw red box on defect
            x1,y1,x2,y2 = map(int, box.xyxy[0])
            cv2.rectangle(frame, (x1,y1), (x2,y2), (0,0,255), 3)
            cv2.putText(frame, f"DEFECT {float(box.conf):.2f}",
                        (x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0,0,255), 2)

    if defect_found:
        GPIO.output(REJECT_PIN, GPIO.HIGH)   # trigger rejection
        time.sleep(0.1)
        GPIO.output(REJECT_PIN, GPIO.LOW)

    cv2.imshow("Inspection System", frame)
    if cv2.waitKey(1) & 0xFF == ord('q'): break

Step 5 — Add logging and statistics

A production system needs to log every inspection for quality records and continuous improvement:

import influxdb_client, datetime

client = influxdb_client.InfluxDBClient(url="http://localhost:8086", token="your-token")
write_api = client.write_api()

def log_inspection(result, defect_found, confidence):
    point = influxdb_client.Point("inspection")         .field("pass", not defect_found)         .field("defect_confidence", float(confidence))         .time(datetime.datetime.utcnow())
    write_api.write(bucket="quality", record=point)

Real-world performance targets

MetricTargetAchievable on Jetson Orin + YOLOv8s
Inspection speed> 30 parts/min✅ 55+ FPS continuous
Defect detection rate> 98%✅ Achievable with good training data
False positive rate< 1%✅ Tune confidence threshold
Latency to rejection< 50ms✅ ~15ms inference + GPIO

The HemiHex Jetson Inspection Kit is a production-ready platform for exactly this application — hardware, JetPack, camera interface, and GPIO all included. Get the kit →

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top
0

Subtotal