# RoRD: 基于 AI 的集成电路版图识别

[//]: # (徽章占位符：您可以根据需要添加构建状态、版本号等徽章)
![Python Version](https://img.shields.io/badge/Python-3.12-blue)
![License](https://img.shields.io/badge/License-Apache%202.0-orange.svg)

## ⚡ Quick Start（含合成数据与H校验）

```bash
# 一键生成→渲染→预览→H校验→写回配置（开启合成混采与 Elastic）
uv run python tools/synth_pipeline.py \
  --out_root data/synthetic \
  --num 50 \
  --dpi 600 \
  --config configs/base_config.yaml \
  --ratio 0.3 \
  --enable_elastic \
  --validate_h --validate_n 6
```

提示：zsh 下使用反斜杠续行时，确保每行末尾只有一个 `\` 且下一行不要粘连参数（避免如 `6uv` 这样的粘连）。

可选：为 KLayout 渲染指定图层配色/线宽/背景（示例：金属层绿色、过孔红色、黑底）
```bash
uv run python tools/layout2png.py \
  --in data/synthetic/gds --out data/synthetic/png --dpi 800 \
  --layermap '1/0:#00FF00,2/0:#FF0000' --line_width 2 --bgcolor '#000000'
```

## 📖 描述

本项目实现了 **RoRD (Rotation-Robust Descriptors)** 模型，这是一种先进的局部特征匹配方法，专用于集成电路（IC）版图的识别。

IC 版图在匹配时可能出现多种方向（0°、90°、180°、270° 及其镜像），RoRD 模型通过其**几何感知损失函数**和**曼哈顿结构优化**的设计，能够有效应对这一挑战。项目采用**几何结构学习**而非纹理学习的训练策略，专门针对 IC 版图的二值化、稀疏性、重复结构和曼哈顿几何特征进行了深度优化。

👉 增量报告与性能分析见：`docs/reports/Increment_Report_2025-10-20.md`

### ✨ 主要功能

* **模型实现**：基于 D2-Net 思路，使用 PyTorch 实现了适用于 IC 版图的 RoRD 模型，**专门针对几何结构学习优化**；支持可切换骨干（`vgg16` / `resnet34` / `efficientnet_b0`）。
* **数据加载**：提供了自定义的 `ICLayoutDataset` 类，用于加载光栅化的 IC 版图图像，支持**曼哈顿几何感知采样**。
* **训练脚本**：通过**几何感知损失函数**训练模型，学习**几何结构描述子**而非纹理特征，确保对二值化、稀疏性、重复结构的鲁棒性。
* **评估脚本**：可在验证集上评估模型性能，**专门针对IC版图特征**计算几何一致性指标。
* **匹配工具**：支持 FPN 多尺度推理与滑窗两种路径，并提供半径 NMS 去重；可直接输出多实例匹配结果。
* **灵活配置与日志**：引入 OmegaConf 驱动的 YAML 配置 (`configs/*.yaml`)，配合 `utils.config_loader` 与 TensorBoard 监控实现参数/路径集中管理。
* **性能工具**：提供 FPN vs 滑窗的对标脚本与多骨干 A/B 基准脚本，便于快速评估速度/显存与精度。

## 🛠️ 安装

### 环境要求

* Python 3.8 或更高版本
* CUDA (可选, 推荐用于 GPU 加速)

### 依赖安装

**使用 uv（推荐）：**
```bash
# 安装 uv（如果尚未安装）
pip install uv

# 安装项目依赖
uv sync
```

**使用 pip：**
```bash
pip install -e .
```

## 🚀 使用方法

### 📁 项目结构

```
RoRD-Layout-Recognation/
├── configs/
│   └── base_config.yaml          # YAML 配置入口
├── data/
│   └── ic_dataset.py             # 数据集与数据接口
├── docs/
│   ├── data_description.md
│   ├── feature_work.md
│   ├── loss_function.md
│   └── NextStep.md
├── models/
│   └── rord.py                   # RoRD 模型与 FPN，多骨干支持
├── utils/
│   ├── config_loader.py          # YAML 配置加载与路径转换
│   ├── data_utils.py
│   └── transforms.py
├── losses.py                     # 几何感知损失集合
├── train.py                      # 训练脚本（YAML + TensorBoard）
├── evaluate.py                   # 评估脚本
├── match.py                      # 模板匹配脚本（FPN / 滑窗 + NMS）
├── tests/
│   ├── benchmark_fpn.py          # FPN vs 滑窗性能对标
│   ├── benchmark_backbones.py    # 多骨干 A/B 前向基准
│   ├── benchmark_attention.py    # 注意力 none/se/cbam A/B 基准
│   └── benchmark_grid.py         # 三维基准：Backbone × Attention × Single/FPN
├── config.py                     # 兼容旧流程的 YAML 读取 shim
├── pyproject.toml
└── README.md
```

### 🧩 配置与模块化更新

- **YAML 配置中心**：所有路径与超参数集中存放在 `configs/*.yaml`，通过 `utils.config_loader.load_config` 统一解析；CLI 的 `--config` 参数可切换实验配置，`to_absolute_path` 则保证相对路径相对配置文件解析。
- **旧配置兼容**：`config.py` 现在仅作为兼容层，将 YAML 配置转换成原有的 Python 常量，便于逐步迁移历史代码。
- **损失与数据解耦**：`losses.py` 汇总几何感知损失，`data/ic_dataset.py` 与 `utils/data_utils.py` 分离数据准备逻辑，便于扩展新的采样策略或损失项。

# 5. 运行 A/B 基准（骨干、注意力、三维网格）
PYTHONPATH=. uv run python tests/benchmark_backbones.py --device cpu --image-size 512 --runs 5
PYTHONPATH=. uv run python tests/benchmark_attention.py --device cpu --image-size 512 --runs 10 --backbone resnet34 --places backbone_high desc_head
PYTHONPATH=. uv run python tests/benchmark_grid.py --device cpu --image-size 512 --runs 3 --backbones vgg16 resnet34 efficientnet_b0 --attentions none se cbam --places backbone_high desc_head
- **日志体系**：`logging` 配置节配合 TensorBoard 集成，`train.py`、`evaluate.py`、`match.py` 可统一写入 `log_dir/子任务/experiment_name`。
 - **模型配置扩展**：
   - `model.backbone.name`: `vgg16 | resnet34 | efficientnet_b0`
   - `model.backbone.pretrained`: 是否加载 ImageNet 预训练
   - `model.attention`: `enabled/type/places`（默认关闭，可选 `cbam` / `se`）
   - `model.fpn`: `enabled/out_channels/levels`

## 🚀 使用方法

### 📋 训练准备清单

在开始训练前，请确保完成以下准备：

#### 1. 数据准备
- **训练数据**：准备PNG格式的布局图像（如电路板布局、建筑平面图等）
- **数据目录结构**：
  ```
  your_data_directory/
  ├── image1.png
  ├── image2.png
  └── ...
  ```

#### 2. 配置文件修改
项目默认从 `configs/base_config.yaml` 读取训练、评估与日志参数。建议复制该文件并按实验命名，例如：

```bash
cp configs/base_config.yaml configs/exp_ic_baseline.yaml
```

在 YAML 中修改路径与关键参数：

```yaml
paths:
  layout_dir: "数据集/训练图像目录"
  save_dir: "输出目录（模型与日志）"
  val_img_dir: "验证集图像目录"
  val_ann_dir: "验证集标注目录"
  template_dir: "模板图像目录"

training:
  num_epochs: 50
  batch_size: 8
  learning_rate: 5.0e-5

logging:
  use_tensorboard: true
  log_dir: "runs"
  experiment_name: "baseline"
```

> 保留 `config.py` 仅用于兼容旧版脚本；新流程全部通过 YAML + `utils.config_loader` 载入配置。

#### 3. 环境检查
确保已正确安装所有依赖：
```bash
python -c "import torch; print('PyTorch version:', torch.__version__)"
python -c "import cv2; print('OpenCV version:', cv2.__version__)"
```

### 🎯 开始训练

#### 基础训练
```bash
uv run python train.py --config configs/exp_ic_baseline.yaml
```

上述命令将读取 `configs/exp_ic_baseline.yaml` 中的路径和训练参数；若未指定 `--config`，脚本会回落到 `configs/base_config.yaml`。

#### 自定义训练参数
```bash
uv run python train.py \
  --config configs/exp_ic_baseline.yaml \
  --data_dir /override/layouts \
  --save_dir /override/models \
  --epochs 60 \
  --batch_size 16 \
  --lr 1e-4
```

#### 查看所有可用参数
```bash
python train.py --help
```

### 📊 训练监控
训练过程中会在 `SAVE_DIR` 目录下生成：
- 日志文件：`training_YYYYMMDD_HHMMSS.log`
- 最佳模型：`rord_model_best.pth`
- 最终模型：`rord_model_final.pth`

### 📈 TensorBoard 实验追踪

`configs/base_config.yaml` 中新增的 `logging` 区块用于控制 TensorBoard：

```yaml
logging:
  use_tensorboard: true          # 是否启用 TensorBoard 记录
  log_dir: "runs"                # 日志根目录（相对/绝对路径均可）
  experiment_name: "default"    # 实验名称，将作为子目录名
```

需要临时覆盖时，可在命令行传入参数（以下命令均可用 `uv run` 直接执行）：

```bash
uv run python train.py --log_dir logs --experiment_name exp001
uv run python evaluate.py --log_dir logs --experiment_name exp001
uv run python match.py --tb_log_matches --log_dir logs --experiment_name exp001
uv run python train.py --disable_tensorboard            # 如需关闭记录
```

执行训练、评估或模板匹配后，通过下列命令启动 TensorBoard：

```bash
uv run tensorboard --logdir runs
```

TensorBoard 中将展示：

- `train.py`：损失、学习率、梯度范数等随时间变化曲线；
- `evaluate.py`：精确率 / 召回率 / F1 分数；
- `match.py`（配合 `--tb_log_matches`）：每个匹配实例的内点数量、尺度和总检测数量。

### 🚀 快速开始示例
```bash
# 1. 安装依赖
uv sync

# 2. 复制并编辑 YAML 配置
cp configs/base_config.yaml configs/exp_ic_baseline.yaml
# 根据数据路径与实验需求调整 paths/training/logging 字段

# 3. 开始训练
uv run python train.py --config configs/exp_ic_baseline.yaml

# 4. 使用训练好的模型进行匹配
uv run python match.py --config configs/exp_ic_baseline.yaml \
                       --model_path ./output/rord_model_final.pth \
                       --layout ./test/layout.png \
                       --template ./test/template.png \
                       --output ./result.png
```

### 4. 模板匹配
```bash
python match.py --model_path /path/to/your/models/rord_model_final.pth \
                --layout /path/to/layout.png \
                --template /path/to/template.png \
                --output /path/to/result.png
```

### 5. 评估模型
```bash
python evaluate.py --model_path /path/to/your/models/rord_model_final.pth \
                   --val_dir /path/to/val/images \
                   --annotations_dir /path/to/val/annotations \
                   --templates_dir /path/to/templates
```

## 📦 数据准备

### 训练数据

* **格式**: PNG 格式的 IC 版图图像，可从 GDSII 或 OASIS 文件光栅化得到。
* **要求**: 数据集应包含多个版图图像，建议分辨率适中（例如 1024x1024）。
* **存储**: 将所有训练图像存放在一个目录中（例如 `path/to/layouts`）。

### 验证数据

* **图像**: PNG 格式的验证集图像，存储在指定目录（例如 `path/to/val/images`）。
* **模板**: 所有模板图像存储在单独的目录中（例如 `path/to/templates`）。
* **标注**: 真实标注信息以 JSON 格式提供，文件名需与对应的验证图像一致，并存储在指定目录（例如 `path/to/val/annotations`）。

JSON 标注文件示例：
```json
{
    "boxes": [
        {"template": "template1.png", "x": 100, "y": 200, "width": 50, "height": 50},
        {"template": "template2.png", "x": 300, "y": 400, "width": 60, "height": 60}
    ]
}
```

## 🧠 模型架构 - IC版图专用优化版

RoRD 模型基于 D2-Net 架构，使用 VGG-16 作为骨干网络，**专门针对IC版图的几何特征进行了深度优化**。

### 网络结构创新
* **检测头**: 用于检测**几何边界关键点**，输出二值化概率图，专门针对IC版图的黑白边界优化
* **描述子头**: 生成 128 维的**几何结构描述子**，而非纹理描述子，具有以下特性：
  - **曼哈顿几何感知**: 专门针对水平和垂直结构优化
  - **重复结构区分**: 能有效区分相同图形的不同实例
  - **二值化鲁棒性**: 对光照变化完全不变
  - **稀疏特征优化**: 专注于真实几何结构而非噪声

### 核心创新 - 几何感知损失函数
**专为IC版图特征设计**：
- **曼哈顿一致性损失**: 确保90度旋转下的几何一致性
- **稀疏性正则化**: 适应IC版图稀疏特征分布
- **二值化特征距离**: 强化几何边界特征，弱化灰度变化
- **几何感知困难负样本**: 基于结构相似性而非像素相似性选择负样本

## 🔎 推理与匹配（FPN 路径与 NMS）

项目已支持通过 FPN 单次推理产生多尺度特征，并在匹配阶段引入半径 NMS 去重以减少冗余关键点：

在 `configs/base_config.yaml` 中启用 FPN 与 NMS：

```yaml
model:
  fpn:
    enabled: true
    out_channels: 256
    levels: [2, 3, 4]

  backbone:
    name: "vgg16"                  # 可选：vgg16 | resnet34 | efficientnet_b0
    pretrained: false

  attention:
    enabled: false
    type: "none"                   # 可选：none | cbam | se
    places: []                      # 插入位置：backbone_high | det_head | desc_head

matching:
  use_fpn: true
  nms:
    enabled: true
    radius: 4
    score_threshold: 0.5
```

运行匹配并将过程写入 TensorBoard：

```bash
uv run python match.py \
  --config configs/base_config.yaml \
  --layout /path/to/layout.png \
  --template /path/to/template.png \
  --tb_log_matches
```

如需回退旧“图像金字塔”路径，将 `matching.use_fpn` 设为 `false` 即可。

也可使用 CLI 快捷开关临时覆盖：

```bash
# 关闭 FPN（等同 matching.use_fpn=false）
uv run python match.py --config configs/base_config.yaml --fpn_off \
  --layout /path/to/layout.png --template /path/to/template.png

# 关闭关键点去重（NMS）
uv run python match.py --config configs/base_config.yaml --no_nms \
  --layout /path/to/layout.png --template /path/to/template.png
```

### 训练策略 - 几何结构学习
模型通过**几何结构学习**策略进行训练：
- **曼哈顿变换生成训练对**: 利用90度旋转等曼哈顿变换
- **几何感知采样**: 优先采样水平和垂直方向的边缘点
- **结构一致性优化**: 学习几何结构描述子而非纹理特征
- **重复结构鲁棒性**: 有效处理IC版图中的大量重复图形

**关键区别**: 传统方法学习纹理特征，我们的方法**学习几何结构特征**，完美适应IC版图的二值化、稀疏性、重复结构和曼哈顿几何特征。

## 📊 结果
可参考以下文档与脚本复现并查看最新结果：

- CPU 多骨干 A/B 基准（512×512，5 次）：见 `docs/description/Performance_Benchmark.md`
- 三维基准（Backbone × Attention × Single/FPN）：见 `docs/description/Performance_Benchmark.md` 与 `tests/benchmark_grid.py`
- FPN vs 滑窗对标脚本：`tests/benchmark_fpn.py`
- 多骨干 A/B 基准脚本：`tests/benchmark_backbones.py`

后续将在 GPU 与真实数据集上补充精度与速度的完整对标表格。

## 📄 许可协议

本项目根据 [Apache License 2.0](LICENSE.txt) 授权。

---

## 🧪 合成数据一键流程与常见问题

### 一键命令
```bash
uv run python tools/generate_synthetic_layouts.py --out_dir data/synthetic/gds --num 200 --seed 42
uv run python tools/layout2png.py --in data/synthetic/gds --out data/synthetic/png --dpi 600
uv run python tools/preview_dataset.py --dir data/synthetic/png --out preview.png --n 8 --elastic
uv run python train.py --config configs/base_config.yaml
```

或使用单脚本一键执行（含配置写回）：
```bash
uv run python tools/synth_pipeline.py --out_root data/synthetic --num 200 --dpi 600 \
  --config configs/base_config.yaml --ratio 0.3 --enable_elastic
```

### YAML 关键片段
```yaml
synthetic:
  enabled: true
  png_dir: data/synthetic/png
  ratio: 0.3

augment:
  elastic:
    enabled: true
    alpha: 40
    sigma: 6
    alpha_affine: 6
    prob: 0.3
```

### 参数建议
- DPI：600–900；图形极细时可到 1200（注意磁盘占用与 IO）。
- ratio：数据少取 0.3–0.5；中等 0.2–0.3；数据多 0.1–0.2。
- Elastic：alpha=40, sigma=6, prob=0.3 为安全起点。

### FAQ
- 找不到 `klayout`：安装系统级 KLayout 并加入 PATH；或使用回退（gdstk+SVG）。
- `cairosvg`/`gdstk` 报错：升级版本、确认写权限、检查输出目录存在。
- 训练集为空：检查 `paths.layout_dir` 与 `synthetic.png_dir` 是否存在且包含 .png；若 syn 目录为空将自动仅用真实数据。

---

## 🧪 合成数据管线与可视化

### 1) 生成合成 GDS
```bash
uv run python tools/generate_synthetic_layouts.py --out_dir data/synthetic/gds --num 200 --seed 42
```

### 2) 批量转换 GDS → PNG
```bash
uv run python tools/layout2png.py --in data/synthetic/gds --out data/synthetic/png --dpi 600
```

若本机未安装 KLayout，将自动回退到 gdstk+SVG 路径；图像外观可能与 KLayout 有差异。

### 3) 开启训练混采
在 `configs/base_config.yaml` 中设置：
```yaml
synthetic:
  enabled: true
  png_dir: data/synthetic/png
  ratio: 0.3
```

### 4) 预览训练对（目检增强/H 一致性）
```bash
uv run python tools/preview_dataset.py --dir data/synthetic/png --out preview.png --n 8 --elastic
```

### 5) 开启/调整 Elastic 变形
```yaml
augment:
  elastic:
    enabled: true
    alpha: 40
    sigma: 6
    alpha_affine: 6
    prob: 0.3
  photometric:
    brightness_contrast: true
    gauss_noise: true
```
