add,山地所贡嘎山10:

优化rgb相机控制,添加采集视频和照片的逻辑;
This commit is contained in:
tangchao0503
2026-09-10 13:48:07 +08:00
parent e552dc2ed5
commit 9bc2133e24
12 changed files with 912 additions and 46 deletions

View File

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

View File

@ -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);

View File

@ -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);

View File

@ -160,6 +160,7 @@
<ClCompile Include="recordFrameCounter.cpp" />
<ClCompile Include="resononImager.cpp" />
<ClCompile Include="ResononNirImager.cpp" />
<ClCompile Include="RgbCameraCaptureCoordinator.cpp" />
<ClCompile Include="RgbCameraOperation.cpp" />
<ClCompile Include="rgbCameraWindow.cpp" />
<ClCompile Include="RobotArmControl.cpp" />
@ -289,6 +290,7 @@
<ClInclude Include="ResononNirImager.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="stdafx.h" />
<QtMoc Include="RgbCameraCaptureCoordinator.h" />
<QtMoc Include="RgbCameraOperation.h" />
<QtMoc Include="resononImager.h" />
<QtMoc Include="QMotorDoubleSlider.h" />

View File

@ -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()
{
}

View File

@ -0,0 +1,69 @@
#pragma once
#include <QObject>
#include <QTimer>
#include <QMutex>
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;
};

View File

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

View File

@ -4,6 +4,9 @@
#include <QObject>
#include <QTimer>
#include <QDir>
#include <QDateTime>
#include <QCoreApplication>
#include <opencv2/opencv.hpp>
#include <QImage>
@ -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

View File

@ -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)

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>416</width>
<height>219</height>
<width>489</width>
<height>329</height>
</rect>
</property>
<property name="sizePolicy">
@ -70,18 +70,50 @@ QPushButton:pressed
}</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>18</width>
<height>100</height>
</size>
</property>
</spacer>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="styleSheet">
<string notr="true">QLabel {
color: rgb(255, 255, 255);
}</string>
</property>
<property name="text">
<string>数据路径</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="dataFolderLineEdit">
<property name="styleSheet">
<string notr="true">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;
}</string>
</property>
<property name="text">
<string>D:\</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="dataFolderBtn">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer">
@ -96,6 +128,19 @@ QPushButton:pressed
</property>
</spacer>
</item>
<item row="0" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>18</width>
<height>100</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
@ -165,7 +210,7 @@ QPushButton:pressed
</property>
</spacer>
</item>
<item row="2" column="1">
<item row="4" column="1">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
@ -178,6 +223,44 @@ QPushButton:pressed
</property>
</spacer>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_2">
<property name="styleSheet">
<string notr="true">QLabel {
color: rgb(255, 255, 255);
}</string>
</property>
<property name="text">
<string>文件名</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="fileNameLineEdit">
<property name="styleSheet">
<string notr="true">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;
}</string>
</property>
<property name="text">
<string>test</string>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>

View File

@ -1,8 +1,11 @@
#include "rgbCameraWindow.h"
#include <Qthread>
#include "rgbCameraWindow.h"
#include <QThread>
#include <QFileDialog>
#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()));//ʹ<><CAB9><EFBFBD>ź<EFBFBD>֪ͨ<CDA8><D6AA><EFBFBD>̣߳<DFB3>ui<75>̣߳<DFB3>ˢ<EFBFBD><CBA2><EFBFBD><EFBFBD>Ƶ <20><> <20>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǽ<EFBFBD><C7BD>濨<EFBFBD><E6BFA8>
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()));//ʹ<>ûص<C3BB><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˢ<EFBFBD><CBA2><EFBFBD><EFBFBD><EFBFBD>̣߳<DFB3>ui<75>̣߳<DFB3><CCA3>ϵ<EFBFBD><CFB5><EFBFBD>Ƶ <20><> ʧ<><CAA7>
connect(ui.close_rgb_camera_btn, SIGNAL(clicked()), this, SLOT(onCloseRgbCamera()));//<2F>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD>
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 << "<22>ر<EFBFBD><D8B1><EFBFBD>Ƶ+++++++++++++++++++++++++++++++++++++++++++" << 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);
}

View File

@ -1,4 +1,4 @@
#pragma once
#pragma once
#include <QDialog>
#include <QNetworkRequest>
@ -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<67><62><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡͼ<C8A1><CDBC><EFBFBD>߳<EFBFBD>
QThread* m_RgbCameraThread;//rgb相机获取图像线程
RgbCameraCaptureCoordinator* m_captureCoordinator;
void setDataFolder(QString dir);
void setFileName(QString name);
void loadSettings();
void saveSettings();
void setupCaptureCoordinator();
};