GrabBag/App/BinocularMark/BinocularMarkServer/BinocularMarkPresenter.h

354 lines
11 KiB
C
Raw Normal View History

2026-03-28 10:49:55 +08:00
#ifndef BINOCULARMARKPRESENTER_H
#define BINOCULARMARKPRESENTER_H
#include <QObject>
#include <QMutex>
#include <QTimer>
#include <QString>
#include <QImage>
#include <atomic>
#include <thread>
#include <memory>
#include <opencv2/opencv.hpp>
#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中配置标定文件路径:
* <CalibrationFile path="../Calib/Mark_13度/StereoCamera.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<SWD_charuco3DMark> marks,
cv::Mat leftImage,
cv::Mat rightImage,
int errorCode);
/**
* @brief 单次检测结果信号
*/
void singleDetectionResult(const TCPClient* pClient,
std::vector<SWD_charuco3DMark> 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<bool> m_bCameraConnected; // 相机是否已连接
std::atomic<bool> m_bAutoStartDetection; // 重连成功后是否自动启动检测
// 采集控制
std::atomic<bool> m_bIsDetecting; // 是否正在检测
std::atomic<bool> m_bSendContinuousResult; // 是否发送持续检测结果
std::atomic<bool> m_bSendContinuousImage; // 是否发送持续图像流
std::atomic<bool> 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