30 KiB
30 KiB
探测器模块使用指南 | Detector Module Usage Guide
1. 模块概述 | Module Overview
XP.Hardware.Detector 是 XplorePlane X 射线检测系统的探测器控制模块,负责与工业 X 射线探测器进行通讯和控制。该模块采用策略模式设计,支持多种探测器型号的统一管理。
核心特性 | Key Features
- 支持多种探测器型号(Varex、iRay 等)
- 完整的探测器生命周期管理(初始化、采集、校正)
- 单帧和连续采集模式
- 自动校正功能(暗场、增益、坏像素)
- 实时状态监控
- 基于 Prism 事件聚合器的松耦合通讯
- 异步操作,不阻塞 UI 线程
2. 模块注册 | Module Registration
探测器模块通过 Prism 的模块化系统注册,在应用启动时自动加载。
在 App.xaml.cs 中注册
using Prism.Modularity;
using XP.Hardware.Detector.Module;
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
// 注册探测器模块 | Register Detector module
moduleCatalog.AddModule<DetectorModule>();
base.ConfigureModuleCatalog(moduleCatalog);
}
模块自动注册的服务
IDetectorFactory- 探测器工厂(瞬态)IDetectorService- 探测器业务服务(单例)
3. 配置文件设置 | Configuration File Setup
在 App.config 中添加探测器配置:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<!-- 探测器类型 | Detector Type -->
<add key="Detector:Type" value="Varex" />
<!-- 网络配置 | Network Configuration -->
<add key="Detector:IP" value="192.168.1.200" />
<add key="Detector:Port" value="50000" />
<!-- 图像存储配置 | Image Storage Configuration -->
<add key="Detector:SavePath" value="D:\Images" />
<add key="Detector:AutoSave" value="true" />
<!-- Varex 探测器特定配置 | Varex Detector Specific Configuration -->
<add key="Varex:ConfigFile" value="detector.xml" />
<add key="Varex:CalibrationFile" value="calibration.cal" />
<!-- iRay 探测器特定配置 | iRay Detector Specific Configuration -->
<add key="IRay:DeviceID" value="0" />
<add key="IRay:ExposureTime" value="100" />
</appSettings>
</configuration>
配置参数说明
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| Type | string | Varex | 探测器类型(Varex/IRay) |
| IP | string | 192.168.1.200 | 探测器 IP 地址 |
| Port | int | 50000 | 探测器端口号 |
| SavePath | string | D:\Images | 图像存储路径 |
| AutoSave | bool | true | 是否自动保存图像 |
4. 在 ViewModel 中使用 | Usage in ViewModel
4.1 注入服务
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using System.Threading.Tasks;
using XP.Common.Logging.Interfaces;
using XP.Hardware.Detector.Abstractions;
using XP.Hardware.Detector.Abstractions.Enums;
using XP.Hardware.Detector.Abstractions.Events;
using XP.Hardware.Detector.Services;
namespace YourNamespace.ViewModels
{
public class YourViewModel : BindableBase
{
private readonly IDetectorService _detectorService;
private readonly IEventAggregator _eventAggregator;
private readonly ILoggerService _logger;
/// <summary>
/// 构造函数,通过依赖注入获取服务 | Constructor with dependency injection
/// </summary>
public YourViewModel(
IDetectorService detectorService,
IEventAggregator eventAggregator,
ILoggerService logger)
{
_detectorService = detectorService;
_eventAggregator = eventAggregator;
_logger = logger.ForModule("YourViewModel");
// 订阅事件 | Subscribe to events
SubscribeEvents();
}
private void SubscribeEvents()
{
// 订阅图像采集事件 | Subscribe to image captured event
_eventAggregator.GetEvent<ImageCapturedEvent>()
.Subscribe(OnImageCaptured);
// 订阅校正完成事件 | Subscribe to correction completed event
_eventAggregator.GetEvent<CorrectionCompletedEvent>()
.Subscribe(OnCorrectionCompleted);
}
private void OnImageCaptured(ImageCapturedEventArgs args)
{
_logger.Info($"图像已采集: {args.FrameNumber}");
}
private void OnCorrectionCompleted(CorrectionCompletedEventArgs args)
{
_logger.Info($"校正完成: {args.CorrectionType}");
}
}
}
4.2 初始化探测器
/// <summary>
/// 初始化探测器 | Initialize detector
/// </summary>
public async Task InitializeDetectorAsync()
{
try
{
_logger.Info("开始初始化探测器... | Starting detector initialization...");
StatusMessage = "正在初始化... | Initializing...";
DetectorResult result = await _detectorService.InitializeAsync();
if (result.IsSuccess)
{
_logger.Info("探测器初始化成功 | Detector initialized successfully");
StatusMessage = "探测器已就绪 | Detector ready";
// 获取探测器信息 | Get detector information
DetectorInfo info = _detectorService.GetInfo();
_logger.Info($"探测器型号: {info.Model}, 分辨率: {info.MaxWidth}x{info.MaxHeight}");
}
else
{
_logger.Error(null, $"探测器初始化失败: {result.ErrorMessage}");
StatusMessage = $"初始化失败: {result.ErrorMessage}";
}
}
catch (Exception ex)
{
_logger.Error(ex, $"初始化异常: {ex.Message}");
StatusMessage = $"初始化异常: {ex.Message}";
}
}
4.3 单帧采集
/// <summary>
/// 单帧采集 | Single frame acquisition
/// </summary>
public async Task AcquireSingleFrameAsync()
{
try
{
if (_detectorService.Status != DetectorStatus.Ready)
{
_logger.Warn("探测器未就绪,无法采集");
StatusMessage = "探测器未就绪 | Detector not ready";
return;
}
_logger.Info("开始单帧采集... | Starting single frame acquisition...");
StatusMessage = "正在采集... | Acquiring...";
DetectorResult result = await _detectorService.AcquireSingleFrameAsync();
if (result.IsSuccess)
{
_logger.Info("单帧采集成功 | Single frame acquired successfully");
StatusMessage = "采集完成 | Acquisition completed";
}
else
{
_logger.Error(null, $"单帧采集失败: {result.ErrorMessage}");
StatusMessage = $"采集失败: {result.ErrorMessage}";
}
}
catch (Exception ex)
{
_logger.Error(ex, $"单帧采集异常: {ex.Message}");
StatusMessage = $"采集异常: {ex.Message}";
}
}
4.4 启动连续采集
/// <summary>
/// 启动连续采集 | Start continuous acquisition
/// </summary>
public async Task StartAcquisitionAsync()
{
try
{
if (_detectorService.Status != DetectorStatus.Ready)
{
_logger.Warn("探测器未就绪,无法启动采集");
return;
}
_logger.Info("启动连续采集... | Starting continuous acquisition...");
StatusMessage = "连续采集中... | Continuous acquisition...";
DetectorResult result = await _detectorService.StartAcquisitionAsync();
if (result.IsSuccess)
{
_logger.Info("连续采集已启动 | Continuous acquisition started");
IsAcquiring = true;
}
else
{
_logger.Error(null, $"启动采集失败: {result.ErrorMessage}");
StatusMessage = $"启动失败: {result.ErrorMessage}";
}
}
catch (Exception ex)
{
_logger.Error(ex, $"启动采集异常: {ex.Message}");
StatusMessage = $"启动异常: {ex.Message}";
}
}
4.5 停止采集
/// <summary>
/// 停止采集 | Stop acquisition
/// </summary>
public async Task StopAcquisitionAsync()
{
try
{
_logger.Info("停止采集... | Stopping acquisition...");
StatusMessage = "正在停止... | Stopping...";
DetectorResult result = await _detectorService.StopAcquisitionAsync();
if (result.IsSuccess)
{
_logger.Info("采集已停止 | Acquisition stopped");
StatusMessage = "已停止 | Stopped";
IsAcquiring = false;
}
else
{
_logger.Error(null, $"停止采集失败: {result.ErrorMessage}");
StatusMessage = $"停止失败: {result.ErrorMessage}";
}
}
catch (Exception ex)
{
_logger.Error(ex, $"停止采集异常: {ex.Message}");
StatusMessage = $"停止异常: {ex.Message}";
}
}
5. 校正功能 | Correction Functions
5.1 自动校正
/// <summary>
/// 执行自动校正(暗场+增益+坏像素)| Execute auto correction (dark + gain + bad pixel)
/// </summary>
/// <param name="frameCount">采集帧数 | Frame count</param>
public async Task AutoCorrectionAsync(int frameCount = 10)
{
try
{
_logger.Info($"开始自动校正,帧数: {frameCount} | Starting auto correction, frames: {frameCount}");
StatusMessage = "正在校正... | Correcting...";
DetectorResult result = await _detectorService.AutoCorrectionAsync(frameCount);
if (result.IsSuccess)
{
_logger.Info("自动校正完成 | Auto correction completed");
StatusMessage = "校正完成 | Correction completed";
}
else
{
_logger.Error(null, $"自动校正失败: {result.ErrorMessage}");
StatusMessage = $"校正失败: {result.ErrorMessage}";
}
}
catch (Exception ex)
{
_logger.Error(ex, $"自动校正异常: {ex.Message}");
StatusMessage = $"校正异常: {ex.Message}";
}
}
5.2 获取探测器信息
/// <summary>
/// 获取探测器信息 | Get detector information
/// </summary>
public void GetDetectorInfo()
{
try
{
DetectorInfo info = _detectorService.GetInfo();
if (info != null)
{
_logger.Info($"探测器信息:");
_logger.Info($" 型号: {info.Model}");
_logger.Info($" 序列号: {info.SerialNumber}");
_logger.Info($" 固件版本: {info.FirmwareVersion}");
_logger.Info($" 分辨率: {info.MaxWidth}x{info.MaxHeight}");
_logger.Info($" 像素尺寸: {info.PixelSize}μm");
_logger.Info($" 位深度: {info.BitDepth}bit");
// 更新 UI 显示 | Update UI display
DetectorModel = info.Model;
Resolution = $"{info.MaxWidth}x{info.MaxHeight}";
PixelSize = $"{info.PixelSize}μm";
}
}
catch (Exception ex)
{
_logger.Error(ex, $"获取探测器信息异常: {ex.Message}");
}
}
6. Prism 事件通讯 | Prism Event Communication
模块使用 Prism 事件聚合器实现跨模块通讯,支持以下事件:
6.1 图像采集事件
// 订阅图像采集事件 | Subscribe to image captured event
_eventAggregator.GetEvent<ImageCapturedEvent>()
.Subscribe(OnImageCaptured, ThreadOption.UIThread);
private void OnImageCaptured(ImageCapturedEventArgs args)
{
// args.FrameNumber - 帧编号
// args.Timestamp - 时间戳
// args.ImageData - 图像数据(如果有)
FrameNumber = args.FrameNumber;
LastCaptureTime = args.Timestamp;
_logger.Info($"图像已采集: 帧 {args.FrameNumber}");
}
6.2 校正完成事件
// 订阅校正完成事件 | Subscribe to correction completed event
_eventAggregator.GetEvent<CorrectionCompletedEvent>()
.Subscribe(OnCorrectionCompleted, ThreadOption.UIThread);
private void OnCorrectionCompleted(CorrectionCompletedEventArgs args)
{
// args.CorrectionType - 校正类型(暗场/增益/坏像素)
// args.IsSuccess - 是否成功
// args.Message - 消息
if (args.IsSuccess)
{
_logger.Info($"校正完成: {args.CorrectionType}");
StatusMessage = $"{args.CorrectionType} 校正完成";
}
else
{
_logger.Error(null, $"校正失败: {args.Message}");
StatusMessage = $"校正失败: {args.Message}";
}
}
7. 完整示例 | Complete Example
using Prism.Commands;
using Prism.Events;
using Prism.Mvvm;
using System;
using System.Threading.Tasks;
using System.Windows.Input;
using XP.Common.Logging.Interfaces;
using XP.Hardware.Detector.Abstractions;
using XP.Hardware.Detector.Abstractions.Enums;
using XP.Hardware.Detector.Abstractions.Events;
using XP.Hardware.Detector.Services;
namespace YourNamespace.ViewModels
{
public class DetectorControlViewModel : BindableBase
{
private readonly IDetectorService _detectorService;
private readonly IEventAggregator _eventAggregator;
private readonly ILoggerService _logger;
#region 属性 | Properties
private string _statusMessage;
public string StatusMessage
{
get => _statusMessage;
set => SetProperty(ref _statusMessage, value);
}
private DetectorStatus _detectorStatus;
public DetectorStatus DetectorStatus
{
get => _detectorStatus;
set => SetProperty(ref _detectorStatus, value);
}
private bool _isAcquiring;
public bool IsAcquiring
{
get => _isAcquiring;
set => SetProperty(ref _isAcquiring, value);
}
private int _frameNumber;
public int FrameNumber
{
get => _frameNumber;
set => SetProperty(ref _frameNumber, value);
}
private string _detectorModel;
public string DetectorModel
{
get => _detectorModel;
set => SetProperty(ref _detectorModel, value);
}
private string _resolution;
public string Resolution
{
get => _resolution;
set => SetProperty(ref _resolution, value);
}
#endregion
#region 命令 | Commands
public ICommand InitializeCommand { get; }
public ICommand AcquireSingleFrameCommand { get; }
public ICommand StartAcquisitionCommand { get; }
public ICommand StopAcquisitionCommand { get; }
public ICommand AutoCorrectionCommand { get; }
public ICommand GetInfoCommand { get; }
#endregion
public DetectorControlViewModel(
IDetectorService detectorService,
IEventAggregator eventAggregator,
ILoggerService logger)
{
_detectorService = detectorService;
_eventAggregator = eventAggregator;
_logger = logger.ForModule("DetectorControlViewModel");
// 初始化命令 | Initialize commands
InitializeCommand = new DelegateCommand(async () => await InitializeAsync());
AcquireSingleFrameCommand = new DelegateCommand(async () => await AcquireSingleFrameAsync(), CanAcquire)
.ObservesProperty(() => DetectorStatus);
StartAcquisitionCommand = new DelegateCommand(async () => await StartAcquisitionAsync(), CanStartAcquisition)
.ObservesProperty(() => DetectorStatus)
.ObservesProperty(() => IsAcquiring);
StopAcquisitionCommand = new DelegateCommand(async () => await StopAcquisitionAsync(), CanStopAcquisition)
.ObservesProperty(() => IsAcquiring);
AutoCorrectionCommand = new DelegateCommand(async () => await AutoCorrectionAsync(), CanCorrect)
.ObservesProperty(() => DetectorStatus);
GetInfoCommand = new DelegateCommand(GetInfo);
// 订阅事件 | Subscribe to events
SubscribeEvents();
}
#region 命令实现 | Command Implementations
private async Task InitializeAsync()
{
try
{
StatusMessage = "正在初始化... | Initializing...";
DetectorResult result = await _detectorService.InitializeAsync();
if (result.IsSuccess)
{
DetectorStatus = _detectorService.Status;
StatusMessage = "探测器已就绪 | Detector ready";
GetInfo();
}
else
{
StatusMessage = $"初始化失败: {result.ErrorMessage}";
}
}
catch (Exception ex)
{
_logger.Error(ex, "初始化异常");
StatusMessage = $"初始化异常: {ex.Message}";
}
}
private async Task AcquireSingleFrameAsync()
{
try
{
StatusMessage = "正在采集... | Acquiring...";
DetectorResult result = await _detectorService.AcquireSingleFrameAsync();
if (result.IsSuccess)
{
StatusMessage = "采集完成 | Acquisition completed";
}
else
{
StatusMessage = $"采集失败: {result.ErrorMessage}";
}
}
catch (Exception ex)
{
_logger.Error(ex, "单帧采集异常");
StatusMessage = $"采集异常: {ex.Message}";
}
}
private async Task StartAcquisitionAsync()
{
try
{
StatusMessage = "启动连续采集... | Starting continuous acquisition...";
DetectorResult result = await _detectorService.StartAcquisitionAsync();
if (result.IsSuccess)
{
IsAcquiring = true;
DetectorStatus = _detectorService.Status;
StatusMessage = "连续采集中... | Continuous acquisition...";
}
else
{
StatusMessage = $"启动失败: {result.ErrorMessage}";
}
}
catch (Exception ex)
{
_logger.Error(ex, "启动采集异常");
StatusMessage = $"启动异常: {ex.Message}";
}
}
private async Task StopAcquisitionAsync()
{
try
{
StatusMessage = "正在停止... | Stopping...";
DetectorResult result = await _detectorService.StopAcquisitionAsync();
if (result.IsSuccess)
{
IsAcquiring = false;
DetectorStatus = _detectorService.Status;
StatusMessage = "已停止 | Stopped";
}
else
{
StatusMessage = $"停止失败: {result.ErrorMessage}";
}
}
catch (Exception ex)
{
_logger.Error(ex, "停止采集异常");
StatusMessage = $"停止异常: {ex.Message}";
}
}
private async Task AutoCorrectionAsync()
{
try
{
StatusMessage = "正在校正... | Correcting...";
DetectorResult result = await _detectorService.AutoCorrectionAsync(10);
if (result.IsSuccess)
{
StatusMessage = "校正完成 | Correction completed";
}
else
{
StatusMessage = $"校正失败: {result.ErrorMessage}";
}
}
catch (Exception ex)
{
_logger.Error(ex, "自动校正异常");
StatusMessage = $"校正异常: {ex.Message}";
}
}
private void GetInfo()
{
try
{
DetectorInfo info = _detectorService.GetInfo();
if (info != null)
{
DetectorModel = info.Model;
Resolution = $"{info.MaxWidth}x{info.MaxHeight}";
}
}
catch (Exception ex)
{
_logger.Error(ex, "获取信息异常");
}
}
#endregion
#region 命令条件 | Command Conditions
private bool CanAcquire() => DetectorStatus == DetectorStatus.Ready;
private bool CanStartAcquisition() => DetectorStatus == DetectorStatus.Ready && !IsAcquiring;
private bool CanStopAcquisition() => IsAcquiring;
private bool CanCorrect() => DetectorStatus == DetectorStatus.Ready;
#endregion
#region 事件处理 | Event Handlers
private void SubscribeEvents()
{
_eventAggregator.GetEvent<ImageCapturedEvent>()
.Subscribe(OnImageCaptured, ThreadOption.UIThread);
_eventAggregator.GetEvent<CorrectionCompletedEvent>()
.Subscribe(OnCorrectionCompleted, ThreadOption.UIThread);
}
private void OnImageCaptured(ImageCapturedEventArgs args)
{
FrameNumber = args.FrameNumber;
}
private void OnCorrectionCompleted(CorrectionCompletedEventArgs args)
{
if (args.IsSuccess)
{
StatusMessage = $"{args.CorrectionType} 校正完成";
}
}
#endregion
}
}
8. 在应用退出时释放资源 | Release Resources on Application Exit
在 App.xaml.cs 的 OnExit 方法中添加:
protected override void OnExit(ExitEventArgs e)
{
// 记录应用退出日志 | Log application exit
Log.Information("XplorePlane主应用退出(XP.App-OnExit)");
// 释放探测器资源 | Release detector resources
try
{
var detectorService = Container.Resolve<IDetectorService>();
// 探测器服务会在 Dispose 时自动停止采集和释放资源
// Detector service will automatically stop acquisition and release resources on Dispose
Log.Information("探测器资源已成功释放 | Detector resources released successfully");
}
catch (Exception ex)
{
Log.Error(ex, "探测器资源释放失败,忽略该错误继续退出 | Failed to release detector resources");
}
// 释放其他资源... | Release other resources...
// 释放Serilog资源(避免日志丢失)| Release Serilog resources
Log.CloseAndFlush();
base.OnExit(e);
}
9. 探测器状态 | Detector Status
9.1 状态枚举
public enum DetectorStatus
{
Uninitialized = 0, // 未初始化
Initializing = 1, // 初始化中
Ready = 2, // 就绪
Acquiring = 3, // 采集中
Correcting = 4, // 校正中
Error = 5 // 错误
}
9.2 状态监控
// 监控探测器状态变化 | Monitor detector status changes
private void MonitorStatus()
{
DetectorStatus currentStatus = _detectorService.Status;
switch (currentStatus)
{
case DetectorStatus.Uninitialized:
StatusMessage = "未初始化 | Uninitialized";
break;
case DetectorStatus.Initializing:
StatusMessage = "初始化中... | Initializing...";
break;
case DetectorStatus.Ready:
StatusMessage = "就绪 | Ready";
break;
case DetectorStatus.Acquiring:
StatusMessage = "采集中... | Acquiring...";
break;
case DetectorStatus.Correcting:
StatusMessage = "校正中... | Correcting...";
break;
case DetectorStatus.Error:
StatusMessage = "错误 | Error";
// 获取错误信息 | Get error information
DetectorResult error = _detectorService.GetLastError();
_logger.Error(null, $"探测器错误: {error.ErrorMessage}");
break;
}
}
10. 异常处理 | Exception Handling
10.1 DetectorResult 结果处理
所有操作返回 DetectorResult 对象:
DetectorResult result = await _detectorService.InitializeAsync();
if (result.IsSuccess)
{
// 操作成功 | Operation successful
_logger.Info("操作成功");
}
else
{
// 操作失败 | Operation failed
string error = result.ErrorMessage;
int errorCode = result.ErrorCode;
Exception exception = result.Exception;
_logger.Error(exception, $"操作失败: {error}, 错误码: {errorCode}");
}
10.2 异常捕获
try
{
DetectorResult result = await _detectorService.AcquireSingleFrameAsync();
// 处理结果 | Process result
}
catch (TimeoutException ex)
{
// 超时异常 | Timeout exception
_logger.Error(ex, "操作超时");
MessageBox.Show("操作超时,请检查探测器连接", "超时",
MessageBoxButton.OK, MessageBoxImage.Warning);
}
catch (InvalidOperationException ex)
{
// 无效操作异常 | Invalid operation exception
_logger.Error(ex, "无效操作");
MessageBox.Show($"无效操作: {ex.Message}", "错误",
MessageBoxButton.OK, MessageBoxImage.Error);
}
catch (Exception ex)
{
// 其他异常 | Other exceptions
_logger.Error(ex, "未知错误");
MessageBox.Show($"发生错误: {ex.Message}", "错误",
MessageBoxButton.OK, MessageBoxImage.Error);
}
11. 日志记录 | Logging
模块使用 Serilog 进行结构化日志记录:
11.1 日志级别
- Debug: 详细的调试信息(帧采集、状态变化等)
- Info: 一般信息(初始化成功、采集开始等)
- Warn: 警告信息(状态异常、参数警告等)
- Error: 错误信息(操作失败、通讯异常等)
- Fatal: 致命错误(系统崩溃等)
11.2 日志示例
// 信息日志 | Info log
_logger.Info("探测器初始化成功 | Detector initialized successfully");
// 警告日志 | Warning log
_logger.Warn("探测器未就绪 | Detector not ready");
// 错误日志 | Error log
_logger.Error(ex, $"操作失败: {ex.Message} | Operation failed: {ex.Message}");
// 调试日志 | Debug log
_logger.Debug($"采集帧 {frameNumber} | Acquired frame {frameNumber}");
12. 性能优化建议 | Performance Optimization Suggestions
12.1 图像处理
避免在 UI 线程处理大图像:
// 推荐:在后台线程处理图像 | Recommended: Process images in background thread
await Task.Run(() =>
{
// 图像处理逻辑 | Image processing logic
ProcessImage(imageData);
});
12.2 异步操作
所有 I/O 操作使用异步方法:
// 正确:异步操作 | Correct: Async operation
await _detectorService.AcquireSingleFrameAsync();
// 错误:同步阻塞 | Wrong: Synchronous blocking
_detectorService.AcquireSingleFrameAsync().Wait(); // 不要这样做!
12.3 事件订阅
及时取消不再需要的事件订阅:
// 保存订阅令牌 | Save subscription token
private SubscriptionToken _imageCapturedToken;
// 订阅事件 | Subscribe to event
_imageCapturedToken = _eventAggregator.GetEvent<ImageCapturedEvent>()
.Subscribe(OnImageCaptured, ThreadOption.UIThread);
// 取消订阅 | Unsubscribe
_eventAggregator.GetEvent<ImageCapturedEvent>()
.Unsubscribe(_imageCapturedToken);
13. 故障排查 | Troubleshooting
13.1 初始化失败
问题: 探测器初始化失败
可能原因:
- 探测器 IP 地址或端口配置错误
- 探测器未启动或网络不通
- 探测器驱动未正确安装
- 配置文件参数错误
解决方案:
- 检查
App.config中的探测器连接参数 - 使用
ping命令测试探测器网络连接 - 确认探测器驱动和 SDK 已安装
- 查看日志文件获取详细错误信息
13.2 采集失败
问题: 无法采集图像
可能原因:
- 探测器未初始化
- 探测器处于错误状态
- 校正未完成
- 网络通讯异常
解决方案:
- 确认已调用
InitializeAsync()并成功 - 检查探测器状态是否为
Ready - 执行自动校正
AutoCorrectionAsync() - 检查网络连接和通讯日志
13.3 校正失败
问题: 校正操作失败
可能原因:
- 探测器未就绪
- 射线源未开启(增益校正需要)
- 采集帧数不足
- 环境光干扰
解决方案:
- 确认探测器状态为
Ready - 增益校正前确保射线源已开启
- 增加采集帧数(建议 10 帧以上)
- 检查暗场环境,避免光线干扰
13.4 通讯超时
问题: 操作超时
可能原因:
- 网络延迟过高
- 探测器响应慢
- 超时配置过短
解决方案:
- 检查网络连接质量
- 增加配置文件中的超时时间
- 检查探测器负载情况
14. 注意事项 | Notes
- 线程安全:
IDetectorService是单例,多个 ViewModel 共享同一个实例 - 异步操作: 所有操作都是异步的,避免阻塞 UI 线程
- 状态检查: 操作前检查探测器状态,确保处于正确状态
- 资源释放: 应用退出时探测器会自动停止采集并释放资源
- 事件订阅: 记得在 ViewModel 销毁时取消事件订阅
- 校正顺序: 建议按照暗场→增益→坏像素的顺序进行校正
- 日志记录: 所有关键操作都有详细的日志记录
- 错误处理: 始终检查
DetectorResult.IsSuccess并处理错误
15. 文档索引 | Documentation Index
- GUIDENCE.md - 本文档,详细使用指南
- README.md - 项目概述和快速参考
- App.config.example - 配置文件示例
16. 技术支持 | Technical Support
如有问题或建议,请联系项目维护团队。
最后更新 | Last Updated: 2026-03-11