Content
# Circuit Recognition MCP
> An intelligent circuit diagram recognition system based on MCP (Model Context Protocol) - Input circuit diagram images, output structured JSON (components, text annotations, topological connections, netlist).
[](https://www.python.org/)
[](LICENSE)
## Why This Project
There are hardly any directly usable circuit diagram recognition tools available online. Existing OCR engines do not recognize circuit symbols, and YOLO detection does not have pre-trained models specifically for circuit components, with very limited training data available - circuit diagrams involve copyright issues, and publicly available datasets are scarce.
To automate circuit simulation, I started from scratch:
1. **Collected multiple public datasets** (CGHD, HCD, etc.) and synthesized a batch of textbook-style circuit diagrams
2. **Trained a YOLO model**, through multiple iterations from v1 to v3, expanding from 8 classes to 10 classes, generalizing from synthetic images to hand-drawn/photos
3. **Built a complete pipeline**: YOLO detection → SAM segmentation → OCR text recognition → topological analysis → fusion output
Open-sourced to save others from repeating the same work. Can be used out-of-the-box, or fine-tuned on top of the pre-trained models.
## What Can Be Recognized
### Supported Circuit Types
- 📖 **Textbook/Circuit Diagrams** (main focus, most training data)
- ✏️ **Hand-Drawn Circuit Diagrams** (trained on CGHD dataset)
- 📐 **Schematics/Diagrams** (trained on HCD dataset)
- 📸 **Physical Photos** (partial support, depends on clarity)
### Supported Components (10 classes)
| Component | English Class Name | Example |
|------|--------------------|------|
| Resistor | `resistor` | R1, R2... |
| Capacitor | `capacitor` | C1, C2... |
| Inductor | `inductor` | L1, L2... |
| Diode | `diode` | D1, D2... |
| Transistor | `transistor` | Q1, Q2... |
| Operational Amplifier | `opamp` | U1, U2... |
| Integrated Circuit | `ic` | U1, U2... |
| Ground | `ground` | GND |
| Voltage Source | `voltage_source` | VCC, VDD |
| Current Source | `current_source` | I1, I2... |
## Training Data Sources
The model was trained using the following datasets, and I would like to thank the creators:
| Dataset | Scale | Type | Source |
|--------|------|------|------|
| **CGHD** (Circuit Graphic Hand-Drawn) | ~1,152 images | Hand-drawn circuit diagrams | [Zenodo public dataset](https://zenodo.org/) |
| **HCD** (Hand-drawn Circuit Diagram) | ~200 images | Hand-drawn schematics | Public academic dataset |
| **Self-synthesized textbook data** | ~5,000 images | SchemDraw auto-generated | Generated by this project |
Training process: Start with self-synthesized data (large quantity, accurate annotation), then mix in hand-drawn datasets for generalization. The final model performs well on both textbook and hand-drawn images.
> Training code and dataset are not included in the repository due to large size (~20 GB). If you need the training data or want to train your own model, please raise an issue, and I can share the dataset preparation script.
## Quick Start
### 1. Environment Preparation
```bash
git clone https://github.com/HR-DONK/circuit-recognition.git
cd circuit-recognition
# Install dependencies
pip install -r requirements.txt
```
### 2. Model Download
| Model | Size | Purpose | Method |
|------|------|--------|------|
| `circuit_yolov8n_v3.pt` | 16 MB | 10-class component detection | Built-in |
| `sam_vit_b_01ec64.pth` | 358 MB | Fine-grained segmentation | **Auto-download on first run** |
The SAM model will be automatically downloaded from Facebook to the `models/` directory on first use.
### 3. Using as an MCP Tool
Add the following configuration to the MCP settings in Claude Code / Claude Desktop:
```json
{
"mcpServers": {
"circuit-recognition": {
"command": "python",
"args": ["src/mcp_server.py"],
"cwd": "/path/to/circuit-recognition"
}
}
}
```
4 available tools:
| Tool | Function |
|------|------|
| `analyze_circuit` | Full-flow analysis: detection + segmentation + OCR + topology + netlist |
| `detect_components` | Quick component detection (only YOLO) |
| `recognize_text` | Text recognition (only OCR) |
| `get_cache_status` | Query cache status |
### 4. Output Example
```json
{
"success": true,
"components": [
{ "class": "resistor", "bbox": [120, 80, 60, 20], "confidence": 0.92 },
{ "class": "capacitor", "bbox": [120, 160, 40, 30], "confidence": 0.88 }
],
"connections": [
{ "from": "R1.pin2", "to": "C1.pin1", "wire_segments": [...] }
],
"nets": {
"VCC": ["R1.pin1"],
"GND": ["C1.pin2", "R2.pin1"],
"NET_1": ["R1.pin2", "C1.pin1"]
},
"title_block": { "title": "RC Filter Circuit" },
"timing": {
"yolo": 0.12, "ocr": 1.68, "total": 2.34
}
}
```
## Pipeline Architecture
```
Input Image → YOLO Component Detection → SAM Fine-grained Segmentation → OCR Text Recognition → Topological Analysis → Fusion Output
0.1s 0.1s on-demand 1.7s 0.2s JSON
```
```
circuit-recognition/
├── src/
│ ├── mcp_server.py # MCP server entry (4 tools)
│ ├── pipeline/
│ │ ├── yolo_detector.py # Stage 1: YOLO component detection
│ │ ├── sam_segmentor.py # Stage 2: SAM fine-grained segmentation
│ │ ├── ocr_engine.py # Stage 3: OCR engine (orchestration layer)
│ │ ├── smart_filter.py # Multi-level text box filtering (size/conf/NMS/ROI/margin)
│ │ ├── backends/
│ │ │ ├── base.py # OCR backend abstract base class
│ │ │ ├── rapidocr_backend.py # RapidOCR backend (default, CPU available)
│ │ │ └── trt_backend.py # TensorRT backend (GPU acceleration)
│ │ ├── topology.py # Stage 4: Topological analysis
│ │ ├── fusion.py # Stage 5: Fusion + netlist generation
│ │ └── preprocessor.py # Image preprocessing + PDF conversion
│ └── cache.py # Multi-level cache
├── config/
│ └── ocr_config.yaml # OCR parameter configuration
├── scripts/
│ └── build_trt_engines.py # TensorRT engine building (requires GPU)
├── tests/ # 38 tests
├── models/ # Model files (auto-download)
└── requirements.txt
```
## Replacing the OCR Engine
The OCR module uses a **pluggable backend architecture**. By default, it uses RapidOCR (ONNX Runtime, CPU available), which can be seamlessly replaced with other OCR engines:
Implement the `OcrBackendBase` abstract class:
```python
from src.pipeline.backends.base import OcrBackendBase
import numpy as np
class MyOcrBackend(OcrBackendBase):
"""Integrate your OCR engine"""
def initialize(self) -> None:
pass # Initialize your OCR model
def release(self) -> None:
pass # Release resources
@property
def is_available(self) -> bool:
return True
def detect(self, image: np.ndarray) -> dict:
# Text region detection
# Return {"boxes": [...], "scores": [...], "cost_sec": 0.0, "img_hw": (h, w)}
pass
def recognize_batch(self, image: np.ndarray, boxes: list) -> list:
# Batch text recognition
# Return [{"text": "...", "confidence": 0.95, "bbox": [x,y,w,h]}, ...]
pass
```
Then register in `ocr_engine.py` and switch in `config/ocr_config.yaml`:
```yaml
backend:
default: myocr
```
**No need to modify `mcp_server.py` or any upper-level code.** Supports integration with: PaddleOCR, Tesseract, EasyOCR, Azure OCR, or any engine you prefer.
## Performance
| Configuration | OCR Time | Note |
|------|---------|------|
| RapidOCR (default) | ~1.7s/page | CPU available, SmartFilter filters irrelevant text |
| RapidOCR + TensorRT rec | ~0.3-0.5s/page | Requires NVIDIA GPU + TensorRT |
| Original RapidOCR (before optimization) | ~2.5s/page | Recognize each box, no filtering |
## Dependencies
```
Python 3.10+
├── torch + ultralytics # YOLO inference
├── segment-anything # SAM segmentation
├── rapidocr-onnxruntime # OCR (default backend)
├── opencv-python-headless # Image processing
├── PyMuPDF # PDF support
└── mcp # MCP protocol framework
```
See [requirements.txt](requirements.txt) for details.
## License
MIT © He Rui