--- license: mit tags: - object-detection - pcb-defect-detection - yolov8 - industrial-inspection - domain-generalization - gerber - automated-optical-inspection datasets: - norbertelter/pcb-defect-dataset metrics: - map library_name: ultralytics pipeline_tag: object-detection --- # GerberFormer: Design-Conditioned PCB Defect Detection ## TL;DR Image-only PCB defect detectors fail catastrophically on unseen board families (mAP@50: **0.06**). Adding a synthetic Gerber prior closes this gap completely (mAP@50: **0.99**) with zero inference overhead. ## Model Description GerberFormer addresses a fundamental weakness in automated optical inspection (AOI): standard detectors memorize the visual appearance of specific PCB board families rather than learning what defects fundamentally are. When deployed on a new board family never seen during training, performance collapses. Our solution: blend a synthetic design prior (derived from median board images using CLAHE enhancement and adaptive thresholding) into the input image at a controlled strength alpha=0.25. This gives the model structural context about what the board should look like, enabling it to detect deviations regardless of board identity. ## Key Results | Model | Seen Boards mAP@50 | Unseen Boards mAP@50 | |-------|--------------------|----------------------| | YOLOv8s image-only (baseline) | 0.9924 | 0.0588 | | YOLOv8s + Gerber alpha=0.10 | 0.9902 | 0.9890 | | **YOLOv8s + Gerber alpha=0.25 (ours)** | **0.9916** | **0.9928** | | YOLOv8s + Gerber alpha=0.50 | 0.9817 | 0.9821 | The generalization gap closes from 0.934 to 0.001. ## Per-Class Performance (Test Set) | Defect Class | Baseline AP@50 | Gerber AP@50 | |--------------|----------------|--------------| | missing_hole | 0.9943 | 0.9937 | | mouse_bite | 0.9949 | 0.9949 | | open_circuit | 0.9941 | 0.9937 | | short | 0.9923 | 0.9901 | | spurious_copper | 0.9950 | 0.9950 | | spur | 0.9871 | 0.9908 | ## Inference Speed No overhead from Gerber conditioning. | Model | Preprocess | Inference | Total | |-------|-----------|-----------|-------| | Baseline | 0.96ms | 1.44ms | 3.39ms | | Gerber (ours) | 0.79ms | 1.26ms | 2.87ms | ## Models in this Repository | File | Description | Val mAP@50 | |------|-------------|------------| | `yolov8_baseline.pt` | YOLOv8s image-only baseline, 100 epochs | 0.992 | | `yolov8_gerber_alpha025.pt` | Main model, Gerber fusion alpha=0.25, 100 epochs | 0.992 | | `yolov8_gerber_alpha010.pt` | Ablation, Gerber fusion alpha=0.10, 50 epochs | 0.992 | | `yolov8_gerber_alpha050.pt` | Ablation, Gerber fusion alpha=0.50, 50 epochs | 0.981 | ## Usage ### Quick Start ```python from huggingface_hub import hf_hub_download from ultralytics import YOLO path = hf_hub_download( repo_id = "pulipakav-1/gerberformer", filename = "yolov8_gerber_alpha025.pt" ) model = YOLO(path) results = model.predict("your_pcb_image.jpg", conf=0.3) results[0].show() ``` ### With Gerber Prior (recommended for unseen boards) ```python from huggingface_hub import hf_hub_download from ultralytics import YOLO import cv2, numpy as np model_path = hf_hub_download( repo_id = "pulipakav-1/gerberformer", filename = "yolov8_gerber_alpha025.pt" ) # Load your board image and prior img = cv2.imread("your_pcb_image.jpg") img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img = cv2.resize(img, (640, 640)) prior = cv2.imread("your_board_prior.png") prior = cv2.cvtColor(prior, cv2.COLOR_BGR2RGB) prior = cv2.resize(prior, (640, 640)) # Blend with alpha=0.25 fused = cv2.addWeighted( img.astype(np.float32), 0.75, prior.astype(np.float32), 0.25, 0 ).astype(np.uint8) cv2.imwrite("fused_input.jpg", cv2.cvtColor(fused, cv2.COLOR_RGB2BGR)) # Inference model = YOLO(model_path) results = model.predict("fused_input.jpg", conf=0.3) results[0].show() ``` ### Build Your Own Gerber Prior ```python import cv2, numpy as np from pathlib import Path def build_gerber_prior(image_dir, n_samples=100, img_size=640): images = sorted(Path(image_dir).glob("*.jpg"))[:n_samples] stack = [] for p in images: img = cv2.imread(str(p)) img = cv2.resize(img, (img_size, img_size)) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) stack.append(img.astype(np.float32)) median = np.median(np.stack(stack), axis=0).astype(np.uint8) gray = cv2.cvtColor(median, cv2.COLOR_RGB2GRAY) clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8)) enhanced = clahe.apply(gray) adaptive = cv2.adaptiveThreshold( enhanced, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 21, 5) sobelx = cv2.Sobel(enhanced, cv2.CV_64F, 1, 0, ksize=3) sobely = cv2.Sobel(enhanced, cv2.CV_64F, 0, 1, ksize=3) gradient = np.sqrt(sobelx**2 + sobely**2) gradient = cv2.normalize(gradient, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8) return np.stack([enhanced, adaptive, gradient], axis=-1) prior = build_gerber_prior("path/to/your_board_images/") cv2.imwrite("my_board_prior.png", prior) ``` ## Dataset PKU PCB Defect Dataset - 10,664 images (8,534 train / 1,066 val / 1,068 test) - 6 defect classes: missing_hole, mouse_bite, open_circuit, short, spurious_copper, spur - 13 board families: l_light, light_01-12, rotation_90, rotation_270 - Download: https://www.kaggle.com/datasets/norbertelter/pcb-defect-dataset ## Reproduce from Scratch ```bash git clone https://github.com/pulipakav-1/gerberformer cd gerberformer pip install -r requirements.txt kaggle datasets download -d norbertelter/pcb-defect-dataset unzip pcb-defect-dataset.zip -d pcb-defect-dataset python priors/build_priors.py python priors/build_fused_dataset.py python training/train_gerber.py python evaluation/evaluate_per_family.py \ --model experiments/gerber_alpha025/weights/best.pt \ --imgdir pcb-fused-dataset/test/images \ --lbldir pcb-defect-dataset/test/labels ``` ## Limitations 1. Requires multiple training images from the same board family to build a reliable prior 2. Uses appearance-based priors rather than true Gerber CAD files 3. Alpha blending is a simple fusion — learned fusion could do better 4. Prior quality degrades for board families with very few training images ## Future Work - Replace synthetic priors with real Gerber file rendering - Implement learned cross-modal fusion via cross-attention - Extend to multi-layer PCB inspection - Deploy with ONNX/TensorRT for real-time AOI ## Links - Code: https://github.com/pulipakav-1/gerberformer - Results and figures: https://huggingface.co/datasets/pulipakav-1/gerberformer-results ## Citation ```bibtex @article{gerberformer2025, title={Design-Conditioned PCB Defect Detection via Synthetic Gerber Priors}, author={Venkata Naga Sai Vishnu Rohit Pulipaka}, journal={Under Review}, year={2025} } ``` ## License MIT