# 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 ``` ## 快速开始 ### 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(); containerRegistry.RegisterSingleton(() => 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()` 幂等,重复调用安全