使用openCV阅读视频 [英] Reading a video with openCV

查看:94
本文介绍了使用openCV阅读视频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个视频 engine2.avi ,我想通过openCV进行阅读和播放.这是我的代码:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

using namespace cv;

int main(int argc, char** argv)
{
    string filename = "D:\\BMDvideos\\engine2.avi";
    VideoCapture capture(filename);
    Mat frame;

    if( !capture.isOpened() )
        throw "Error when reading steam_avi";

    namedWindow("w", 1);
    for( ; ; )
    {
        capture >> frame;
        //if(!frame)
        //    break;
        imshow("w", frame);
        waitKey(20); // waits to display frame
    }
    waitKey(0);
}

如果我的文件具有编解码器YUV 4:2:2 (UYVY)(我使用Direct-Show录制了视频),则此代码不起作用,但是当我使用抓取了openCV的视频时,此代码可以工作!!

有人知道这是怎么工作的吗?

更新:

在阅读了一些链接后,建议捕获异常将解决该问题,然后我修改了代码.它没有帮助,但这是修改后的代码:

cv::VideoCapture cap("d:\\BMDvideos\\engine2.avi");
cv::Mat frame;

try
{
    cap >> frame;
}
catch(cv::Exception ex)
{
    std::cout << ex.what() << std::endl;
}
catch(...)
{
    std::cout << "Unknown exception" << std::endl;  
}

程序在cap>>frame中崩溃.我读过类似的问题,但它们使用YUV(4:2:0)中的帧,而我的视频具有UYVY(4:2:2).如何将其转换为RGB颜色模型?

更新2:

在karlphillip的建议之后,我使用了OpenCV2.4.3,但是使用下面的代码我仍然遇到相同的错误:

#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\opencv.hpp>
using namespace cv;
using namespace std;

int main(){
    cv::Mat frame;
    cv::VideoCapture cap("d:\\BMDvideos\\B\\Aufnahme.avi");
    if(!cap.isOpened())
    {
        cout << "Error can't find the file"<<endl;
    }

    while(1){
        if(!cap.read(frame))
            imshow("",frame);

        cv::waitKey(33);
    }
    return 0;
}

解决方案

以下几个链接可能会对您有所帮助:

修改:

我必须先清除一些内容: OpenCV能够从视频文件中读取YUV帧,因为它是基础库(FFmpeg/GStreamer)起作用的. OpenCV还支持通过cvCvtColor()CV_YCrCb2RGBCV_RGBYCrCb YUV和RGB 的特定类型之间进行转换. /p>

再次检查您的问题时,我注意到您没有指定发生的错误的类型.您可以在做得更好使用可能

如果由于某种原因,捕获界面无法打开文件,它将立即退出应用程序,而不会进一步崩溃只是在cap.read(frame)崩溃.

I have a video engine2.avi that I want to read and show with openCV. Here's my code:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

using namespace cv;

int main(int argc, char** argv)
{
    string filename = "D:\\BMDvideos\\engine2.avi";
    VideoCapture capture(filename);
    Mat frame;

    if( !capture.isOpened() )
        throw "Error when reading steam_avi";

    namedWindow("w", 1);
    for( ; ; )
    {
        capture >> frame;
        //if(!frame)
        //    break;
        imshow("w", frame);
        waitKey(20); // waits to display frame
    }
    waitKey(0);
}

This code doesn't work if my file has the codec YUV 4:2:2 (UYVY) (I recorded the video using Direct-Show), but works when I use a video I grabbed whit openCV !!

Has anybody an Idea how this could work ?

UPDATE:

After reading some links, suggesting that catching exception will solve the problem, I modified my code. It didn't help, but here is the modified code:

cv::VideoCapture cap("d:\\BMDvideos\\engine2.avi");
cv::Mat frame;

try
{
    cap >> frame;
}
catch(cv::Exception ex)
{
    std::cout << ex.what() << std::endl;
}
catch(...)
{
    std::cout << "Unknown exception" << std::endl;  
}

The program crashes in cap>>frame. I readed similar questions but they use a frame in YUV (4:2:0), while my video has UYVY (4:2:2). How can I convert this into RGB color model?

UPDATE 2:

After karlphillip's suggestion, I used OpenCV2.4.3, but I still got the same error using the code below:

#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\opencv.hpp>
using namespace cv;
using namespace std;

int main(){
    cv::Mat frame;
    cv::VideoCapture cap("d:\\BMDvideos\\B\\Aufnahme.avi");
    if(!cap.isOpened())
    {
        cout << "Error can't find the file"<<endl;
    }

    while(1){
        if(!cap.read(frame))
            imshow("",frame);

        cv::waitKey(33);
    }
    return 0;
}

解决方案

Here is a couple of links that might help you:

Edit:

I must clear something first: OpenCV is capable of reading YUV frames from a video file because it's the underlying library (FFmpeg/GStreamer) that does the job. OpenCV also supports converting between a specific type of YUV and RGB through cvCvtColor() with CV_YCrCb2RGB or CV_RGBYCrCb.

Upon examining your question again, I noticed you didn't specify the kind of error that happened. You could do a better job at dealing with a possible failure from the capture interface by printing a message to the screen instead of throwing it.

I tested the video file you shared and I had no problems playing it on a window using the following code:

#include <cv.h>
#include <highgui.h>

#include <iostream>

int main(int argc, char* argv[])
{
    cv::VideoCapture cap(argv[1]);
    if (!cap.isOpened())
    {
        std::cout << "!!! Failed to open file: " << argv[1] << std::endl;
        return -1;
    }

    cv::Mat frame;
    for(;;)
    {

        if (!cap.read(frame))             
            break;

        cv::imshow("window", frame);

        char key = cvWaitKey(10);
        if (key == 27) // ESC
            break;
    }

    return 0;
}

If, for some reason, the capture interface fails to open the file it will quit the application immediately, instead of going further just to crash at cap.read(frame).

这篇关于使用openCV阅读视频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆