Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PCB Electronic Component Detection (YOLO26 · RF-DETR)

Object detection for electronic components on printed circuit boards — capacitors, resistors, ICs, diodes, LEDs, connectors and friends — trained on merged public PCB datasets and benchmarked on Apple Silicon.

Undergraduate project at RMUTT (Rajamangala University of Technology Thanyaburi).

Most of the inline documentation in the scripts is written in Thai. เอกสารในสคริปต์ส่วนใหญ่เขียนเป็นภาษาไทย


What's in here

This is a research repo, not a library. Alongside the training pipelines it carries the tooling built to answer specific questions about the data and the hardware:

Area Scripts
Training src/train_smd.py, src/train_pcb2.py, src/train_merged*.py, train_t7.py, train_filtered.py, train_mlx.py
RF-DETR comparison src/train_merged_T6_rfdetr.py, notebooks/train_merged_T6_rfdetr_colab.ipynb
Dataset merging src/merge_datasets.py, merge_datasets_v2.py, merge_datasets_v3.py
Data leakage group_split.py
Duplicate detection find_duplicates.py, dup_lab.py, dataset_checker_gui.py
Preprocessing research apply_fpic_filter.py, ab_filter_experiment.py, filter_lab.py, make_variants.py
Backend benchmark benchmark_backends.pybench_out.txt, bench_results.json
Inference GUIs src/detect_gui.py, src/detect_viewer.py, src/preview_detect.py
Label Studio label_config.xml, make_ls_preview.py, ndjson_clone_gui.py, fix_polygon_labels.py
Live dashboard training-dashboard/ (Next.js + Recharts)

Datasets

Two Roboflow exports form the base, later merged with four more sources into merged_T6:

Config Classes Notes
data_smd_absolute.yaml 8 CAPACITOR DIODE EC IC LED RESISTOR SCAPACITOR ZENER
data_pcb2_absolute.yaml 23 Superset taxonomy — adds Connector, Ferrite Bead, Test Point, Transistor, jumpers …
data_merged_absolute.yaml 18 The merged_V1 label space
merged_T6 16 Six sources: smd · i2 · pccomp · pcbdetv2 · compdetect · pcbcomp

merged_T6 classes: IC LED battery buzzer capacitor clock connector diode display fuse inductor potentiometer relay resistor switch transistor

Base export: PCB Electronic components (CC BY 4.0) — 5,363 images, YOLO26 format, resized 640×640 with grayscale CRT-phosphor preprocessing and 3 augmented versions per source image.

Dataset directories and runs/ weights are not committed — the data_*.yaml files hold absolute paths and need rewriting for your machine.


Three findings worth reading the code for

1. Board-level data leakage was inflating mAP

merged_T6 stitches together six sources that photograph the same physical boards. Splitting train/valid/test per image scattered one board across all three splits:

images in valid whose board also appears in train ....  55.5%
images in test  whose board also appears in train ....  65.9%

The model was being scored on boards it had already memorised. group_split.py regroups the split by board identity so the reported numbers mean something.

2. The FPIC preprocessing filter, measured instead of assumed

PCBSegClassNet (Table VII) reports large IoU gains from an HSI + CLAHE colour transform — but for their segmentation network, at 512×512, on their data. Different architecture, different task, different dataset.

apply_fpic_filter.py reproduces their filter chain exactly (BGR→HLS, CLAHE clip_limit=4.0, tile 8×8), make_variants.py builds four matched dataset variants (rgb / clahe-only / hsi / fpic), and ab_filter_experiment.py runs the A/B on YOLO directly rather than assuming the gain transfers. filter_lab.py is a live GUI for sweeping the parameters the paper never specifies.

3. MLX is not faster than MPS above nano scale

yolo-mlx advertises 2.07× inference and 2.65× training over PyTorch MPS — but measured on an M4 Pro against COCO, which is neither this machine nor this dataset. benchmark_backends.py re-measures it here (imgsz=640, nc=16, compile/fuse on):

Inference — batch=1, median ms (FPS)

scale MLX MPS CPU MLX/MPS
n 3.3 (300) 4.2 (240) 38.5 (26) 1.25×
m 15.5 (64) 15.3 (65) 169.6 (6) 0.98×
l 20.0 (50) 19.1 (52) 213.7 (5) 0.96×
x 40.4 (25) 35.6 (28) 351.6 (3) 0.88×

Training step — batch=2, median ms (img/s), network fwd+bwd+optimizer only

scale MLX MPS CPU MLX/MPS
n 48 (41.3) 45 (44.2) 292 (6.8) 0.93×
m 207 (9.7) 163 (12.2) 1421 (1.4) 0.79×
l 257 (7.8) 193 (10.4) 1698 (1.2) 0.75×
x 441 (4.5) 379 (5.3) 2857 (0.7) 0.86×

MLX only wins at n. From m upward MPS is ahead, and the gap widens with scale.

The benchmark also pins down the classic measurement trap — not waiting for the GPU:

scale backend real (synced) fake (no sync)
m MLX 15.5 ms 0.1 ms — 105× too fast
x MLX 40.4 ms 0.3 ms — 132× too fast
x MPS 35.6 ms 25.9 ms

Lazy MLX evaluation means an unsynced timer measures queueing, not compute.


Setup

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

requirements.txt: ultralytics · PyQt5 · opencv-python · numpy · reportlab · PyYAML

Extras installed per experiment: rfdetr[train] for the RF-DETR pipeline, yolo-mlx for the MLX backend (setup_mlx.sh).

Training targets device='mps' (Apple Silicon) throughout.

Running

source .venv/bin/activate

# 1. SMD model — trains from scratch
python src/train_smd.py

# 2. PCB2 model — fine-tunes from the SMD output, so run step 1 first
python src/train_pcb2.py

# 3. Merged model
python src/merge_datasets.py
python src/train_merged.py

# resume an interrupted run
python src/resume_train_smd.py    # or resume_train_pcb2.py / resume_train_merged.py

Each resume_train_*.py loads that pipeline's last.pt and calls model.train(resume=True) — for continuing an interrupted run, not extending a finished one.

Inference GUI

python src/detect_gui.py

PyQt5 viewer with debounced confidence/IoU sliders, per-class toggles that re-filter without re-running inference, a confidence-sorted detection list, scroll-zoom and drag-pan, live camera inference, and saving annotated frames.

Training dashboard

cd training-dashboard
npm install
npm run dev          # http://localhost:3000

Next.js 14 + Recharts monitor that compares the v1 / T5 / T6 runs side by side and refreshes every 10 seconds.


Related

License

No license file yet. The Roboflow base dataset is CC BY 4.0.

About

YOLO26 / RF-DETR object detection for electronic components on printed circuit boards — dataset merging, board-level split leakage analysis, FPIC preprocessing A/B, and an MLX vs MPS benchmark on Apple Silicon. RMUTT project.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages