#ifndef COMMONDIALOGCAMERALEVEL_H #define COMMONDIALOGCAMERALEVEL_H #include #include #include #include #include #include #include #include #include #include "IVrEyeDevice.h" #include "VZNL_Types.h" #include "LaserDataLoader.h" #include "BasePresenter.h" namespace Ui { class CommonDialogCameraLevel; } /** * @brief 相机调平计算接口 * * 应用需要实现此接口来计算调平参数(因为每个项目的标定算法接口不同) */ class ICameraLevelCalculator { public: virtual ~ICameraLevelCalculator() = default; /** * @brief 计算平面调平参数 * @param scanData 扫描数据(多帧激光线数据) * @param planeCalib 输出:调平矩阵 (9个元素) * @param planeHeight 输出:地面高度 * @param invRMatrix 输出:逆旋转矩阵 (9个元素) * @return true: 计算成功, false: 计算失败 */ virtual bool CalculatePlaneCalibration( const std::vector>& scanData, double planeCalib[9], double& planeHeight, double invRMatrix[9]) = 0; }; /** * @brief 相机调平结果保存接口 * * 应用需要实现此接口来保存调平结果 */ class ICameraLevelResultSaver { public: virtual ~ICameraLevelResultSaver() = default; /** * @brief 保存调平结果 * @param planeCalib 调平矩阵 (9个元素) * @param planeHeight 地面高度 * @param invRMatrix 逆旋转矩阵 (9个元素) * @param cameraIndex 相机索引(1-based) * @param cameraName 相机名称 * @return true: 保存成功, false: 保存失败 */ virtual bool SaveLevelingResults(double planeCalib[9], double planeHeight, double invRMatrix[9], int cameraIndex, const QString& cameraName) = 0; /** * @brief 加载调平结果 * @param cameraIndex 相机索引(1-based) * @param cameraName 相机名称 * @param planeCalib 输出:调平矩阵 (9个元素) * @param planeHeight 输出:地面高度 * @param invRMatrix 输出:逆旋转矩阵 (9个元素) * @return true: 加载成功, false: 加载失败或无数据 */ virtual bool LoadLevelingResults(int cameraIndex, const QString& cameraName, double planeCalib[9], double& planeHeight, double invRMatrix[9]) = 0; }; /** * @brief 通用相机调平对话框 * * 用于执行相机的调平操作,计算地面校准参数并保存 * 支持多相机选择和调平 */ class CommonDialogCameraLevel : public QDialog { Q_OBJECT public: explicit CommonDialogCameraLevel(QWidget *parent = nullptr); ~CommonDialogCameraLevel(); // Delete copy constructor and assignment operator due to atomic members CommonDialogCameraLevel(const CommonDialogCameraLevel&) = delete; CommonDialogCameraLevel& operator=(const CommonDialogCameraLevel&) = delete; /** * @brief 设置相机列表和Presenter * @param cameraList 相机设备列表 * @param presenter BasePresenter指针,用于设置回调和访问相机 * @param calculator 标定计算接口 * @param resultSaver 结果保存接口 */ void SetCameraList(const std::vector>& cameraList, BasePresenter* presenter, ICameraLevelCalculator* calculator, ICameraLevelResultSaver* resultSaver); private slots: void on_btn_apply_clicked(); void on_btn_cancel_clicked(); void on_combo_camera_currentIndexChanged(int index); private: Ui::CommonDialogCameraLevel *ui; // 相机列表和名称 std::vector> m_cameraList; BasePresenter* m_presenter = nullptr; ICameraLevelCalculator* m_calculator = nullptr; ICameraLevelResultSaver* m_resultSaver = nullptr; // 扫描数据缓存 std::vector> m_scanDataCache; std::mutex m_scanDataMutex; LaserDataLoader m_dataLoader; // 数据加载器,用于释放内存 // 状态回调相关 std::atomic m_swingFinished {false}; // 摆动完成标志,同时表示扫描完成 std::atomic m_callbackRestored {false}; // 状态回调是否已恢复 // 初始化相机选择框 void initializeCameraCombo(); // 执行相机调平 bool performCameraLeveling(); // 直接使用相机接口进行扫描 bool startCameraScan(int cameraIndex); bool stopCameraScan(int cameraIndex); // 检测数据回调函数 static void StaticDetectionCallback(EVzResultDataType eDataType, SVzLaserLineData* pLaserLinePoint, void* pUserData); void DetectionCallback(EVzResultDataType eDataType, SVzLaserLineData* pLaserLinePoint); // 状态回调函数 static void StaticStatusCallback(EVzDeviceWorkStatus eStatus, void* pExtData, unsigned int nDataLength, void* pInfoParam); void StatusCallback(EVzDeviceWorkStatus eStatus, void* pExtData, unsigned int nDataLength, void* pInfoParam); // 设置和恢复状态回调 void setLevelingStatusCallback(); void restorePresenterStatusCallback(); // 处理扫描到的地面数据进行调平计算 bool calculatePlaneCalibration(double planeCalib[9], double& planeHeight, double invRMatrix[9]); // 清空扫描数据缓存 void clearScanDataCache(); // 更新调平结果显示 void updateLevelingResults(double planeCalib[9], double planeHeight, double invRMatrix[9]); // 检查并显示相机标定状态 void checkAndDisplayCalibrationStatus(int cameraIndex); }; #endif // COMMONDIALOGCAMERALEVEL_H