Files
XplorePlane/XP.Calibration/README.md
T
2026-04-23 19:38:44 +08:00

160 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# XP.Calibration
平面 CT 系统几何校准库,基于 .NET 8 + Emgu.CV,从 C++ OpenCV 实现移植而来。
## 功能
提供两种校准方法:
- **中心校准 (CenterCalibration)** — 从投影序列检测球心轨迹,椭圆拟合后反算倾斜角和焦点投影偏移,适用于快速估算
- **完整几何校准 (FullCalibration)** — 基于 TIGRE 投影模型(角点法),使用 Levenberg-Marquardt 优化器同时优化 5~9 个几何参数
## 项目结构
```
XP.Calibration/
├── Models/
│ ├── CalibrationModels.cs # EllipseResult, GeoParams, CenterCalibrationResult
│ ├── FullCalibrationResult.cs # 完整校准输出 (各参数 + RMS)
│ └── FullCalibrationOptions.cs # 优化模式选项
├── Core/
│ ├── RawReader.cs # RAW float32 投影数据读取
│ ├── BallDetector.cs # 球心检测 (自适应阈值+亚像素质心 / Canny+椭圆拟合)
│ └── TigreProjection.cs # TIGRE 投影模型 (rollPitchYaw + eulerZYZ)
├── CenterCalibration.cs # 中心校准
└── FullCalibration.cs # 完整几何校准 (LM 优化)
```
## 校准参数
完整几何校准支持三种模式:
| 模式 | 参数数 | 优化参数 |
|------|--------|----------|
| 基础 | 5 | ay, det_y, det_x, det_z, R |
| +探测器偏移 | 7 | 基础 + offDetecU, offDetecV |
| +距离 | 9 | 基础 + offDetecU, offDetecV + DSO, DSD |
参数含义:
| 参数 | 说明 | TIGRE 对应 |
|------|------|-----------|
| ay | 旋转轴倾斜角 | angles[:,1] |
| det_x | 探测器 dYaw (Rx) | rotDetector[:,0] |
| det_y | 探测器 dPitch (Ry) | rotDetector[:,1] |
| det_z | 探测器 dRoll (Rz) | rotDetector[:,2] |
| R | 物体偏移半径 | offOrigin[:,2] = -R |
| offDetecU/V | 探测器平移偏移 | offDetector[:,0]/[:,1] |
| DSO | 焦点到旋转中心距离 | geo.DSO |
| DSD | 焦点到探测器距离 | geo.DSD |
## 使用示例
### 中心校准
```csharp
var geo = new GeoParams
{
DSO = 200, DSD = 500, PixelSize = 0.6,
NDetecU = 512, NDetecV = 512
};
var calib = new CenterCalibration();
var result = calib.CalibrateFromRaw("projections.raw", 512, 512, 360, geo);
Console.WriteLine($"倾斜角: {result.AlphaDeg:F2}°");
Console.WriteLine($"R: {result.R_mm:F2} mm");
Console.WriteLine($"焦点投影: ({result.FocalU:F2}, {result.FocalV:F2})");
```
### 完整几何校准 (5 参数)
```csharp
var geo = new GeoParams
{
DSO = 250, DSD = 450, PixelSize = 0.6,
NDetecU = 512, NDetecV = 512
};
var full = new FullCalibration();
var result = full.CalibrateFromRaw("projections.raw", 512, 512, 360, geo);
Console.WriteLine($"ay: {result.AyDeg:F4}°");
Console.WriteLine($"det_z: {result.DetZDeg:F4}°");
Console.WriteLine($"R: {result.R_mm:F4} mm");
Console.WriteLine($"RMS: {result.RmsPx:F6} px");
```
### 完整几何校准 (9 参数)
```csharp
var options = new FullCalibrationOptions
{
OptimizeDetectorOffset = true, // +offDetecU/V
OptimizeDistances = true, // +DSO/DSD
MaxIterations = 5000,
Tolerance = 1e-16
};
var full = new FullCalibration();
// 可选: 监听优化进度
full.OnProgress = (iter, rms, p) =>
Console.WriteLine($"Iter {iter}: RMS={rms:F6} px");
var result = full.CalibrateFromRaw("projections.raw", 512, 512, 360, geo, options);
```
### 直接传入 Mat 列表
如果投影数据已经在内存中(比如从相机采集),可以直接传 `List<Mat>`
```csharp
List<Mat> projections = ...; // 已有的 CV_32F Mat 列表
var result = new FullCalibration().Calibrate(projections, geo, options);
```
### 切换球心检测方法
默认使用自适应阈值 + 亚像素质心法。如需使用 Canny + 椭圆拟合法:
```csharp
// 关闭亚像素质心,改用矩心
BallDetector.EnableSubPixel = false;
// 或直接调用椭圆拟合检测
BallDetector.DetectCenterByEllipse(mat, out var center);
```
## 算法说明
### 球心检测流程
1. 归一化 float32 → 8bit
2. 高斯模糊 (3×3, σ=0.8)
3. 自适应阈值二值化 (blockSize=31, C=-5)
4. 查找最大轮廓
5. 亚像素质心 (强度加权) 或矩心
### TIGRE 投影模型
完全按照 TIGRE `computeDeltas_Siddon` 流程实现:
1. 初始化探测器角点 (P, Pu0, Pv0) 和射线源 S
2. `rollPitchYaw` — 探测器自身旋转 (det_x, det_y, det_z)
3. 探测器偏移 (offDetecU/V)
4. `eulerZYZ` — 扫描旋转 (scanAngle, ay)
5. 物体偏移 (offOrigX = -R)
6. 射线-平面交点 → 像素坐标
### LM 优化器
- 数值差分雅可比矩阵 (中心差分, ε=1e-7)
- Cholesky 分解求解法方程
- 自适应阻尼因子 (成功 ×0.3, 失败 ×10)
- 参数边界约束 (clamp)
## 依赖
- .NET 8.0-windows
- Emgu.CV 4.10.0.5680