Qt+Opencv实现本地视频读取及显示

首先明确我们的思路,我们现在的思路是读取视频文件然后定时读取并显示视频中的每一帧。(鉴于本人技术力有限目前只想到了这种方法,后续如果对视频成色有更高要求会补充)

读取视频文件

我们先使用QFileDialog中的getOpenFileName函数选择要打开的文件并获取其绝对路径,使用opencv中VideoCapture对象的open方法读取本地视频

const QString dyn = "*.gif;;*.mp4;;*.avi;;*.dat;;*.mkv;;*.flv;;*.vob;;*.3gp";
QString path = QFileDialog::getOpenFileName(this,"打开文件","./", dyn);
cap.open(path.toStdString());

显示视频文件

首先这里先说个坑,我们是绝对不能用waitKey()函数来实现帧与帧之间的时间间隔的,因为我们用的是QLabel来显示,而QLabel是组件,使用waitKey()会使得QLabel数据堵塞,最终实操的结果也只会是过一会后显示视频的最后一帧。

对于这样的情况我们的解决方案是,使用QTimer定时器。
QTimer的主要方法是start(internal)表示每隔internal毫秒发送一个timeout()信号,这样我们只需要编写响应这个信号的槽函数并连接信号和槽函数即可。
连接部分:

QTimer* vedioshow = new QTimer();
//vedioshow是我的QTimer对象
connect(vedioshow, SIGNAL(timeout()), this, SLOT(my_vedioshow()));

槽函数部分:

//这个部分是槽函数,实现读取图像的每一帧并做一定的识别和处理
VideoCapture cap;
void MainWindow::my_vedioshow()
{
    Mat source, result;
    cap.read(source);
    if (source.empty())//如果视频已经读取完成则停止发送timeout()信号
    {
        vedioshow->stop();
        return;
    }
    result  = pic_convert(source);//用于处理每一帧图像的函数
    QImage SImg = Mat2QImage(source);//这个转换函数是需要自己写的
    QImage RImg = Mat2QImage(result);
    //InputImg和OutputImg为两个QLabel
    pic_show(this->ui->InputImg, SImg);//这个显示函数是需要自己写的
    pic_show(this->ui->OutputImg, RImg);
    this->ui->InputImg->update();
    this->ui->OutputImg->update();
}

你可能感兴趣的:(机器视觉与图像处理,opencv,qt,音视频)