Чтение видео с openCV
У меня есть видео движок2.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:
После предложения карлфиллипа я использовал OpenCV2. 4. 3, но я все равно получил ту же ошибку, используя код ниже:
#include <opencv2corecore.hpp>
#include <opencv2highguihighgui.hpp>
#include <opencv2opencv.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;
}
3 ответа:
Вот несколько ссылок, которые могут вам помочь:
- загрузка, сохранение и отображение изображений YUV 420
- Как прочитать кадр из файла YUV в OpenCV?
- преобразование YUV в BGR или RGB в OpenCV
Edit:
Сначала я должен кое-что прояснить: OpenCV способен считывать кадры YUV из видеофайла, потому что это базовая библиотека (FFmpeg/GStreamer), которая выполняет эту работу. OpenCV также поддерживает преобразование между определенным типом YUV и RGB через
Изучив ваш вопрос еще раз, я заметил, что вы не указали вид ошибки, которая произошла. Вы могли бы сделать лучшую работу в , имея дело С возможным сбой из интерфейса захвата путем печати сообщения на экран вместоcvCvtColor()
сCV_YCrCb2RGB
илиCV_RGBYCrCb
.throw
его ввода.Я протестировал видео файл, которым вы поделились, и у меня не было проблем с воспроизведением его в окне используя следующий код:
#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; }
Если по какой-либо причине интерфейс capture не сможет открыть файл, он немедленно завершит работу приложения, вместо того чтобы продолжить работу, чтобы просто завершить работу в
cap.read(frame)
.
Если вы просто ищете для отображения видео, Вот код, который работал для меня, Пожалуйста, проверьте, если это поможет вам в любом случае.
#include <stdio.h> #include <opencv2/opencv.hpp> int main(){ CvCapture *camera=cvCaptureFromFile("C:\\test.avi"); if (camera==NULL) printf("camera is null\n"); else printf("camera is not null"); cvNamedWindow("img"); while (cvWaitKey(10)!=atoi("q")){ double t1=(double)cvGetTickCount(); IplImage *img=cvQueryFrame(camera); /*if(img){ cvSaveImage("C:/opencv.jpg",img); }*/ double t2=(double)cvGetTickCount(); printf("time: %gms fps: %.2g\n",(t2-t1)/(cvGetTickFrequency()*1000.), 1000./((t2-t1)/(cvGetTickFrequency()*1000.))); cvShowImage("img",img); } cvReleaseCapture(&camera); }
Надеюсь, это поможет вам.