Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading a video with openCV

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;
}
like image 373
Engine Avatar asked Feb 12 '13 13:02

Engine


1 Answers

Here is a couple of links that might help you:

  • Load, Save and Show YUV 420 images
  • How to read a frame from YUV file in OpenCV?
  • Converting YUV into BGR or RGB in OpenCV

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).

like image 73
karlphillip Avatar answered Nov 10 '22 05:11

karlphillip