测试环境qt6.5.3 opencv4.10,以下是参考界面和主要文件的代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "qtimer.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
// 显示摄像头内容
void MainWindow::updateFrame() {
cv::Mat frame;
capture >> frame; // 从摄像头获取帧
if (frame.empty()) return;
// 转换成Qt可显示的格式
QImage img = QImage((const uchar*)frame.data, frame.cols, frame.rows, QImage::Format_BGR888);
ui->label->setPixmap(QPixmap::fromImage(img).scaled(ui->label->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
}
void MainWindow::on_openCamera_clicked()
{
capture.open(0); // 打开默认摄像头
if (!capture.isOpened()) {
QMessageBox::warning(this, "Error", "Failed to open camera.");
return;
}
timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &MainWindow::updateFrame);
timer->start(30); // 30ms更新一次
}
void MainWindow::on_closeCamera_clicked()
{
if (isRecording) {
writer.release(); // 释放视频文件
// 恢复录制按钮状态
ui->pushButton_RCD->setText("录制");
ui->pushButton_RCD->setEnabled(true);
ui->pushButton_StopRcd->setEnabled(false);
isRecording = false;
}
if (timer) {
timer->stop();
delete timer;
timer = nullptr;
}
capture.release(); // 释放摄像头
ui->label->clear();
}
void MainWindow::on_pushButton_RCD_clicked()
{
if (!capture.isOpened()) {
QMessageBox::warning(this, "Error", "Camera is not opened.");
return;
}
// 获取当前日期时间,并格式化为文件名
QString dateTime = QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss");
QString filename = QDir::currentPath() + "/" + dateTime + ".avi"; // 保存到程序目录
// 设置视频编码和帧率
int width = capture.get(cv::CAP_PROP_FRAME_WIDTH);
int height = capture.get(cv::CAP_PROP_FRAME_HEIGHT);
// 打开 AVI 文件进行录制
writer.open(filename.toStdString(), cv::VideoWriter::fourcc('M', 'J', 'P', 'G'), 30, cv::Size(width, height));
if (!writer.isOpened()) {
QMessageBox::warning(this, "Error", "Failed to start video recording.");
return;
}
isRecording = true;
// 更新录制按钮状态
ui->pushButton_RCD->setText("录制中...");
ui->pushButton_RCD->setEnabled(false);
ui->pushButton_StopRcd->setEnabled(true);
// 使用 QTimer 定时捕获帧
QTimer* timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &MainWindow::recordFrame);
timer->start(33); // 约每30帧每秒 (1000ms / 30fps ≈ 33ms)
}
void MainWindow::recordFrame()
{
if (isRecording) {
cv::Mat frame;
capture >> frame; // 从摄像头捕获一帧
if (frame.empty()) {
QMessageBox::warning(this, "Error", "Failed to capture frame.");
return;
}
writer.write(frame); // 将帧写入视频文件
}
}
void MainWindow::on_pushButton_StopRcd_clicked()
{
if (isRecording) {
writer.release(); // 释放视频文件
// 恢复录制按钮状态
ui->pushButton_RCD->setText("录制");
ui->pushButton_RCD->setEnabled(true);
ui->pushButton_StopRcd->setEnabled(false);
isRecording = false;
}
}