Files
XplorePlane/XP.Camera

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 命名空间下。

项目引用

<ProjectReference Include="..\XP.Camera\XP.Camera.csproj" />

快速开始

1. 通过工厂创建控制器

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 容器中注册:

var config = AppConfig.Load();
containerRegistry.RegisterSingleton<ICameraFactory, CameraFactory>();
containerRegistry.RegisterSingleton<ICameraController>(() =>
    new CameraFactory().CreateController(config.CameraType));

相机品牌通过配置文件 config.json 指定:

{
  "CameraType": "Basler"
}

3. 实时图像显示(WPF 绑定)

_camera.ImageGrabbed += (s, e) =>
{
    var bitmap = PixelConverter.ToBitmapSource(
        e.PixelData, e.Width, e.Height, e.PixelFormat);
    Application.Current.Dispatcher.Invoke(() => CameraImageSource = bitmap);
};

4. 软件触发采集流程

camera.Open();
camera.SetExposureTime(10000);  // 10ms
camera.StartGrabbing();
camera.ExecuteSoftwareTrigger();
camera.StopGrabbing();
camera.Close();

5. 使用标定模块

标定模块完全自包含,可独立使用,无需外部依赖。

棋盘格标定(相机内参 + 畸变校正)

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();

九点标定(像素→世界坐标)

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

// 棋盘格标定
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 接口即可:

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() 幂等,重复调用安全