使用 OpenCV 打开和读取 avi 文件 - Ubuntu

Posted

技术标签:

【中文标题】使用 OpenCV 打开和读取 avi 文件 - Ubuntu【英文标题】:Open and read avi files with OpenCV - Ubuntu 【发布时间】:2012-06-27 00:37:24 【问题描述】:

我刚刚在 R. Laganiere 的 OpenCV 2 Computer Vision Application Programming Cookbook 一书中读到了这一点:

需要注意的是,为了打开指定的视频 文件,您的计算机必须安装相应的编解码器, 否则 cv::VideoCapture 将无法理解输入 文件。通常,如果您能够打开带有视频的视频文件 您机器上的播放器(例如 Windows Media Player),然后是 OpenCV 应该也能读取这个文件。

不幸的是,事情对我来说并不容易。是的,我可以在我的视频播放器上读取 avi 文件,但它不适用于我的 OpenCV-Qt 应用程序。 VideoCapture isOpen() 方法返回 false,尽管路径正确,并且所需的每个编解码器似乎都在这里。我尝试了几个文件,所以它与一种特定的格式无关。

这里有人有使用 OpenCV 在 Ubuntu 中打开 avi 文件的经验吗?我认为这是一个大问题,在互联网上找不到任何真正相关的解决方案......

谢谢!!

[编辑] 这是我正在处理的功能;这里的一些变量是类成员,所以看起来可能不完整。但是,正是这段代码不起作用。特别是我实例化一个新 VideoCapture 对象的那一行。

void MainWindow::on_actionOuvrir_fichier_triggered()

    //mettre a -1 streamId
    streamId = -1;
    //get path to the avi file
    QString fileName = QFileDialog::getOpenFileName(this,tr("Ouvrir fichier video"),"/home", tr("Videos (*.avi)"));
    std::string utf8_text = fileName.toUtf8().constData();
    //open .avi
    capture = new VideoCapture(utf8_text);
    //check 
    if(!capture->isOpened())
        cout << "probleme ouverture fichier video" << endl;
    //delay between each frame in ms
    rate = capture->get(CV_CAP_PROP_FPS);
    delay = 1000 / rate;
    //start Qtimer recordId
    recordId = startTimer(delay);
    //capture first frame
    if(!capture->read(in))
        cout << "probleme lecture frame fichier video" << endl;

[编辑 2] 在 Windows 7 上测试

void MainWindow::on_actionOuvrir_fichier_triggered()

    //mettre a -1 streamId
    streamId = -1;
    //ouvrir fenetre navigation fichiers pour recuperer path vers .avi
    QString fileName = QFileDialog::getOpenFileName(this,tr("Ouvrir fichier video"),"/home",
                                                    tr("Videos (*.avi)"));
    //std::string utf8_text = fileName.toUtf8().constData();
    std::string current_locale_text = fileName.toLocal8Bit().constData();
    if(QDir().exists(current_locale_text.c_str())) std::cout << "Path is good!" << endl;
    //ouvrir .avi
    capture = new VideoCapture(current_locale_text);
    //check ouverture
    if(!capture->isOpened())
        cout << "probleme ouverture fichier video" << endl;
    //calculer delay between each frame in ms
//    rate = capture->get(CV_CAP_PROP_FPS);
//    delay = 1000 / rate;
    //demarrer timer recordId
    recordId = startTimer(100);
    //capture premiere frame
    if(!capture->read(in))
        cout << "probleme lecture frame fichier video" << endl;

使用该代码,我能够打开一些 avi 文件,但不是全部(实际上远非如此)。所以我想我肯定有编解码器问题......有人能告诉我如何在 Ubuntu 下解决这个问题吗?不要让我继续赏金!非常感谢。

[编辑 3] 正如Etienne 所建议的那样,我遵循here 的说明,并尝试使用带有给定命令行的mencoder 将我的视频转换为OpenCV 在所有平台上都支持的I420 格式。因此,根据 VLC,我从 24 位 RGB (RV24) 编解码器转到了 Planar 4:2:0 YUV (I420)。虽然行为相同,但我仍然无法实例化 VideoCapture 对象。

THERE IS A LOT OF UNSOLVED CASES 类似于我在 Stack Overflow 上的...

【问题讨论】:

你能帮忙解决一下这个 Astor 吗?谢谢 Open .avi with OpenCV 2.4 & Ubuntu 11.04的可能重复 你已经问过这个问题了。确保您发送到 OpenCV 的路径有效:if (QDir().exists(utf8_text.c_str())) std::cout &lt;&lt; "Path is good!\n"; 确实是重复的;我想改写它,它是混乱和不清楚的。对于那个很抱歉。关于这个问题,我尝试通过 capture = new VideoCapture("1.avi"); 直接加载与我的应用程序位于同一文件夹中的文件。也没有工作,所以这不是与路径相关的问题,除非我实际上有两个问题:) 再次抱歉重复发布,这不是故意的。 您查看过 OpenCV 视频编解码器的兼容性吗? :opencv.willowgarage.com/wiki/VideoCodecs 【参考方案1】:

我终于设法解决了我的问题。

我做了什么:

尝试打开一些视频,最终找到一个可以工作的视频。幸运的是,我只用了 3 个视频就找到了一个有效的视频。

使用 VLC 检查编解码器。它是 MPEG-4 XVID。

使用mencoder将我要读取的文件转换为XVID:

sudo mencoder myFile.avi -ovc lavc vcodec=mpeg4:mbd=2:cbp:trell:vbitrate=300 -ffourcc XVID -o test.avi

我也切换到旧的 C 函数cvCaptureFromFile()。我将返回 C++ 界面以确保它确实是一个编解码器问题,但我很确定它是([EDIT] 这是一个编解码器问题)。

什么没用:

重新编译 OpenCV 并启用 Qt 支持

【讨论】:

注意 VLC 有它自己的 buitlin 编解码器,它不使用系统编解码器。所以仅仅因为它在 vlc 中打开并不能很好地测试系统 但是 VLC 会告诉您它使用哪个编解码器来读取您的文件,所以是的,这对于了解如何对文件进行编码很有用。就我而言,我可以使用我的应用程序打开文件,但我不知道如何。 VLC 给了我信息;所以现在我将以这种方式对所有其他视频进行编码。

以上是关于使用 OpenCV 打开和读取 avi 文件 - Ubuntu的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Python OpenCV 4.1.2-dev 读取 .avi 文件

如何在 Java 中使用 openCV 的 VideoCapture 方法打开和处理 .mpeg 或 .avi 等视频文件

OpenCV中如何播放avi文件的音频

opencv 怎样从MP4格式视频中读取一帧

关于opencv读取图片、视频总是窗口一闪不出图、视频的问题

从正在写入的视频 .avi 文件中读取