Explorar el Código

新增相机标定接口、数据模型及服务实现

本次提交引入了相机标定相关的核心代码,包括:
- 新增 ICameraCalibrationService 接口,定义标定与坐标变换方法;
- 新增 CameraCalibrationResult 数据模型,封装标定参数与结果信息;
- 新增 CameraCalibrationService 服务,实现接口方法(当前为占位实现);
- 更新 csproj 文件,添加相关文件引用。

为后续集成 OpenCV 标定算法和机器人视觉坐标系转换奠定基础。
孝锋 徐 hace 8 meses
padre
commit
c7b0b9d08d

+ 1 - 0
TeamAAS-VM/App.xaml.cs

@@ -114,6 +114,7 @@ namespace TeamAAS_VP
             containerRegistry.RegisterSingleton<IProductService, ProductService>();
             containerRegistry.RegisterSingleton<IRemoteCommandService, RemoteCommandService>();
             containerRegistry.RegisterSingleton<ILightManagerService, LightManagerService>();
+            containerRegistry.RegisterSingleton<ICameraCalibrationService, CameraCalibrationService>();
             containerRegistry.RegisterSingleton<Management>();
 
             // Register system database service and initializer

+ 61 - 0
TeamAAS-VM/Interfaces/ICameraCalibrationService.cs

@@ -0,0 +1,61 @@
+using System;
+using System.Threading.Tasks;
+using OpenCvSharp;
+using TeamAAS_VP.Models;
+
+namespace TeamAAS_VP.Interfaces
+{
+    /// <summary>
+    /// 提供相机标定与像素坐标系/机器人坐标系变换的服务接口。
+    /// 注意:此接口只定义方法签名与文档,具体算法与实现由实现类提供。
+    /// </summary>
+    public interface ICameraCalibrationService : IDisposable
+    {
+        /// <summary>
+        /// 使用一组棋盘格或标定图像执行相机标定。返回是否成功。
+        /// </summary>
+        /// <param name="images">用于标定的灰度或彩色图像阵列。</param>
+        /// <param name="patternSize">棋盘格内角点数(cols, rows)。</param>
+        /// <param name="squareSize">物理上每格的尺寸(单位:毫米或用户约定单位)。</param>
+        /// <returns>如果标定成功,返回标定结果对象;否则返回 null 或抛出异常(视实现而定)。</returns>
+        Task<CameraCalibrationResult> CalibrateAsync(Mat[] images, OpenCvSharp.Size patternSize, double squareSize);
+
+        /// <summary>
+        /// 根据已标定的相机参数,将像素坐标转换到相机坐标系(例如相机局部三维坐标)。
+        /// </summary>
+        /// <param name="pixel">像素坐标(x,y)。</param>
+        /// <param name="depth">该像素的深度(或Z)值,若无则由实现者定义默认行为。</param>
+        /// <returns>相机坐标系下的三维点。</returns>
+        System.Numerics.Vector3 PixelToCameraPoint(System.Numerics.Vector2 pixel, double depth = 1.0);
+
+        /// <summary>
+        /// 将相机坐标系中的三维点变换到机器人坐标系,使用当前估计的外参/变换矩阵。
+        /// </summary>
+        /// <param name="cameraPoint">相机坐标系三维点。</param>
+        /// <returns>机器人坐标系三维点。</returns>
+        System.Numerics.Vector3 CameraToRobotPoint(System.Numerics.Vector3 cameraPoint);
+
+        /// <summary>
+        /// 将机器人坐标系中的三维点变换到相机坐标系。
+        /// </summary>
+        /// <param name="robotPoint">机器人坐标系三维点。</param>
+        /// <returns>相机坐标系三维点。</returns>
+        System.Numerics.Vector3 RobotToCameraPoint(System.Numerics.Vector3 robotPoint);
+
+        /// <summary>
+        /// 估算相机中心(相机在机器人坐标系下的位置),通常基于标定得到的外参或一组已知对应点。
+        /// </summary>
+        /// <returns>机器人坐标系下的相机中心位置。</returns>
+        System.Numerics.Vector3 EstimateCameraCenter();
+
+        /// <summary>
+        /// 获取当前标定结果(如果存在)。
+        /// </summary>
+        CameraCalibrationResult CurrentCalibration { get; }
+
+        /// <summary>
+        /// 清除/重置当前的标定结果与内部状态。
+        /// </summary>
+        void Reset();
+    }
+}

+ 58 - 0
TeamAAS-VM/Models/CameraCalibrationResult.cs

@@ -0,0 +1,58 @@
+using System;
+
+namespace TeamAAS_VP.Models
+{
+    /// <summary>
+    /// 相机标定结果数据传输对象。
+    /// 包含内参、畸变系数、外参等可选字段,供服务与 ViewModel 交换使用。
+    /// </summary>
+    public class CameraCalibrationResult
+    {
+        /// <summary>
+        /// 标定是否成功
+        /// </summary>
+        public bool Success { get; set; }
+
+        /// <summary>
+        /// 说明性消息或错误信息
+        /// </summary>
+        public string Message { get; set; }
+
+        /// <summary>
+        /// 相机内参矩阵(3x3),按行主序展开(长度应为9)。
+        /// 如果为空表示未设置。
+        /// </summary>
+        public double[] CameraMatrix { get; set; }
+
+        /// <summary>
+        /// 畸变系数(可包含 k1,k2,p1,p2,k3 ...)
+        /// </summary>
+        public double[] DistCoeffs { get; set; }
+
+        /// <summary>
+        /// 旋转向量或旋转矩阵的压缩表示(视实现而定)。
+        /// </summary>
+        public double[] Rotation { get; set; }
+
+        /// <summary>
+        /// 平移向量(tx,ty,tz)
+        /// </summary>
+        public double[] Translation { get; set; }
+
+        /// <summary>
+        /// 标定时间戳
+        /// </summary>
+        public DateTime Timestamp { get; set; }
+
+        public CameraCalibrationResult()
+        {
+            Success = false;
+            Message = string.Empty;
+            CameraMatrix = null;
+            DistCoeffs = null;
+            Rotation = null;
+            Translation = null;
+            Timestamp = DateTime.UtcNow;
+        }
+    }
+}

+ 94 - 0
TeamAAS-VM/Services/CameraCalibrationService.cs

@@ -0,0 +1,94 @@
+using System;
+using System.Threading.Tasks;
+using OpenCvSharp;
+using TeamAAS_VP.Models;
+using System.Numerics;
+using TeamAAS_VP.Interfaces;
+
+namespace TeamAAS_VP.Services
+{
+    /// <summary>
+    /// 相机标定服务的骨架实现。实际的标定算法和数据持久化由后续实现补充。
+    /// </summary>
+    public class CameraCalibrationService : ICameraCalibrationService
+    {
+        private bool _disposed;
+
+        public CameraCalibrationResult CurrentCalibration { get; private set; }
+
+        public CameraCalibrationService()
+        {
+            // 初始化内部状态
+            CurrentCalibration = null;
+        }
+
+        public async Task<CameraCalibrationResult> CalibrateAsync(Mat[] images, OpenCvSharp.Size patternSize, double squareSize)
+        {
+            // 占位实现:调用者将补充真实标定实现。
+            // 做最小的参数检查以避免误用。
+            if (images == null) throw new ArgumentNullException(nameof(images));
+            if (images.Length == 0) throw new ArgumentException("images 不能为空", nameof(images));
+
+            // 在后台线程上执行耗时计算的占位符
+            return await Task.Run(() =>
+            {
+                // TODO: 在此实现相机标定(使用 OpenCvSharp.CalibrateCamera 等)
+                // 当前返回空结果,表示尚未实现。
+                CurrentCalibration = new CameraCalibrationResult
+                {
+                    Timestamp = DateTime.UtcNow,
+                    Success = false,
+                    Message = "未实现:请在 CameraCalibrationService 中补充标定算法。"
+                };
+
+                return CurrentCalibration;
+            });
+        }
+
+        public Vector3 PixelToCameraPoint(Vector2 pixel, double depth = 1.0)
+        {
+            // 占位:如果没有标定参数则抛出异常,避免误用
+            if (CurrentCalibration == null || !CurrentCalibration.Success) throw new InvalidOperationException("当前没有有效的标定结果。");
+
+            // TODO: 根据内参和畸变校正将像素映射到相机坐标系
+            return new Vector3((float)pixel.X, (float)pixel.Y, (float)depth);
+        }
+
+        public Vector3 CameraToRobotPoint(Vector3 cameraPoint)
+        {
+            if (CurrentCalibration == null || !CurrentCalibration.Success) throw new InvalidOperationException("当前没有有效的标定结果。");
+
+            // TODO: 使用外参(旋转+平移)将相机点变换至机器人坐标系
+            return cameraPoint;
+        }
+
+        public Vector3 RobotToCameraPoint(Vector3 robotPoint)
+        {
+            if (CurrentCalibration == null || !CurrentCalibration.Success) throw new InvalidOperationException("当前没有有效的标定结果。");
+
+            // TODO: 使用外参逆变换
+            return robotPoint;
+        }
+
+        public Vector3 EstimateCameraCenter()
+        {
+            if (CurrentCalibration == null || !CurrentCalibration.Success) throw new InvalidOperationException("当前没有有效的标定结果。");
+
+            // TODO: 根据外参估算相机在机器人坐标系中的位置
+            return new Vector3(0, 0, 0);
+        }
+
+        public void Reset()
+        {
+            CurrentCalibration = null;
+        }
+
+        public void Dispose()
+        {
+            if (_disposed) return;
+            _disposed = true;
+            // 释放任何非托管资源(如果有)
+            GC.SuppressFinalize(this);
+        }
+    }
+}

+ 3 - 0
TeamAAS-VM/TeamAAS-VP.csproj

@@ -590,6 +590,7 @@
     <Compile Include="Models\AlarmRecord.cs" />
     <Compile Include="Models\AnalysisParameters.cs" />
     <Compile Include="Models\AnalysisResult.cs" />
+    <Compile Include="Models\CameraCalibrationResult.cs" />
     <Compile Include="Models\ChessboardInfo.cs" />
     <Compile Include="Models\DataPoint.cs" />
     <Compile Include="Models\Lights\ChannelConfig.cs" />
@@ -604,6 +605,8 @@
     <Compile Include="Models\TcpConfig.cs" />
     <Compile Include="Models\UserLoginRecord.cs" />
     <Compile Include="Services\CalibrationService.cs" />
+    <Compile Include="Services\CameraCalibrationService.cs" />
+    <Compile Include="Interfaces\ICameraCalibrationService.cs" />
     <Compile Include="Services\CameraService.cs" />
     <Compile Include="Core\Cameras\AHuaCamera.cs" />
     <Compile Include="Core\Cameras\CognexCamera.cs" />