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();
};