Pipeline Overview¶
The detection pipeline is a chain of composable stages that convert an input circuit schematic image into a list of detected line segments. Each stage is independently benchmarkable and swappable.
How It Works¶
- A
Pipelineis constructed from a list ofPipelineStageinstances pipeline.run(image, params)executes stages sequentially, passing intermediate results- Each stage's output is collected for visualization
- The final result contains detected lines, per-stage outputs, and timing
PipelineFactory¶
Pipelines are built from config dicts or YAML via PipelineFactory:
from wire_detection.pipeline.factory import PipelineFactory
pipeline = PipelineFactory.from_config({
"stages": ["crop", "mask", "threshold", "invert", "dilate",
"ccl", "contour_extract", "dedup", "length_filter"],
"crop": {"padding": 10},
"threshold": {"mode": "otsu"},
"dilate": {"kernel_size": 5, "iterations": 1},
"ccl": {"min_area": 30},
"dedup": {"angle": 10, "dist": 12},
"length_filter": {"min_length": 20},
})
result = pipeline.run(image)
Default Pipeline¶
The 9-stage pipeline, executed in order:
| # | Stage | Purpose |
|---|---|---|
| 1 | crop |
Crop to component bounding box region with padding |
| 2 | mask |
Fill component polygons with white (occlude wires behind components) |
| 3 | threshold |
Convert grayscale to binary (Otsu, manual, or adaptive) |
| 4 | invert |
Bitwise NOT so wires become white on black |
| 5 | dilate |
Morphological dilation to thicken thin wires |
| 6 | ccl |
Connected component labeling, filter by minimum area |
| 7 | contour_extract |
Extract one line segment per blob (farthest contour extremes) |
| 8 | dedup |
Merge collinear/overlapping lines by angle + distance threshold |
| 9 | length_filter |
Remove lines shorter than minimum length |
Config-Driven¶
Every aspect of the pipeline is configurable:
# config/sweeps.yaml
baseline:
stages:
- threshold
- invert
- dilate
- ccl
- contour_extract
- dedup
- length_filter
threshold:
mode: otsu
dilate:
kernel_size: 5
iterations: 1
ccl:
min_area: 30
dedup:
angle: 10
dist: 12
length_filter:
min_length: 20
Result Type¶
class PipelineResult(TypedDict):
lines: list[Line] # Final detected lines
raw_lines: list[Line] # Lines before dedup/filter
blob_count: int
stage_outputs: dict[str, np.ndarray] # Intermediate images
params_used: dict
elapsed_ms: float
Plugin Architecture¶
New stages and backends can be registered without modifying framework code: