使用 openCV 阅读视频
Posted
技术标签:
【中文标题】使用 openCV 阅读视频【英文标题】:Reading a video with openCV 【发布时间】:2013-01-27 19:38:48 【问题描述】:我有一个视频 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;
【问题讨论】:
【参考方案1】:这里有几个链接可能对您有所帮助:
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编辑:
我必须先明确一点:OpenCV 能够从视频文件中读取 YUV 帧,因为它是完成这项工作的底层库 (FFmpeg/GStreamer)。 OpenCV 还支持在特定类型的YUV and RGB 到cvCvtColor()
与CV_YCrCb2RGB
或CV_RGBYCrCb
之间进行转换。
再次检查您的问题后,我注意到您没有具体说明发生的错误类型。您可以通过在屏幕上打印消息而不是 throw
ing 来从捕获界面使用 dealing dealing 和 possible failure do a better job。
我测试了您共享的视频文件,并且使用以下代码在窗口上播放它没有问题:
#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)
处崩溃。
【讨论】:
感谢@karlphilip 的回答。但是在这些链接中,他们解释了如何将 YUV 4:2:2 中的帧转换为 RGB,当我尝试从中获取帧时,我有一个视频,整个程序崩溃了!! 上传视频到某处,让我们测试一下。 您周围没有较小的视频吗?我没有时间下载 1GB。 :( 嗯,这将只有 2 秒,因为输入设备提供 HD 1900x1080,这是一个行数据,所以我可以更改它???? 考虑编辑问题以插入一个简短的、可编译的示例的完整代码,以重现您所面临的问题。在我的机器上使用我的代码不会发生。【参考方案2】:如果您只是想显示视频,下面是对我有用的代码, 请检查它是否对您有任何帮助。
#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);
希望对你有所帮助。
【讨论】:
这段代码只是看了一个视频,这是我的问题,编解码器是问题!不过还是谢谢! 如果问题出在编解码器上,如果您仍然遇到问题,请确保安装 ffmpeg 编解码器。 Check this link for installation of ffmpeg.【参考方案3】:我意识到,VideoCapture 对象需要 opencv_ffmpeg310_64.dll。 将此 dll 复制到二进制文件夹后,您的 VideoCapture 对象应该能够读取视频文件。
【讨论】:
以上是关于使用 openCV 阅读视频的主要内容,如果未能解决你的问题,请参考以下文章