Qt+OpenCV摄像头读取保存回放视频

上一篇文章中,在Qt中配置了OpenCV的开发环境,并且添加了所需要的库文件,这篇文章,开始读取摄像头视频,并保存

要注意OpenCV2和OpenCV3的读取保存方法是有区别的,本文是基于OpenCV3的方法进行视频读取与保存

参考:http://blog.csdn.net/sinat_24206709/article/details/53152966

一、读取单个摄像头视频

在mainwindow.cpp中添加如下代码:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    Mat input_image;
    VideoCapture cam(0);
    if (!cam.isOpened()) exit(0);
    namedWindow("摄像头");
    while (true) 
    {
        cam >> input_image;
        imshow("input image", input_image);
        if (27 == waitKey(30))
            break;
    }
}
MainWindow::~MainWindow()
{
    delete ui;
}

运行后即可打开笔记本摄像头,并显示视频数据

如果有别的摄像头,可以插入,然后修改VideoCapture cam(0)中的0为1、2....即可

二、保存视频

在UI界面添加打开摄像头、保存视频、关闭摄像头、打开视频的按钮,效果如图所示

为了实现保存视频的功能,添加了定时器,实现隔一段时间来读取一帧,然后保存的效果,代码如下:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/video.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    timer = new QTimer(this);
    cam = NULL;
    OPEN = true;
    /*信号和槽*/
    connect(ui->OpenCameraBtn,SIGNAL(click()),this,SLOT(on_OpenCameraBtn_clicked()));//打开摄像头按钮
    connect(ui->TakePicBtn,SIGNAL(click()),this,SLOT(on_TakePicBtn_clicked()));//保存视频按钮
    connect(ui->CloseCameraBtn,SIGNAL(click()),this,SLOT(on_CloseCameraBtn_clicked()));//关闭摄像头按钮
    connect(ui->OpenVideoBtn,SIGNAL(click()),this,SLOT(on_OpenVideoBtn_clicked()));//打开视频按钮
    connect(timer,SIGNAL(timeout()),this,SLOT(getFrame()));
}
/******************************
 ***********打开摄像头***********
 *****************************/
void MainWindow::on_OpenCameraBtn_clicked()
{
    // 设置摄像头的拍摄属性为 分辨率640x480,帧率30fps
//    cam.set(CAP_PROP_FRAME_HEIGHT, 480);
//    cam.set(CAP_PROP_FRAME_WIDTH, 640);
//    cam.set(CAP_PROP_FPS, 30.0);
    //打开摄像头 从摄像头中获取视频
    cam.open(0);
    //开启定时器,每隔0.05秒刷新一次
    timer->start(50);
}
void MainWindow::getFrame()
{
   //读取摄像头信息 将读取回来的帧转换成QImage类型
   //从摄像头中抓取并返回每一帧
   cam >> frame;
   //将抓取到的帧转换成QImage格式
   QImage img1 = QImage((const unsigned char*)frame.data, frame.cols, frame.rows, QImage::Format_RGB888).rgbSwapped();//个人测试时可以试试去掉.rgbSwapped()后的效果
   //将图片显示到QLabel上
   //ui->label->setPixmap(QPixmap::fromImage(img1));
   namedWindow("VideoPlay", WINDOW_NORMAL);
   imshow("VideoPlay", frame);
   waitKey(1000 / 30);
}
/******************************
 ***********保存视频按钮************
 *****************************/
void MainWindow::on_TakePicBtn_clicked()
{
    if(!cam.isOpened())
        cam.open(0);
    //VideoWriter write("D:\\test.avi", VideoWriter::fourcc('M', 'J', 'P', 'G'), 30.0, Size(640, 480), true);
    write.open("D:\\test.avi",VideoWriter::fourcc('M', 'J', 'P', 'G'), 30.0, Size(640, 480), true);
    while(OPEN)
    {
        cam >> frame;
        //设置保存视频的格式为AVI,编码为MJPG
        write.write(frame);        
        namedWindow("VideoPlay", WINDOW_NORMAL);
        imshow("VideoPlay", frame);
        waitKey(1000 / 30);
    }
}

三、关闭摄像头

/******************************
 ***********关闭摄像头***********
 *****************************/
void MainWindow::on_CloseCameraBtn_clicked()
{
    timer->stop();
    cam.release();
    OPEN = false;
    write.release();
    destroyWindow("VideoPlay");
}

四、打开保存的视频

/******************************
 ***********打开视频***********
 *****************************/
void MainWindow::on_OpenVideoBtn_clicked()
{
    VideoCapture video;
    Mat frame2;
    video.open("D:\\test.avi");
    while (video.isOpened())
    {
        video >> frame2;
        imshow("video", frame2);
        if (cvWaitKey(40) == 27)  //cvWaitKey的参数相当于多少ms一帧,现在是40ms一帧,1s25帧
            break;                //按ESC就退出
    }
}
MainWindow::~MainWindow()
{
    delete ui;
}

五、在mainwindow.h中添加槽函数和类的声明

private slots:
    void on_OpenCameraBtn_clicked();
    void getFrame();
    void on_TakePicBtn_clicked();
    void on_CloseCameraBtn_clicked();
    void on_OpenVideoBtn_clicked();
private:
    Ui::MainWindow *ui;
    Mat frame;//摄像头每次抓取的图像为一帧,使用该指针指向一帧图像的内存空间
    QTimer *timer;//定时器用于定时取帧,上面说的隔一段时间就去取就是用这个实现
    VideoCapture cam;
    VideoWriter write;
    bool OPEN;

 

 
  • 12
    点赞
  • 125
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 28
    评论
如果你想在Qt读取地方摄像头视频,可以使用OpenCV的`VideoCapture`类进行操作。 具体步骤如下: 1. 在Qt中添加OpenCV库,可以在.pro文件中添加以下内容: ``` INCLUDEPATH += /usr/local/include/opencv4 LIBS += -L/usr/local/lib -lopencv_core -lopencv_highgui -lopencv_videoio ``` 其中,`/usr/local/include/opencv4`为OpenCV的头文件路径,`/usr/local/lib`为OpenCV库文件路径。 2. 在Qt中创建一个窗口用于显示视频。 3. 使用`VideoCapture`类打开地方摄像头,可以通过参数指定摄像头的设备编号或者视频文件的路径。 4. 循环读取视频帧并在窗口中显示,直到读取失败或者用户退出程序。 完整代码示例如下: ``` #include <opencv2/opencv.hpp> #include <QApplication> #include <QMainWindow> #include <QImage> #include <QPixmap> #include <QLabel> int main(int argc, char *argv[]) { QApplication app(argc, argv); QMainWindow window; QLabel label; window.setCentralWidget(&label); window.show(); cv::VideoCapture cap(0); // 打开地方摄像头 if (!cap.isOpened()) // 打开失败 { std::cerr << "Failed to open camera." << std::endl; return -1; } while (true) // 循环读取视频帧 { cv::Mat frame; cap >> frame; // 读取视频帧 if (frame.empty()) break; // 读取失败,退出循环 cv::cvtColor(frame, frame, cv::COLOR_BGR2RGB); // OpenCV图像格式为BGR,需要转换为RGB QImage qimg(frame.data, frame.cols, frame.rows, QImage::Format_RGB888); // 创建QImage对象 QPixmap qpixmap = QPixmap::fromImage(qimg); // 转换为QPixmap对象 label.setPixmap(qpixmap); // 显示在窗口中 QApplication::processEvents(); // 处理Qt事件,保证窗口正常显示 if (cv::waitKey(30) == 'q') break; // 按下q键退出循环 } return app.exec(); } ``` 其中,`QMainWindow`和`QLabel`用于创建窗口和显示视频帧,`QImage`和`QPixmap`用于将OpenCV的图像格式转换为Qt的图像格式,`QApplication::processEvents()`用于保证窗口正常显示。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宗而研之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值