354 lines
11 KiB
C++
354 lines
11 KiB
C++
#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
|