GrabBag/App/BinocularMark/BinocularMarkApp/BinocularMarkPresenter.h
2025-12-20 16:18:12 +08:00

354 lines
11 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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