Automated extraction of structured data from electrical circuit diagrams into machine-readable relational graphs.
Circuit Extract takes single-line diagrams, substation schematics, and power distribution drawings as input -- in any format from CAD source files to photos of paper drawings -- and produces a structured JSON/CSV graph of every component, connection, and substation in the diagram. Built for digital twin construction, asset inventory reconciliation, and power systems analysis.
circuit-extract
DXF / PDF / PNG / JPG ------> [ OCR + Vision AI + CV ] ------> JSON Graph
+ Review Queue
- Multi-format ingestion -- AutoCAD DXF (parsed directly via ezdxf), PDF (vector-aware rasterization), and raster images (PNG/JPG/TIFF/BMP)
- Hybrid AI pipeline -- PaddleOCR for text extraction, Gemini/Claude Vision for symbol detection, OpenCV for wire tracing
- Spatial graph construction -- KD-tree nearest-neighbor matching snaps detected symbols to wire endpoints with configurable tolerance
- Intelligent tiling -- Large diagrams (>4000px) are automatically split into overlapping tiles, processed independently, and merged with spatial deduplication
- Bus bar detection -- Dual detection via vision model + geometric heuristic (aspect ratio), represented as star-topology nodes
- Cross-sheet stitching -- Detects reference patterns (
SEE SHEET N,>>LABEL) via OCR and creates inferred connections across sheets - Confidence scoring -- Every extracted entity carries a confidence score with full provenance tracking back to source coordinates and extraction method
- Review queue -- Low-confidence detections, ambiguous overlaps, and inventory mismatches are automatically flagged for human review
- Inventory cross-validation -- Fuzzy-match extracted components against customer inventory CSV/Excel to catch phantom detections and missing equipment
- SPICE schematic workflow -- Separate pipeline for analog circuit schematics: netlist parsing, normalization, topology-aware benchmarking
Input File
|
v
[Ingest] ---- DXF: ezdxf block/entity parsing (ground truth, confidence=1.0)
| |-- PDF: PyMuPDF rasterization at configurable DPI
| '-- Raster: PIL image loading
v
[Preprocess] - Deskew (Hough angle estimation)
| Denoise (Non-local means)
| Binarize (Adaptive threshold)
| Tile splitting (configurable grid + overlap)
v
[OCR] -------- PaddleOCR v5 (78 text annotations on sample diagram)
v
[Detection] -- Gemini 2.5 Flash / Claude Vision (129 symbols detected)
| Zero-temperature, defensive prompting, schema validation
| Confidence floor filtering (>0.3)
v
[Lines] ------ OpenCV Canny + HoughLinesP (791 wire segments detected)
v
[Graph] ------ scipy KD-tree spatial matching
| Snap tolerance with distance-decay confidence
| Bus bar star-topology construction
| Substation boundary inference
v
[Tile Merge] - Overlap deduplication (spatial + fuzzy name matching)
| Cross-sheet reference stitching
| Confidence combination: 1-(1-c1)(1-c2)
v
[Validation] - Inventory fuzzy match (Levenshtein)
| Telemetry ID cross-check
v
[Review] ----- Flag low-confidence entities
| Flag inventory mismatches
| Flag ambiguous overlaps
v
[Export] ------ JSON structured graph + flat tables
# Clone and install
git clone https://github.com/yashpatil582/circuit-extract.git
cd circuit-extract
pip install -e ".[dev]"
# For Claude Vision support
pip install -e ".[claude]"# From a PDF
circuit-extract extract diagram.pdf --output-dir ./output
# From a DXF (CAD)
circuit-extract extract schematic.dxf --output-dir ./output
# From a raster image
circuit-extract extract photo.png --output-dir ./output
# With inventory cross-validation
circuit-extract extract diagram.pdf --output-dir ./output \
--inventory assets.csv \
--telemetry telemetry_ids.txtThe pipeline produces:
| File | Description |
|---|---|
structured_graph.json |
Flat graph with components array and connectors with endpoint references |
extraction_result.json |
Full pipeline output with provenance and raw LLM responses |
components.json |
Component table (type, name, rating, confidence, bounding box) |
connections.json |
Connection table (from/to component IDs, type, confidence) |
substations.json |
Substation groupings |
review_queue.json |
Items flagged for human review |
errors.json |
Non-fatal errors encountered during processing |
From a data center power supply single-line diagram:
{
"summary": {
"substations": 1,
"components": 129,
"connections": 5,
"review_items": 5,
"errors": 0
},
"components": [
{
"component_type": "generator",
"name": "GEN 1",
"confidence": 0.99,
"provenance": {
"source_type": "raster_pdf",
"extraction_method": "gemini_vision"
}
},
{
"component_type": "panel",
"name": "Generator Terminal Electrical Cabinet A1",
"confidence": 0.99
},
{
"component_type": "ups",
"name": "UPS 1",
"confidence": 0.99
}
]
}A separate pipeline for analog circuit schematics with SPICE netlist processing:
# Prepare PDFs/images into a flat PNG dataset
circuit-extract schematic prepare ./schematics --output-dir ./prepared --dpi 300
# Normalize SPICE netlists (.sp, .cir, .ckt, .net) to canonical form
circuit-extract schematic normalize ./netlists --output-dir ./normalized
# Benchmark predicted netlists against expected (topology-aware comparison)
circuit-extract schematic benchmark ./expected ./predicted --output report.json
# Run Netlistify inference on a dataset
circuit-extract schematic run-netlistify ./dataset \
--netlistify-dir /path/to/Netlistify \
--output-dir ./resultsAll pipeline parameters are configurable via TOML:
[detection]
backend = "gemini_vision" # or "claude_vision" or "yolo"
[detection.gemini_vision]
model = "gemini-2.5-flash"
temperature = 0.0
[tiling]
enabled = true
grid_cols = 6
grid_rows = 8
overlap_fraction = 0.15
min_image_dimension_for_tiling = 4000
[graph]
snap_tolerance_px = 15.0
bus_bar_aspect_ratio = 8.0
dedup_distance_px = 20.0
dedup_name_similarity = 0.85
[pipeline]
review_confidence_threshold = 0.7Use a custom config:
circuit-extract --config my_config.toml extract diagram.pdf --output-dir ./outputcircuit-extract/
src/circuit_extract/
cli.py # Click CLI
config.py # TOML config + Pydantic models
models.py # 20+ Pydantic v2 data models
pipeline.py # Orchestrator with graceful degradation
ingest/ # DXF, PDF, raster loaders
preprocess/ # Deskew, denoise, binarize, tile
ocr/ # PaddleOCR integration
detection/ # Gemini Vision, Claude Vision, YOLO backends
lines/ # OpenCV Canny + HoughLinesP
graph/ # KD-tree builder, tiling dedup, bus bar
validation/ # Inventory + telemetry cross-check
review/ # Confidence-based review queue
export/ # JSON serialization
schematic/ # SPICE parsing, netlist benchmarking
tests/ # 97 unit tests, integration + LLM markers
config/ # TOML configuration files
Every extracted entity carries full provenance:
class Component(BaseModel):
id: str # UUID
substation_id: str | None # FK -> Substation
component_type: ComponentType # transformer, circuit_breaker, bus_bar, ...
name: str | MissingField
designation: str | MissingField # e.g. "CB-101", "T1"
rating: str | MissingField # e.g. "100A", "13.8kV"
provenance: Provenance # source file, page, tile, method, raw LLM response
confidence: float # 0.0-1.0
missing_data: list[str] # fields that couldn't be extracted| Backend | Best For | Status |
|---|---|---|
| Gemini Vision | Cold-start, no training data needed | Default |
| Claude Vision | Alternative provider, high accuracy | Supported |
| YOLO | High-speed inference with training data | Planned |
All backends use defensive prompting: zero temperature, explicit "no hallucination" rules, structured JSON schema validation, confidence floor filtering, and full raw response logging for audit.
# Unit tests (fast, no external services)
pytest
# Integration tests (requires fixtures + OCR models)
pytest -m integration
# All tests
pytest -m ""97 unit tests covering models, graph construction, tiling dedup, bus bar detection, OCR parsing, vision response validation, inventory matching, and export serialization.
- Python 3.12+ with Pydantic v2 for data validation
- PaddleOCR v5 for text extraction
- Gemini / Claude Vision API for symbol detection
- OpenCV for edge detection and line tracing
- scipy KD-tree for spatial graph matching
- ezdxf for native AutoCAD DXF parsing
- PyMuPDF for PDF rasterization
- python-Levenshtein for fuzzy string matching
MIT