Files
XplorePlane/XP.Camera/README.md
T

216 lines
6.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.Camera 使用说明
基于 .NET 8 WPF 的工业相机控制与标定类库,采用工厂模式 + 统一接口设计,支持多品牌相机扩展。当前已实现 Basler pylon SDK 驱动。
## 环境要求
- .NET 8 SDK
- Windows 操作系统
- Basler pylon 8 SDK(已安装并配置环境变量)
## 项目结构
```
XP.Camera/
├── Core/ # 相机核心抽象
│ ├── ICameraController.cs # 控制器接口 + 工厂接口
│ ├── CameraFactory.cs # 统一工厂(根据品牌创建控制器)
│ ├── CameraModels.cs # CameraInfo、ImageGrabbedEventArgs、GrabErrorEventArgs
│ └── CameraExceptions.cs # CameraException、ConnectionLostException、DeviceNotFoundException
├── Basler/ # Basler 品牌实现
│ └── BaslerCameraController.cs # Basler pylon SDK 实现
├── Converters/ # 数据转换工具
│ └── PixelConverter.cs # 像素数据 → WPF BitmapSource 转换
├── Calibration/ # 相机标定模块
│ ├── CalibrationProcessor.cs # 九点标定(DLT 单应性矩阵,像素→世界坐标)
│ ├── ChessboardCalibrator.cs # 棋盘格标定(Zhang's 方法,内参 + 畸变校正)
│ ├── IDialogService.cs # ICalibrationDialogService 接口
│ ├── DefaultCalibrationDialogService.cs # 默认实现(标准 WPF MessageBox
│ ├── CalibrationLocalizedStrings.cs # XAML 本地化绑定辅助
│ ├── Controls/ # 标定 UI 控件(UserControl
│ │ ├── CalibrationControl.xaml/.cs # 九点标定界面
│ │ ├── ChessboardCalibrationControl.xaml/.cs # 棋盘格标定界面
│ │ └── ImageCanvasControl.xaml/.cs # 图像画布(缩放/平移)
│ ├── ViewModels/ # 标定视图模型
│ │ ├── CalibrationViewModel.cs
│ │ └── ChessboardCalibrationViewModel.cs
│ └── Resources/ # 本地化资源
│ ├── CalibrationResources.resx # 中文(默认)
│ ├── CalibrationResources.en-US.resx # 英文
│ └── CalibrationResources.Designer.cs
└── XP.Camera.csproj
```
所有相机核心类型在 `XP.Camera` 命名空间下,标定模块在 `XP.Camera.Calibration` 命名空间下。
## 项目引用
```xml
<ProjectReference Include="..\XP.Camera\XP.Camera.csproj" />
```
## 快速开始
### 1. 通过工厂创建控制器
```csharp
using XP.Camera;
ICameraFactory factory = new CameraFactory();
using ICameraController camera = factory.CreateController("Basler");
CameraInfo info = camera.Open();
Console.WriteLine($"已连接: {info.ModelName} (SN: {info.SerialNumber})");
```
### 2. 依赖注入方式(推荐)
在 Prism / DI 容器中注册:
```csharp
var config = AppConfig.Load();
containerRegistry.RegisterSingleton<ICameraFactory, CameraFactory>();
containerRegistry.RegisterSingleton<ICameraController>(() =>
new CameraFactory().CreateController(config.CameraType));
```
相机品牌通过配置文件 `config.json` 指定:
```json
{
"CameraType": "Basler"
}
```
### 3. 实时图像显示(WPF 绑定)
```csharp
_camera.ImageGrabbed += (s, e) =>
{
var bitmap = PixelConverter.ToBitmapSource(
e.PixelData, e.Width, e.Height, e.PixelFormat);
Application.Current.Dispatcher.Invoke(() => CameraImageSource = bitmap);
};
```
### 4. 软件触发采集流程
```csharp
camera.Open();
camera.SetExposureTime(10000); // 10ms
camera.StartGrabbing();
camera.ExecuteSoftwareTrigger();
camera.StopGrabbing();
camera.Close();
```
### 5. 使用标定模块
标定模块完全自包含,可独立使用,无需外部依赖。
#### 棋盘格标定(相机内参 + 畸变校正)
```csharp
using XP.Camera.Calibration;
using XP.Camera.Calibration.ViewModels;
using XP.Camera.Calibration.Controls;
// 使用默认对话框服务(标准 WPF MessageBox
var dialogService = new DefaultCalibrationDialogService();
var viewModel = new ChessboardCalibrationViewModel(dialogService);
var window = new Window
{
Title = "棋盘格标定",
Width = 1600, Height = 900,
Content = new ChessboardCalibrationControl { DataContext = viewModel }
};
window.ShowDialog();
```
#### 九点标定(像素→世界坐标)
```csharp
var dialogService = new DefaultCalibrationDialogService();
var viewModel = new CalibrationViewModel(dialogService);
var window = new Window
{
Title = "九点标定",
Width = 1400, Height = 850,
Content = new CalibrationControl { DataContext = viewModel }
};
window.ShowDialog();
```
#### 纯算法调用(不使用 UI
```csharp
// 棋盘格标定
var calibrator = new ChessboardCalibrator();
calibrator.CalibrateFromImages(imagePaths, boardWidth: 11, boardHeight: 8, squareSize: 15f, out string error);
calibrator.SaveCalibration("camera_calibration.json");
// 九点标定
var processor = new CalibrationProcessor();
processor.Calibrate(points);
var worldPoint = processor.PixelToWorld(new PointF(100, 200));
```
#### 自定义对话框服务
如需自定义弹框样式,实现 `ICalibrationDialogService` 接口即可:
```csharp
public class MyDialogService : ICalibrationDialogService
{
// 实现所有接口方法,使用自定义 UI 组件...
}
```
## 核心接口
### ICameraController
| 方法 | 说明 |
|------|------|
| `Open()` | 打开连接,返回 `CameraInfo` |
| `Close()` | 关闭连接(自动停止采集) |
| `StartGrabbing()` | 以软件触发模式启动采集 |
| `ExecuteSoftwareTrigger()` | 触发一帧采集 |
| `StopGrabbing()` | 停止采集 |
| `Get/SetExposureTime` | 曝光时间(微秒) |
| `Get/SetGain` | 增益值 |
| `Get/SetWidth/Height` | 图像尺寸 |
| `Get/SetPixelFormat` | 像素格式(Mono8 / BGR8 / BGRA8 |
### 事件
| 事件 | 说明 |
|------|------|
| `ImageGrabbed` | 成功采集一帧图像 |
| `GrabError` | 图像采集失败 |
| `ConnectionLost` | 相机连接意外断开 |
> 所有事件均在非 UI 线程触发,更新 WPF 界面时需通过 `Dispatcher.Invoke` 调度。
## 异常处理
| 异常类型 | 场景 |
|---------|------|
| `DeviceNotFoundException` | 无可用相机 |
| `ConnectionLostException` | 相机物理断开 |
| `CameraException` | SDK 操作失败(基类) |
## 扩展其他品牌相机
1.`Basler/` 同级创建新文件夹,实现 `ICameraController` 接口
2.`CameraFactory.cs` 中注册新品牌
3. 配置文件切换品牌即可,业务代码无需修改
## 线程安全
- 所有公共方法均线程安全
- 事件回调不持有内部锁,不会导致死锁
- `Open()` / `Close()` 幂等,重复调用安全