From 9bc2133e2467dc89ebebc43528d3d21c7af40904 Mon Sep 17 00:00:00 2001 From: tangchao0503 <735056338@qq.com> Date: Thu, 10 Sep 2026 13:48:07 +0800 Subject: [PATCH] =?UTF-8?q?add=EF=BC=8C=E5=B1=B1=E5=9C=B0=E6=89=80?= =?UTF-8?q?=E8=B4=A1=E5=98=8E=E5=B1=B110=EF=BC=9A=20=E4=BC=98=E5=8C=96rgb?= =?UTF-8?q?=E7=9B=B8=E6=9C=BA=E6=8E=A7=E5=88=B6=EF=BC=8C=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=87=87=E9=9B=86=E8=A7=86=E9=A2=91=E5=92=8C=E7=85=A7=E7=89=87?= =?UTF-8?q?=E7=9A=84=E9=80=BB=E8=BE=91=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HPPA/AppSettings.cpp | 25 +++ HPPA/AppSettings.h | 7 + HPPA/HPPA.cpp | 4 + HPPA/HPPA.vcxproj | 2 + HPPA/RgbCameraCaptureCoordinator.cpp | 246 +++++++++++++++++++++++++++ HPPA/RgbCameraCaptureCoordinator.h | 69 ++++++++ HPPA/RgbCameraOperation.cpp | 227 +++++++++++++++++++++++- HPPA/RgbCameraOperation.h | 39 ++++- HPPA/imageProcessor.cpp | 2 +- HPPA/rgbCamera.ui | 113 ++++++++++-- HPPA/rgbCameraWindow.cpp | 186 ++++++++++++++++++-- HPPA/rgbCameraWindow.h | 38 ++++- 12 files changed, 912 insertions(+), 46 deletions(-) create mode 100644 HPPA/RgbCameraCaptureCoordinator.cpp create mode 100644 HPPA/RgbCameraCaptureCoordinator.h diff --git a/HPPA/AppSettings.cpp b/HPPA/AppSettings.cpp index e7c07a8..aa966ef 100644 --- a/HPPA/AppSettings.cpp +++ b/HPPA/AppSettings.cpp @@ -120,6 +120,31 @@ void AppSettings::setFiberImagerDataFolder(const QString& path) m_settings.setValue("General/FiberImagerDataFolder", path); } +QString AppSettings::rgbCameraDataFolder() const +{ + QString path = m_settings.value("RgbCamera/RgbCameraDataFolder", "D:").toString(); + if (path.isEmpty()) + { + return QCoreApplication::applicationDirPath() + "/CapturedRgbCameraData/"; + } + return path; +} + +void AppSettings::setRgbCameraDataFolder(const QString& path) +{ + m_settings.setValue("RgbCamera/RgbCameraDataFolder", path); +} + +QString AppSettings::rgbCameraFileName() const +{ + return m_settings.value("RgbCamera/FileName", "test").toString(); +} + +void AppSettings::setRgbCameraFileName(const QString& name) +{ + m_settings.setValue("RgbCamera/FileName", name); +} + double AppSettings::scanSpeed() const { return m_settings.value("OneMotorControl/ScanSpeed", kDefaultScanSpeed).toDouble(); diff --git a/HPPA/AppSettings.h b/HPPA/AppSettings.h index 5fbf564..1f062fe 100644 --- a/HPPA/AppSettings.h +++ b/HPPA/AppSettings.h @@ -38,6 +38,13 @@ public: QString FiberImagerDataFolder() const; void setFiberImagerDataFolder(const QString& path); + QString rgbCameraDataFolder() const; + void setRgbCameraDataFolder(const QString& path); + + // RGB相机文件名 + QString rgbCameraFileName() const; + void setRgbCameraFileName(const QString& name); + // 扫描速度 double scanSpeed() const; void setScanSpeed(double value); diff --git a/HPPA/HPPA.cpp b/HPPA/HPPA.cpp index 53e7417..82f1dce 100644 --- a/HPPA/HPPA.cpp +++ b/HPPA/HPPA.cpp @@ -1166,6 +1166,9 @@ void HPPA::onGonggashanRecord(QString posInfo) } onStartRecordStep1(); + + //采集rgb图像 + } void HPPA::recordFromRobotArm(int fileCounter) @@ -1667,6 +1670,7 @@ void HPPA::createGonggaRotatingPlatformScenario() m_tabManager->showTab(m_hic); m_tabManager->showTab(m_ic); + m_tabManager->showTab(m_rgbCameraControlWindow); m_tabManager->showTab(m_fodisWindow); m_tabManager->showTab(m_omc); m_tabManager->showTab(m_gonggaShanRecordCtl); diff --git a/HPPA/HPPA.vcxproj b/HPPA/HPPA.vcxproj index 5fa1c3b..1592e1a 100644 --- a/HPPA/HPPA.vcxproj +++ b/HPPA/HPPA.vcxproj @@ -160,6 +160,7 @@ + @@ -289,6 +290,7 @@ + diff --git a/HPPA/RgbCameraCaptureCoordinator.cpp b/HPPA/RgbCameraCaptureCoordinator.cpp new file mode 100644 index 0000000..a112cce --- /dev/null +++ b/HPPA/RgbCameraCaptureCoordinator.cpp @@ -0,0 +1,246 @@ +#include "stdafx.h" +#include "RgbCameraCaptureCoordinator.h" +#include "RgbCameraOperation.h" +#include "AppSettings.h" + +RgbCameraCaptureCoordinator::RgbCameraCaptureCoordinator(RgbCameraOperation* rgbCamera, QObject* parent) + : QObject(parent) + , m_rgbCamera(rgbCamera) + , m_captureMode(None) + , m_isCapturing(false) + , m_isCameraOpened(false) + , m_pendingOpenCamera(false) + , m_pendingMode(None) +{ + if (m_rgbCamera) + { + connect(m_rgbCamera, &RgbCameraOperation::CamOpenedSignal, + this, &RgbCameraCaptureCoordinator::onCameraOpened); + connect(m_rgbCamera, &RgbCameraOperation::CamClosedSignal, + this, &RgbCameraCaptureCoordinator::onCameraClosed); + connect(m_rgbCamera, &RgbCameraOperation::VideoRecordingStartedSignal, + this, &RgbCameraCaptureCoordinator::onVideoRecordingStarted); + connect(m_rgbCamera, &RgbCameraOperation::VideoRecordingStoppedSignal, + this, &RgbCameraCaptureCoordinator::onVideoRecordingStopped); + + connect(this, &RgbCameraCaptureCoordinator::openCameraSignal, + m_rgbCamera, &RgbCameraOperation::OpenCamera, Qt::QueuedConnection); + connect(this, &RgbCameraCaptureCoordinator::closeCameraSignal, + m_rgbCamera, &RgbCameraOperation::CloseCamera, Qt::QueuedConnection); + connect(this, &RgbCameraCaptureCoordinator::startVideoRecordingSignal, + m_rgbCamera, &RgbCameraOperation::startVideoRecording, Qt::QueuedConnection); + connect(this, &RgbCameraCaptureCoordinator::stopVideoRecordingSignal, + m_rgbCamera, &RgbCameraOperation::stopVideoRecording, Qt::QueuedConnection); + connect(this, &RgbCameraCaptureCoordinator::startPhotoSaveTimerSignal, + m_rgbCamera, &RgbCameraOperation::startPhotoSaveTimer, Qt::QueuedConnection); + connect(this, &RgbCameraCaptureCoordinator::stopPhotoSaveTimerSignal, + m_rgbCamera, &RgbCameraOperation::stopPhotoSaveTimer, Qt::QueuedConnection); + } +} + +RgbCameraCaptureCoordinator::~RgbCameraCaptureCoordinator() +{ + cleanup(); +} + +void RgbCameraCaptureCoordinator::startVideoCapture() +{ + QMutexLocker locker(&m_dataMutex); + + if (m_isCapturing) + { + if (m_captureMode == Video) + { + //emit errorOccurred(QStringLiteral("视频正在采集中")); + return; + } + else + { + //emit errorOccurred(QStringLiteral("正在执行其他采集操作")); + return; + } + } + + m_pendingOpenCamera = true; + m_pendingMode = Video; + + openCamera(); +} + +void RgbCameraCaptureCoordinator::stopVideoCapture() +{ + QMutexLocker locker(&m_dataMutex); + + if (m_captureMode != Video || !m_isCapturing) + { + //emit errorOccurred(QStringLiteral("视频未在采集中")); + return; + } + + if (m_rgbCamera) + { + emit stopVideoRecordingSignal(); + closeCamera(); + } +} + +void RgbCameraCaptureCoordinator::startPhotoCapture() +{ + QMutexLocker locker(&m_dataMutex); + + if (m_isCapturing) + { + if (m_captureMode == Photo) + { + //emit errorOccurred(QStringLiteral("照片正在采集中")); + return; + } + else + { + //emit errorOccurred(QStringLiteral("正在执行其他采集操作")); + return; + } + } + + m_pendingOpenCamera = true; + m_pendingMode = Photo; + + openCamera(); +} + +void RgbCameraCaptureCoordinator::stopPhotoCapture() +{ + QMutexLocker locker(&m_dataMutex); + + if (m_captureMode != Photo || !m_isCapturing) + { + return; + } + + emit stopPhotoSaveTimerSignal(); + emit captureStopped(Photo); + closeCamera(); +} + +void RgbCameraCaptureCoordinator::openCamera() +{ + if (!m_rgbCamera) + { + emit cameraOpenFailed(QStringLiteral("RGB相机对象未初始化")); + return; + } + + if (m_isCameraOpened) + { + onCameraOpened(); + return; + } + + emit openCameraSignal(); +} + +void RgbCameraCaptureCoordinator::closeCamera() +{ + if (!m_rgbCamera) + { + return; + } + + if (m_isCameraOpened) + { + emit closeCameraSignal(); + } + else + { + m_isCameraOpened = false; + m_isCapturing = false; + m_captureMode = None; + } +} + +void RgbCameraCaptureCoordinator::cleanup() +{ + QMutexLocker locker(&m_dataMutex); + + if (m_rgbCamera && m_isCapturing) + { + if (m_captureMode == Video) + { + emit stopVideoRecordingSignal(); + } + } + + closeCamera(); +} + +void RgbCameraCaptureCoordinator::onCameraOpened() +{ + //QMutexLocker locker(&m_dataMutex); + + m_isCameraOpened = true; + emit cameraOpened(); + + qDebug() << "Camera opened. Pending open camera: " << m_pendingOpenCamera << ", Pending mode: " << m_pendingMode; + if (!m_pendingOpenCamera) + { + return; + } + qDebug() << "Camera opened. Pending open camera: --------------------------------------------"; + + m_pendingOpenCamera = false; + CaptureMode mode = m_pendingMode; + m_pendingMode = None; + + m_captureMode = mode; + m_isCapturing = true; + + if (mode == Video) + { + emit startVideoRecordingSignal(); + } + else if (mode == Photo) + { + emit captureStarted(Photo); + emit startPhotoSaveTimerSignal(); + } +} + +void RgbCameraCaptureCoordinator::onCameraClosed() +{ + QMutexLocker locker(&m_dataMutex); + + m_isCameraOpened = false; + + CaptureMode previousMode = m_captureMode; + + if (m_isCapturing) + { + emit captureStopped(previousMode); + } + + m_isCapturing = false; + m_captureMode = None; + + emit cameraClosed(); +} + +void RgbCameraCaptureCoordinator::onVideoRecordingStarted() +{ + QMutexLocker locker(&m_dataMutex); + + emit captureStarted(Video); +} + +void RgbCameraCaptureCoordinator::onVideoRecordingStopped() +{ + QMutexLocker locker(&m_dataMutex); + + emit captureStopped(Video); + + emit stopVideoRecordingSignal(); + closeCamera(); +} + +void RgbCameraCaptureCoordinator::onPhotoCaptured() +{ +} diff --git a/HPPA/RgbCameraCaptureCoordinator.h b/HPPA/RgbCameraCaptureCoordinator.h new file mode 100644 index 0000000..b8f25cc --- /dev/null +++ b/HPPA/RgbCameraCaptureCoordinator.h @@ -0,0 +1,69 @@ +#pragma once + +#include +#include +#include + +class RgbCameraOperation; + +class RgbCameraCaptureCoordinator : public QObject +{ + Q_OBJECT + +public: + enum CaptureMode { None = 0, Video, Photo }; + Q_ENUM(CaptureMode) + + explicit RgbCameraCaptureCoordinator(RgbCameraOperation* rgbCamera, QObject* parent = nullptr); + ~RgbCameraCaptureCoordinator(); + + // 视频采集控制 + Q_INVOKABLE void startVideoCapture(); + Q_INVOKABLE void stopVideoCapture(); + + // 照片采集控制 + Q_INVOKABLE void startPhotoCapture(); + Q_INVOKABLE void stopPhotoCapture(); + + // 状态查询 + CaptureMode getCurrentMode() const { return m_captureMode; } + bool isCapturing() const { return m_isCapturing; } + bool isCameraOpened() const { return m_isCameraOpened; } + +Q_SIGNALS: + void captureStarted(CaptureMode mode); + void captureStopped(CaptureMode mode); + void cameraOpened(); + void cameraClosed(); + void cameraOpenFailed(const QString& error); + void errorOccurred(const QString& error); + void photoCaptured(const QString& filePath); + + void openCameraSignal(); + void closeCameraSignal(); + void startVideoRecordingSignal(); + void stopVideoRecordingSignal(); + void startPhotoSaveTimerSignal(); + void stopPhotoSaveTimerSignal(); + +public Q_SLOTS: + void openCamera(); + void closeCamera(); + +private Q_SLOTS: + void onCameraOpened(); + void onCameraClosed(); + void onVideoRecordingStarted(); + void onVideoRecordingStopped(); + void onPhotoCaptured(); + void cleanup(); + +private: + RgbCameraOperation* m_rgbCamera; + CaptureMode m_captureMode; + bool m_isCapturing; + bool m_isCameraOpened; + bool m_pendingOpenCamera;//指示相机是否是带目的的打开:带目的打开true(打开就要录像+m_pendingMode),还是手动打开(false,不带目的) + CaptureMode m_pendingMode; + mutable QMutex m_dataMutex; +}; diff --git a/HPPA/RgbCameraOperation.cpp b/HPPA/RgbCameraOperation.cpp index 9c2cdbc..bc4c0de 100644 --- a/HPPA/RgbCameraOperation.cpp +++ b/HPPA/RgbCameraOperation.cpp @@ -1,15 +1,55 @@ #include "stdafx.h" #include "RgbCameraOperation.h" +#include "AppSettings.h" RgbCameraOperation::RgbCameraOperation() { cam = nullptr; m_ImageProcessor = new ImageProcessor(); m_func = nullptr; + m_videoWriter = nullptr; + m_isRecording = false; + + m_captureTimer = new QTimer(this); + connect(m_captureTimer, &QTimer::timeout, this, &RgbCameraOperation::onCaptureFrame); + + m_photoSaveTimer = new QTimer(this); + m_photoSaveTimer->setSingleShot(false); + connect(m_photoSaveTimer, &QTimer::timeout, this, &RgbCameraOperation::onPhotoSaveTimeout); } RgbCameraOperation::~RgbCameraOperation() { + if (m_photoSaveTimer != nullptr) + { + m_photoSaveTimer->stop(); + //delete m_photoSaveTimer; + m_photoSaveTimer = nullptr; + } + + if (m_captureTimer != nullptr) + { + m_captureTimer->stop(); + //delete m_captureTimer; + m_captureTimer = nullptr; + } + + if (m_videoWriter != nullptr) + { + if (m_isRecording) + { + m_videoWriter->release(); + } + delete m_videoWriter; + m_videoWriter = nullptr; + } + + if (cam != nullptr) + { + cam->release(); + delete cam; + cam = nullptr; + } } void RgbCameraOperation::OpenCamera() @@ -17,21 +57,80 @@ void RgbCameraOperation::OpenCamera() std::cout << "打开摄像头+++++++++++++++++++++++++++++++++++++++++++" << std::endl; cam = new cv::VideoCapture(0); + // 设置摄像头分辨率为最高可用分辨率 + int width = 640;//1920 + int height = 480;//1080 + cam->set(cv::CAP_PROP_FRAME_WIDTH, width); + cam->set(cv::CAP_PROP_FRAME_HEIGHT, height); + + // 验证实际设置的分辨率 + double actualWidth = cam->get(cv::CAP_PROP_FRAME_WIDTH); + double actualHeight = cam->get(cv::CAP_PROP_FRAME_HEIGHT); + std::cout << "摄像头分辨率设置为: " << actualWidth << "x" << actualHeight << std::endl; + record = true; - while (record) - { - //std::cout << "采集影像+++++++++++++++++++++++++++++++++++++++++++" << std::endl; - cam->read(frame); - m_qImage = m_ImageProcessor->Mat2QImage(frame); + // 使用定时器定期获取图像,不再阻塞线程 + m_captureTimer->start(33); // ~30fps + m_frameCounter = 0; +} - emit PlotSignal(); +void RgbCameraOperation::onCaptureFrame() +{ + if (!record || cam == nullptr || !cam->isOpened()) + { + return; } - cam->release(); + cam->read(frame); + m_frameCounter++; + if (m_frameCounter == 1) + { + emit CamOpenedSignal(); + } - emit CamOpenedSignal(); + // 保存视频逻辑:如果正在录制,将当前帧写入视频 + if (m_isRecording && m_videoWriter != nullptr && !frame.empty()) + { + m_videoWriter->write(frame); + } + m_qImage = m_ImageProcessor->Mat2QImage(frame.clone()); + emit PlotSignal(); +} + +void RgbCameraOperation::onPhotoSaveTimeout() +{ + if (m_qImage.isNull()) + { + std::cerr << "保存图片失败:当前没有可用的图像数据" << std::endl; + return; + } + + QString timestamp = QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss_zzz"); + QString prefix = AppSettings::instance().rgbCameraFileName(); + QString fileName = QString("%1_rgb_%2.jpg").arg(prefix).arg(timestamp); + QString fullPath = AppSettings::instance().rgbCameraDataFolder() + QDir::separator() + fileName; + + if (m_qImage.save(fullPath, "JPG", 95)) + { + std::cout << "图片已保存: " << fullPath.toStdString() << std::endl; + emit photoSavedSignal(fullPath); + } + else + { + std::cerr << "保存图片失败: " << fullPath.toStdString() << std::endl; + } +} + +void RgbCameraOperation::startPhotoSaveTimer() +{ + m_photoSaveTimer->start(2000); // 每2秒保存一张照片 +} + +void RgbCameraOperation::stopPhotoSaveTimer() +{ + m_photoSaveTimer->stop(); } void RgbCameraOperation::OpenCamera_callback() @@ -66,5 +165,117 @@ void RgbCameraOperation::CloseCamera() record = false; + // 停止定时器 + m_captureTimer->stop(); + m_photoSaveTimer->stop(); + + // 停止视频录制 + if (m_isRecording) + { + stopVideoRecording(); + } + + // 释放摄像头 + if (cam != nullptr) + { + cam->release(); + //delete cam; + cam = nullptr; + } + emit CamClosedSignal(); } + +void RgbCameraOperation::saveImage() +{ + if (m_qImage.isNull()) + { + std::cerr << "保存图片失败:当前没有可用的图像数据" << std::endl; + return; + } + + // 生成带时间戳的文件名 + QString timestamp = QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss_zzz"); + QString prefix = AppSettings::instance().rgbCameraFileName(); + QString fileName = QString("%1_rgb_%2.jpg").arg(prefix).arg(timestamp); + QString fullPath = AppSettings::instance().rgbCameraDataFolder() + QDir::separator() + fileName; + + // 保存为 JPG 格式 + if (m_qImage.save(fullPath, "JPG", 95)) + { + std::cout << "图片已保存: " << fullPath.toStdString() << std::endl; + } + else + { + std::cerr << "保存图片失败: " << fullPath.toStdString() << std::endl; + } +} + +void RgbCameraOperation::startVideoRecording() +{ + if (m_isRecording) + { + std::cout << "视频已经在录制中" << std::endl; + return; + } + + if (frame.empty()) + { + std::cerr << "开始录制失败:当前没有可用的帧数据" << std::endl; + return; + } + + // 释放旧的 VideoWriter + if (m_videoWriter != nullptr) + { + delete m_videoWriter; + m_videoWriter = nullptr; + } + + // 生成带时间戳的视频文件名 + QString timestamp = QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss"); + QString prefix = AppSettings::instance().rgbCameraFileName(); + QString fileName = QString("%1_video_%2.avi").arg(prefix).arg(timestamp); + QString fullPath = AppSettings::instance().rgbCameraDataFolder() + QDir::separator() + fileName; + + // 获取视频编码器和帧大小 + int fourcc = cv::VideoWriter::fourcc('M', 'J', 'P', 'G'); // Motion-JPEG 编码器 + cv::Size frameSize = frame.size(); + + // 创建 VideoWriter + m_videoWriter = new cv::VideoWriter(fullPath.toStdString(), fourcc, 30.0, frameSize); + + if (!m_videoWriter->isOpened()) + { + std::cerr << "创建视频写入器失败: " << fullPath.toStdString() << std::endl; + delete m_videoWriter; + m_videoWriter = nullptr; + return; + } + + m_isRecording = true; + std::cout << "开始录制视频: " << fullPath.toStdString() << std::endl; + + emit VideoRecordingStartedSignal(); +} + +void RgbCameraOperation::stopVideoRecording() +{ + if (!m_isRecording) + { + std::cout << "视频没有在录制" << std::endl; + return; + } + + if (m_videoWriter != nullptr) + { + m_videoWriter->release(); + //delete m_videoWriter; + m_videoWriter = nullptr; + } + + m_isRecording = false; + std::cout << "停止录制视频" << std::endl; + + emit VideoRecordingStoppedSignal(); +} diff --git a/HPPA/RgbCameraOperation.h b/HPPA/RgbCameraOperation.h index 334172e..758b6e2 100644 --- a/HPPA/RgbCameraOperation.h +++ b/HPPA/RgbCameraOperation.h @@ -4,6 +4,9 @@ #include #include +#include +#include +#include #include #include @@ -24,6 +27,12 @@ public: QImage m_qImage; void setCallback(void(*func)()); + // 保存图片和视频的公共接口 + void saveImage(); // 保存当前帧为图片 + void startVideoRecording(); // 开始视频录制 + void stopVideoRecording(); // 停止视频录制 + bool isRecording() const { return m_isRecording; } // 获取录制状态 + private: cv::Mat frame; cv::VideoCapture *cam; @@ -34,15 +43,33 @@ private: bool record; + // 保存图片和视频相关 + cv::VideoWriter* m_videoWriter; + bool m_isRecording; + int m_frameCounter; + + // 定时器获取图像 + QTimer* m_captureTimer; + // 定时器保存照片 + QTimer* m_photoSaveTimer; + +private slots: + void onCaptureFrame(); + void onPhotoSaveTimeout(); + +Q_SIGNALS: + void PlotSignal(); + void CamOpenedSignal(); + void CamClosedSignal(); + void VideoRecordingStartedSignal(); // 录制开始信号 + void VideoRecordingStoppedSignal(); // 录制停止信号 + void photoSavedSignal(const QString& filePath); // 照片保存成功信号 + public slots: void OpenCamera(); void OpenCamera_callback();//不使用信号而使用回调函数来通知界面刷新视频 void CloseCamera(); - -signals: - void PlotSignal(); - - void CamOpenedSignal(); - void CamClosedSignal(); + void startPhotoSaveTimer(); + void stopPhotoSaveTimer(); }; #endif // !RGBCAMERAOPERATION_H diff --git a/HPPA/imageProcessor.cpp b/HPPA/imageProcessor.cpp index 57972b9..dcce648 100644 --- a/HPPA/imageProcessor.cpp +++ b/HPPA/imageProcessor.cpp @@ -109,7 +109,7 @@ QImage ImageProcessor::Mat2QImage(cv::Mat cvImg)//https://www.cnblogs.com/annt/p QImage::Format_RGB888); } - return qImg; + return qImg.copy(); // 返回独立数据副本,避免cvImg被覆盖导致QImage数据失效 } cv::Mat ImageProcessor::CStretchDeal(const cv::Mat img, const uint minnum, const uint maxnum) diff --git a/HPPA/rgbCamera.ui b/HPPA/rgbCamera.ui index 554c98d..9f086aa 100644 --- a/HPPA/rgbCamera.ui +++ b/HPPA/rgbCamera.ui @@ -6,8 +6,8 @@ 0 0 - 416 - 219 + 489 + 329 @@ -70,18 +70,50 @@ QPushButton:pressed } - - - - Qt::Vertical - - - - 18 - 100 - - - + + + + + + QLabel { + color: rgb(255, 255, 255); +} + + + 数据路径 + + + + + + + QLineEdit { + background-color: #142D7F; + color: #e6eeff; + border: 1px solid #2f6bff; + border-radius: 6px; + padding: 4px 8px; + min-width: 70px; + min-height: 20px; + font-size: 13px; +} + + + D:\ + + + true + + + + + + + ... + + + + @@ -96,6 +128,19 @@ QPushButton:pressed + + + + Qt::Vertical + + + + 18 + 100 + + + + @@ -165,7 +210,7 @@ QPushButton:pressed - + Qt::Vertical @@ -178,6 +223,44 @@ QPushButton:pressed + + + + + + QLabel { + color: rgb(255, 255, 255); +} + + + 文件名 + + + + + + + QLineEdit { + background-color: #142D7F; + color: #e6eeff; + border: 1px solid #2f6bff; + border-radius: 6px; + padding: 4px 8px; + min-width: 70px; + min-height: 20px; + font-size: 13px; +} + + + test + + + false + + + + + diff --git a/HPPA/rgbCameraWindow.cpp b/HPPA/rgbCameraWindow.cpp index 4314805..e4728c7 100644 --- a/HPPA/rgbCameraWindow.cpp +++ b/HPPA/rgbCameraWindow.cpp @@ -1,8 +1,11 @@ -#include "rgbCameraWindow.h" -#include +#include "rgbCameraWindow.h" +#include +#include +#include "AppSettings.h" rgbCameraWindow::rgbCameraWindow(QWidget* parent) : QDialog(parent) + , m_captureCoordinator(nullptr) { ui.setupUi(this); @@ -11,22 +14,185 @@ rgbCameraWindow::rgbCameraWindow(QWidget* parent) m_RgbCamera->moveToThread(m_RgbCameraThread); m_RgbCameraThread->start(); - connect(ui.open_rgb_camera_btn, SIGNAL(clicked()), m_RgbCamera, SLOT(OpenCamera()));//ʹÓÃÐźÅ֪ͨÖ÷Ị̈߳¨uiỊ̈߳©ˢÐÂÊÓƵ ¡ú ³ɹ¦£¬µ«ÊǽçÃ濨¶Ù connect(m_RgbCamera, SIGNAL(PlotSignal()), this, SIGNAL(PlotRgbImageSignal())); - //m_RgbCamera->setCallback(onPlotRgbImage); - //connect(this->ui.open_rgb_camera_btn, SIGNAL(clicked()), m_RgbCamera, SLOT(OpenCamera_callback()));//ʹÓûص÷º¯ÊýÀ´ˢÐÂÖ÷Ị̈߳¨uiỊ̈߳©ÉϵÄÊÓƵ ¡ú ʧ°Ü - - connect(ui.close_rgb_camera_btn, SIGNAL(clicked()), this, SLOT(onCloseRgbCamera()));//¹رÕÏà»ú + connect(ui.open_rgb_camera_btn, &QPushButton::clicked, + this, [this]() { if (m_captureCoordinator) m_captureCoordinator->openCamera(); }); connect(m_RgbCamera, SIGNAL(CamClosedSignal()), this, SIGNAL(CamClosedSignal())); + + connect(ui.close_rgb_camera_btn, &QPushButton::clicked, + this, [this]() { if (m_captureCoordinator) m_captureCoordinator->closeCamera(); }); + + connect(this->ui.dataFolderBtn, SIGNAL(clicked()), this, SLOT(onSelectDataFolder())); + + connect(this->ui.take_video_btn, &QPushButton::clicked, + this, [this]() { + if (m_captureCoordinator) + { + if (!m_captureCoordinator->isCapturing()) + m_captureCoordinator->startVideoCapture(); + else if (m_captureCoordinator->getCurrentMode() == RgbCameraCaptureCoordinator::Video) + m_captureCoordinator->stopVideoCapture(); + } + }); + connect(this->ui.take_photo_btn, &QPushButton::clicked, + this, [this]() { + if (m_captureCoordinator) + { + if (!m_captureCoordinator->isCapturing()) + m_captureCoordinator->startPhotoCapture(); + else if (m_captureCoordinator->getCurrentMode() == RgbCameraCaptureCoordinator::Photo) + m_captureCoordinator->stopPhotoCapture(); + } + }); + + connect(ui.fileNameLineEdit, &QLineEdit::textChanged, this, &rgbCameraWindow::onFileNameChanged); + + setupCaptureCoordinator(); + + loadSettings(); } rgbCameraWindow::~rgbCameraWindow() { + delete m_captureCoordinator; + m_captureCoordinator = nullptr; + + m_RgbCameraThread->quit(); + m_RgbCameraThread->wait(); + delete m_RgbCamera; + delete m_RgbCameraThread; } -void rgbCameraWindow::onCloseRgbCamera() +void rgbCameraWindow::setupCaptureCoordinator() { - //std::cout << "¹رÕÊÓƵ+++++++++++++++++++++++++++++++++++++++++++" << std::endl; - m_RgbCamera->CloseCamera(); + m_captureCoordinator = new RgbCameraCaptureCoordinator(m_RgbCamera, this); + + connect(m_captureCoordinator, &RgbCameraCaptureCoordinator::captureStarted, + this, &rgbCameraWindow::onCaptureStarted); + connect(m_captureCoordinator, &RgbCameraCaptureCoordinator::captureStopped, + this, &rgbCameraWindow::onCaptureStopped); + connect(m_captureCoordinator, &RgbCameraCaptureCoordinator::cameraOpened, + this, &rgbCameraWindow::onCameraOpened); + connect(m_captureCoordinator, &RgbCameraCaptureCoordinator::cameraClosed, + this, &rgbCameraWindow::onCameraClosed); + connect(m_captureCoordinator, &RgbCameraCaptureCoordinator::cameraOpenFailed, + this, &rgbCameraWindow::onCameraOpenFailed); + connect(m_captureCoordinator, &RgbCameraCaptureCoordinator::photoCaptured, + this, &rgbCameraWindow::onPhotoCaptured); + connect(m_RgbCamera, &RgbCameraOperation::photoSavedSignal, + this, &rgbCameraWindow::onPhotoSaved); +} + +void rgbCameraWindow::startVideoCapture() +{ + if (m_captureCoordinator) + { + m_captureCoordinator->startVideoCapture(); + } +} + +void rgbCameraWindow::stopVideoCapture() +{ + if (m_captureCoordinator) + { + m_captureCoordinator->stopVideoCapture(); + } +} + +void rgbCameraWindow::startPhotoCapture() +{ + if (m_captureCoordinator) + { + m_captureCoordinator->startPhotoCapture(); + } +} + +void rgbCameraWindow::stopPhotoCapture() +{ + if (m_captureCoordinator) + { + m_captureCoordinator->stopPhotoCapture(); + } +} + +void rgbCameraWindow::onCaptureStarted(RgbCameraCaptureCoordinator::CaptureMode mode) +{ + if (mode == RgbCameraCaptureCoordinator::Video) + { + ui.take_video_btn->setText(QString::fromLocal8Bit("停止录制")); + } + else if (mode == RgbCameraCaptureCoordinator::Photo) + { + ui.take_photo_btn->setText(QString::fromLocal8Bit("采集中...")); + } +} + +void rgbCameraWindow::onCaptureStopped(RgbCameraCaptureCoordinator::CaptureMode mode) +{ + if (mode == RgbCameraCaptureCoordinator::Video) + { + ui.take_video_btn->setText(QString::fromLocal8Bit("录制视频")); + } + else if (mode == RgbCameraCaptureCoordinator::Photo) + { + ui.take_photo_btn->setText(QString::fromLocal8Bit("拍照")); + } +} + +void rgbCameraWindow::onCameraOpened() +{ +} + +void rgbCameraWindow::onCameraClosed() +{ +} + +void rgbCameraWindow::onCameraOpenFailed(const QString& error) +{ + //QMessageBox::warning(this, QString::fromLocal8Bit("相机打开失败"), error); +} + +void rgbCameraWindow::onPhotoCaptured(const QString& filePath) +{ +} + +void rgbCameraWindow::onPhotoSaved(const QString& filePath) +{ + // 可在此更新界面,例如显示已保存的照片数量 + std::cout << "照片已保存: " << filePath.toStdString() << std::endl; +} + +void rgbCameraWindow::loadSettings() +{ + QString folder = AppSettings::instance().rgbCameraDataFolder(); + setDataFolder(folder); + setFileName(AppSettings::instance().rgbCameraFileName()); +} + +void rgbCameraWindow::onSelectDataFolder() +{ + QString dir = QFileDialog::getExistingDirectory(this, + QString::fromLocal8Bit("选择数据保存路径"), + ui.dataFolderLineEdit->text()); + + setDataFolder(dir); +} + +void rgbCameraWindow::setDataFolder(QString dir) +{ + if (!dir.isEmpty()) + { + ui.dataFolderLineEdit->setText(dir); + } +} + +void rgbCameraWindow::setFileName(QString name) +{ + ui.fileNameLineEdit->setText(name); +} + +void rgbCameraWindow::onFileNameChanged(const QString& text) +{ + AppSettings::instance().setRgbCameraFileName(text); } diff --git a/HPPA/rgbCameraWindow.h b/HPPA/rgbCameraWindow.h index 9cacd23..2d2ad5c 100644 --- a/HPPA/rgbCameraWindow.h +++ b/HPPA/rgbCameraWindow.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include #include @@ -8,6 +8,7 @@ #include "ui_rgbCamera.h" #include "RgbCameraOperation.h" +#include "RgbCameraCaptureCoordinator.h" class rgbCameraWindow : public QDialog { @@ -19,16 +20,41 @@ public: RgbCameraOperation* m_RgbCamera; -public Q_SLOTS: - void onCloseRgbCamera(); + // 视频采集控制 + void startVideoCapture(); + void stopVideoCapture(); -signals: + // 照片采集控制 + void startPhotoCapture(); + void stopPhotoCapture(); + +public Q_SLOTS: + void onSelectDataFolder(); + void onFileNameChanged(const QString& text); + +Q_SIGNALS: void PlotRgbImageSignal(); void CamClosedSignal(); +private Q_SLOTS: + // 协调器信号处理 + void onCaptureStarted(RgbCameraCaptureCoordinator::CaptureMode mode); + void onCaptureStopped(RgbCameraCaptureCoordinator::CaptureMode mode); + void onCameraOpened(); + void onCameraClosed(); + void onCameraOpenFailed(const QString& error); + void onPhotoCaptured(const QString& filePath); + void onPhotoSaved(const QString& filePath); + private: Ui::rgbCameraClass ui; - - QThread* m_RgbCameraThread;//rgbÏà»ú»ñȡͼÏñÏ߳Ì + QThread* m_RgbCameraThread;//rgb相机获取图像线程 + RgbCameraCaptureCoordinator* m_captureCoordinator; + + void setDataFolder(QString dir); + void setFileName(QString name); + void loadSettings(); + void saveSettings(); + void setupCaptureCoordinator(); };