I have just read this in the book OpenCV 2 Computer Vision Application Programming Cookbook by R. Laganiere :
It is important to note that in order to open the specified video file, your computer must have the corresponding codec installed, otherwise cv::VideoCapture will not be able to understand the input file. Normally, if you are able to open your video file with a video player on your machine (such as the Windows Media Player), then OpenCV should also be able to read this file.
Unfortunately, things aren't that easy for me. Yes, I can read avi files on my video player, however it does not work with my OpenCV-Qt application. VideoCapture isOpen() method returns false, despite the fact that the path is correct, and every codec needed seem to be here. I tried several files, so it is not related to one particular format.
Does someone here has experience in opening avi files in Ubuntu using OpenCV ? I think this is a big issue, can't find any trully relevant solution on the internet...
Thanks !!
[EDIT] Here is the function I am working on; some of the variables here are class members, so it may looks incomplete. However, it is this very piece of code that is not working. In particular, the line where I instanciate a new VideoCapture object.
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;
}
[EDIT 2] test on 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;
}
With that code I was able to open SOME avi files, but not all (actually far from that). So I guess I definitely have a codec issue... does anyone can tell me how to fix this under Ubuntu ? Don't let me go on bounty for that one ! Thank you very much.
[EDIT 3] As suggested by Etienne, I followed instructions here and tried to convert my video to the I420 format supposedly supported by OpenCV on all platforms, using mencoder with the command line given. So I went from 24 bits RGB (RV24) codec to Planar 4:2:0 YUV (I420), according to VLC. Same behavior though, I'm still unable to instanciate the VideoCapture object.
THERE IS A LOT OF UNSOLVED CASES similar to mine on Stack Overflow...
I finally managed to solve my problem.
What I did :
try to open some video to finally find one that would work. Fortunately it only took me 3 videos to find one that work.
check the codec with VLC. It is MPEG-4 XVID.
use mencoder to convert the file I wanted to read to XVID:
sudo mencoder myFile.avi -ovc lavc vcodec=mpeg4:mbd=2:cbp:trell:vbitrate=300 -ffourcc XVID -o test.avi
I also switched to old C function cvCaptureFromFile()
. I will go back to C++ interface to make sure it was indeed a codec issue, but I am pretty sure it was ([EDIT] it was a codec issue).
What did not work :