计算机系统应用教程网站

网站首页 > 技术文章 正文

Qt opencv打开摄像头并录制成为AVI 文件

btikc 2024-12-09 10:55:53 技术文章 18 ℃ 0 评论

测试环境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;
    }
}



本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表