我有一个视频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 <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;
}
以下是几个可能对您有所帮助的链接:
- 加载、保存和显示YUV 420图像
- 如何在OpenCV中从YUV文件中读取帧
- 在OpenCV中将YUV转换为BGR或RGB
编辑:
我必须首先澄清:OpenCV能够从视频文件中读取YUV帧,因为它是底层库(FFmpeg/GStreamer)。OpenCV还支持通过cvCvtColor()
和CV_YCrCb2RGB
或CV_RGBYCrCb
在特定类型的YUV和RGB之间进行转换。
在再次检查你的问题时,我注意到你没有具体说明发生的错误类型。您可以通过在屏幕上打印消息而不是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;
}
如果由于某种原因,捕获接口无法打开文件,它将立即退出应用程序,而不是在cap.read(frame)
崩溃。
如果您只是想显示视频,下面是适用于我的代码,请检查它是否对您有任何帮助。
#include <stdio.h>
#include <opencv2/opencv.hpp>
int main(){
CvCapture *camera=cvCaptureFromFile("C:\test.avi");
if (camera==NULL)
printf("camera is nulln");
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: %.2gn",(t2-t1)/(cvGetTickFrequency()*1000.), 1000./((t2-t1)/(cvGetTickFrequency()*1000.)));
cvShowImage("img",img);
}
cvReleaseCapture(&camera);
}
希望这对你有帮助。
我意识到,VideoCapture对象需要opencv_ffmpeg310_64.dll。一旦你将这个dll复制到你的二进制文件夹中,你的VideoCapture对象应该能够读取视频文件。