#ifndef BINOCULARMARKPRESENTER_H #define BINOCULARMARKPRESENTER_H #include #include #include #include #include #include #include #include #include #include "IGalaxyDevice.h" #include "binocularMarkCam_Export.h" #include "SG_baseDataType.h" #include "IYTCPServer.h" /** * @brief BinocularMark检测系统Presenter类 * 管理双目相机采集和标记检测算法 */ class BinocularMarkPresenter : public QObject { Q_OBJECT public: explicit BinocularMarkPresenter(QObject *parent = nullptr); ~BinocularMarkPresenter(); /** * @brief 初始化双目相机 * @return 0-成功,非0-失败 */ int initCameras(); /** * @brief 关闭双目相机 */ void closeCameras(); /** * @brief 启动采集和检测线程 * @return 0-成功,非0-失败 */ int startDetection(); /** * @brief 停止采集和检测 */ void stopDetection(); /** * @brief 是否正在检测 */ bool isDetecting() const { return m_bIsDetecting.load(); } /** * @brief 加载配置文件(XML格式) * * 从config.xml加载应用配置(端口、相机参数、Mark参数等), * 然后自动加载双目标定文件StereoCamera.xml。 * * XML格式参考:WorkpieceProjectConfig/config/config.xml * * 重要:必须在config.xml中配置标定文件路径: * * * @param configFilePath 配置文件路径 * @return true-成功,false-失败 */ bool loadConfiguration(const QString& configFilePath); /** * @brief 加载双目标定参数(OpenCV XML格式) * * 从StereoCamera.xml文件读取所有标定参数: * - 左右相机内参矩阵和畸变系数 * - 双目校正参数(R1, R2, P1, P2, Q) * * 注意:此文件为只读,不应修改。标定参数由标定工具生成。 * * @param calibFilePath 标定文件路径(StereoCamera.xml) * @return true-成功,false-失败 */ bool loadCalibration(const QString& calibFilePath); /** * @brief 获取服务器端口 */ quint16 getServerPort() const { return m_nServerPort; } /** * @brief 设置服务器端口 */ void setServerPort(quint16 port) { m_nServerPort = port; } /** * @brief 获取Q矩阵数据(用于算法) */ const cv::Mat& getQMatrix() const { return m_Q; } /** * @brief 设置Mark配置信息 */ void setMarkInfo(const SWD_BQ_CharucoMarkInfo& markInfo) { m_markInfo = markInfo; } /** * @brief 设置Board配置信息 */ void setBoardInfo(const SWD_BQ_MarkBoardInfo& boardInfo) { m_boardInfo = boardInfo; } public slots: /** * @brief 处理单次检测请求(返回图像+Mark) */ void handleSingleDetection(const TCPClient* pClient); /** * @brief 处理单次图像请求(只返回图像) */ void handleSingleImage(const TCPClient* pClient); /** * @brief 处理开始持续工作请求 */ void handleStartWork(); /** * @brief 处理停止持续工作请求 */ void handleStopWork(); /** * @brief 处理开始持续图像流请求 */ void handleStartContinuousImage(); /** * @brief 处理停止持续图像流请求 */ void handleStopContinuousImage(); /** * @brief 处理设置曝光时间请求(同时设置左右相机) * @param exposureTime 曝光时间 */ void handleSetExposureTime(double exposureTime); /** * @brief 处理设置增益请求(同时设置左右相机) * @param gain 增益 */ void handleSetGain(double gain); /** * @brief 处理设置左相机曝光时间请求 * @param exposureTime 曝光时间 */ void handleSetLeftExposureTime(double exposureTime); /** * @brief 处理设置右相机曝光时间请求 * @param exposureTime 曝光时间 */ void handleSetRightExposureTime(double exposureTime); /** * @brief 处理设置左相机增益请求 * @param gain 增益 */ void handleSetLeftGain(double gain); /** * @brief 处理设置右相机增益请求 * @param gain 增益 */ void handleSetRightGain(double gain); /** * @brief 处理获取相机信息请求 * @param pClient 客户端指针 * @param camera 相机标识("left"或"right") */ void handleGetCameraInfo(const TCPClient* pClient, const QString& camera); /** * @brief 处理获取标定矩阵请求 * @param pClient 客户端指针 */ void handleGetCalibration(const TCPClient* pClient); /** * @brief 处理设置标定矩阵请求 * @param pClient 客户端指针 * @param calibrationXml 标定矩阵XML内容 */ void handleSetCalibration(const TCPClient* pClient, const QString& calibrationXml); signals: /** * @brief 检测结果信号 * @param marks 检测到的3D标记列表 * @param leftImage 左相机图像 * @param rightImage 右相机图像 * @param errorCode 错误码 */ void detectionResult(std::vector marks, cv::Mat leftImage, cv::Mat rightImage, int errorCode); /** * @brief 单次检测结果信号 */ void singleDetectionResult(const TCPClient* pClient, std::vector marks, cv::Mat leftImage, cv::Mat rightImage, int errorCode); /** * @brief 单次图像结果信号 */ void singleImageResult(const TCPClient* pClient, cv::Mat leftImage, cv::Mat rightImage); /** * @brief 相机信息结果信号 * @param pClient 客户端指针 * @param camera 相机标识("left"或"right") * @param serialNumber 序列号 * @param modelName 型号 * @param displayName 显示名称 * @param exposureTime 曝光时间 * @param gain 增益 */ void cameraInfoResult(const TCPClient* pClient, const QString& camera, const QString& serialNumber, const QString& modelName, const QString& displayName, double exposureTime, double gain); /** * @brief 标定矩阵结果信号 * @param pClient 客户端指针 * @param calibrationXml 标定矩阵XML字符串 */ void calibrationMatrixResult(const TCPClient* pClient, const QString& calibrationXml); /** * @brief 相机连接状态变化信号 * @param connected true-已连接,false-未连接 */ void cameraConnectionChanged(bool connected); private slots: /** * @brief 相机重连定时器槽函数 */ void onCameraReconnectTimer(); private: /** * @brief 采集线程函数 */ void captureThreadFunc(); /** * @brief 尝试连接相机(辅助函数) * @return 0-成功,非0-失败 */ int tryConnectCameras(); /** * @brief 左相机图像回调 */ void leftCameraCallback(const GalaxyImageData& imageData); /** * @brief 右相机图像回调 */ void rightCameraCallback(const GalaxyImageData& imageData); /** * @brief 处理双目图像并进行检测 */ void processImages(); /** * @brief GalaxyImageData转换为cv::Mat */ cv::Mat imageDataToMat(const GalaxyImageData& imageData); private: // 双目相机设备对象 IGalaxyDevice* m_pLeftCamera; // 左相机 IGalaxyDevice* m_pRightCamera; // 右相机 // 相机重连机制 QTimer* m_pCameraReconnectTimer; // 相机重连定时器 std::atomic m_bCameraConnected; // 相机是否已连接 std::atomic m_bAutoStartDetection; // 重连成功后是否自动启动检测 // 采集控制 std::atomic m_bIsDetecting; // 是否正在检测 std::atomic m_bSendContinuousResult; // 是否发送持续检测结果 std::atomic m_bSendContinuousImage; // 是否发送持续图像流 std::atomic m_bIsProcessingImage; // 是否正在处理图像(用于丢帧) std::chrono::steady_clock::time_point m_lastImageSendTime; // 上次发送图像时间(用于限制帧率) std::thread m_captureThread; // 采集线程 // 图像缓存 QMutex m_imageMutex; // 图像互斥锁 GalaxyImageData m_leftImageData; // 左相机图像数据 GalaxyImageData m_rightImageData; // 右相机图像数据 bool m_bLeftImageReady; // 左相机图像就绪标志 bool m_bRightImageReady; // 右相机图像就绪标志 // 配置参数 quint16 m_nServerPort; // TCP服务器端口 unsigned int m_nLeftCameraIndex; // 左相机索引 unsigned int m_nRightCameraIndex; // 右相机索引 std::string m_strLeftCameraSerial; // 左相机序列号(优先使用) std::string m_strRightCameraSerial; // 右相机序列号(优先使用) // 相机参数 double m_fExposureTime; // 曝光时间 double m_fGain; // 增益 // 双目标定参数(OpenCV标定得到的完整参数) cv::Mat m_cameraMatrixL; // 左相机内参矩阵 3x3 cv::Mat m_distCoeffsL; // 左相机畸变系数 cv::Mat m_cameraMatrixR; // 右相机内参矩阵 3x3 cv::Mat m_distCoeffsR; // 右相机畸变系数 cv::Mat m_R1; // 左相机校正旋转矩阵 3x3 cv::Mat m_R2; // 右相机校正旋转矩阵 3x3 cv::Mat m_P1; // 左相机投影矩阵 3x4 cv::Mat m_P2; // 右相机投影矩阵 3x4 cv::Mat m_Q; // 视差到深度的映射矩阵 4x4 // Mark检测配置参数 SWD_BQ_CharucoMarkInfo m_markInfo; // Mark板配置 SWD_BQ_MarkBoardInfo m_boardInfo; // Board配置 double m_disparityOffset; // 视差偏移 // 标定文件路径 QString m_calibrationFilePath; // 标定文件完整路径 }; #endif // BINOCULARMARKPRESENTER_H