OpenCV1.1无法读视频文件的解决方法

来源:互联网 发布:网络上流行的英文歌曲 编辑:程序博客网 时间:2024/06/05 15:08

无法读视频大多是由于视频编码的原因,只要有支持的编解码器就可以解决这个问题。

可以在OpenCV link里添加ffopencv.lib,这个库要和一个叫做 ffopencv110.dll 的动态连接库连接,才能使用它里面的函数 。这个 ffopencv110.dll 动态连接库要从yahoo group下载,也可以自己编译,不过要修改一些文件,比较麻烦。下载后,使用的时候放到project 的debug文件里就可以。

还有一种方法,就是下载个ffdshow安装,这是个免费的编解码软件,支持很多编码方式。它本身没有播放器,但播放器都可以使用它解码。我看到有人用人用这个方法成功了。

------------
最近用opencv来读取avi文件,发现无论用CvCreateFileCapture,还是CvCaptureFromFile或者CvCaptureFromAVI,总是返回0,也就是无法捕获视频,后来知道这三个函数其实都是一样的东西,只是用宏语句定义(#define)的不同名称,这些宏定义在highgui.h里可以看到。
例如:
#define cvCaptureFromAVI cvCaptureFromFile
#define cvCaptureFromFile cvCreateFileCapture


所以用cvCaptureFromAVI()跟cvCaptureFromFile(),cvCreateFileCapture()其實都是一樣的東西.這邊其實副檔名不限avi檔,只要檔案格式符合OpenCV播放程式內建格式的標準就行.
cvCaptureFromAVI("AVI檔案名稱");

无法捕获视频,可能是codec的原因,codec是什么?不甚了解。查阅了一下codec的资料,内容有不少,有涉及视频压缩和传输的,还有容器的概念,各种视频编解码器类型,例如mpeg 1,2,4, xvid, h264, divx , mp3等等。
原来同样扩展名的avi文件,它内部的编码方式也是多种多样。容器可以理解成一个壳,把编码后的音轨,视频数据等按照某种规则放进里面,就生成独立的视频文件。这个视频文件就是个容器,容器的格式有 avi,mpg,flv等等。
知道了这些后用mencoder 重新给视频转换了编码,容器指定为 avi,可是尝试了各种编码后依然无法捕获。

后来在某个博客上看到这么一段话:
附註:opencv1.1取消了AviForamt=-1的功能,並且要掛上ffopencv的函式庫才能使用,關於avi檔案的存取,必須要去Yahoo Group下載ffopencv110.dll覆蓋到C:/Program Files/OpenCV/bin的目錄底下

博客地址: http://yester-place.blogspot.com/2008/06/gui5.html ,上面很多opencv的教程 


ffopencv 的 ff 应该是指 ffmpeg ,opencv 利用了ffmpeg生成的一个动态链接库,在里面有一些可以使用ffmpeg 的功能的函数调用。 第一次去opencv的 yahoo group,搜索ffopencv, 就找到了答案。我看的是这个帖子,下面贴出地址:
http://tech.groups.yahoo.com/group/OpenCV/message/58026

总结一下,与这几个文件有关,ffopencv.h, highgui.h, cvcap_ffmpeg 和 cvcap_win32 ,还要从opencv源码库(在 sourceforge)里下载这个文件夹 otherlibs/_graphics/include/FFMPEG  。这个文件夹在原opencv发布的时候被漏掉了。
ffopencv110.dll 这个动态链接库也必须要有,用的函数调用都在这里面。

引起问题的原因是 highgui.h里面漏掉了 声明函数 CVAPI(CvCapture*) cvCreateFileCapture_FFMPEG( const char* filename ); ,当highgui library 加载ffopencv110.dll 插件的时候,会在 dll 里寻找几个函数(如果找不到就会忽略他们),(look for cvCreateFileCapture_FFMPEG_p in cvcap_w32.cpp)。

具体方法:
在cvcap_ffmpeg.cpp里漏掉了cvReleaseVideoWriter_FFMPEG 和 cvReleaseCapture_FFMPEG 的代码,
添加下面的代码:
void cvReleaseVideoWriter_FFMPEG(CvVideoWriter** writer) {
if (writer!=NULL) {
if (*writer!=NULL)
delete *writer;
*writer=NULL;
}
}
void cvReleaseCapture_FFMPEG(CvCapture** capture) {
if (capture!=NULL) {
if (*capture!=NULL)
delete *capture;
*capture=NULL;
}
}

在ffopencv.h里也要修改:
CVAPI(CvCapture*) cvCreateFileCapture_FFMPEG( const char* filename );
CVAPI(void) cvReleaseCapture_FFMPEG(CvCapture** capture);
CVAPI(CvVideoWriter*) cvCreateVideoWriter_FFMPEG( const char *filename, int fourcc,double fps, CvSize frameSize, int is_color );
CVAPI(int) cvWriteFrame_FFMPEG( CvVideoWriter * writer, const IplImage * image );
CVAPI(void) cvReleaseVideoWriter_FFMPEG( CvVideoWriter ** writer );

最后必须要重新建立ffopencv110.dll,我rebuild the ffopencv110.dll 总是有错误,好在从yahoo group上可以下载ffopencv110.rar,用新的dll代替原来的那个使用,问题就解决了。

教授告诉了一个方法,无法捕获视频,可能是解编码器(codec)的原因,可以先用gomplayer捕获帧,然后再用opencv把这些帧重新写成 avi文件。
按这个方法成功捕获了大量的帧图片,一些不能捕获的视频经过mencoder转换编码后也可以成功捕获,可是要把这些帧写成视频的时候 ,cvCreateVideoWriter却总是返回 0(无法获得写视频文件的结构的指针)。依然是codec的原因,用 -1 代替CV_FOURCC,这样写视频文件时会出现选择codec的窗口,选择一个codec,这样写成的视频就可以被opencv读取了。我开始用了0 代替writer的参数CV_FOURCC, 这样可以成功写文件,可是没有指定codec生成的文件无法打开。


附上原文:

Re: Big problem reading saved videos back in.

Hi.
This is for opencv 1.1pre. The problem is that the header function

CVAPI(CvCapture*) cvCreateFileCapture_FFMPEG( const char* filename );

is missing in ffopencv.h. When the highgui library loads the
ffopencv110.dll plug-in looks for several functions in the dll (if it
doesn't find them, it ignores them) (look for
icvCreateFileCapture_FFMPEG_p in cvcap_w32.cpp).

Also the source code of cvReleaseVideoWriter_FFMPEG and
cvReleaseCapture_FFMPEG is missing (I didn't find it). Because the
function cvReleaseVideoWriter doesn't exist, the video trailer (extra
data) is not written in the video file (you can't play avi files in
windows media player even with installed codecs).

You have to rebuild the ffopencv110. To do this you have to include
this code in cvcap_ffmpeg.cpp:

void cvReleaseVideoWriter_FFMPEG(CvVideoWriter** writer) {
if (writer!=NULL) {
if (*writer!=NULL)
delete *writer;
*writer=NULL;
}
}
void cvReleaseCapture_FFMPEG(CvCapture** capture) {
if (capture!=NULL) {
if (*capture!=NULL)
delete *capture;
*capture=NULL;
}
}

You must use this header functions in ffopencv.h (check for the
differences).

CVAPI(CvCapture*) cvCreateFileCapture_FFMPEG( const char* filename );
CVAPI(void) cvReleaseCapture_FFMPEG(CvCapture** capture);
CVAPI(CvVideoWriter*) cvCreateVideoWriter_FFMPEG( const char *
filename, int fourcc,double fps, CvSize frameSize, int is_color );
CVAPI(int) cvWriteFrame_FFMPEG( CvVideoWriter * writer, const
IplImage * image );
CVAPI(void) cvReleaseVideoWriter_FFMPEG( CvVideoWriter ** writer );

Also you have to download the folder
otherlibs/_graphics/include/FFMPEG from the OpenCV source code
repository in sourceforge because is missing in the original opencv
1.1 pre distribution.

Darío.

--- In OpenCV@yahoogroups.com, "jd185152" <jd185152@...> wrote:
>
> Hi All.
>
> im _really_ stuck:
>
> I want to read avi videos written with opencv's
> CvVideoWriter back into my application using
> cvCreateFileCapture (or cvCaptureFromAVI).
>
> i have tried saving the video using different codecs
> FOURCC's: DIB_, I420, IYUV, MSVC, MJPG, IRAW, XVID, RGB8...
> Saving does work with some of the codecs (MSVC, I420), as
> the video can be watched in media player.
>
> But reading the avi file back in will not work at all -
> cvCreateFileCapture() always returns a NULL pointer on me.
>
> My OS is windows vista and the problem shows in both
> 1.0 and 1.1alpha releases of opencv.
>
> I tried converting one of the saved videos (.avi, i420 codec)
> using mencoder to i420 format (doesnt make much sense, does it?)
> Interestingly, opencv could read the converted video.
>
> So my best guess is that opencv is broken in this respect.
>
> Hope to hear from you,
> Jonas
>
------------------------------------------------------------------------------------------------------------------

Hi nol1ght

In the file ffopencv.cpp is the line
#include "cvcap_ffmpeg.cpp"
That includes the file in the build of the ffopencv110.dll library.

You can check for the changes in the libraries you build with depends
(http://www.dependencywalker.com/). If you check the original
ffopencv110.dll file, you will notice that there are missing function
exports (this is because there are missing function headers and
implementations).

If you rebuild the library ffopencv with the instructions that I gave
in the previous post, you will notice in the new library that
cvCreateFileCapture_FFMPEG
cvReleaseCapture_FFMPEG
cvCreateVideoWriter_FFMPEG
cvReleaseVideoWriter_FFMPEG
are now exported (with depends).

If you have problems, make sure that you build the "release" version of the library, because that is the one that is used by the ffopencv
distribution (it is in the bin directory). Also you can try to copy the opencv libraries in the same directory of your exe file and remove the path of opencv in the path environment variable.

Dario.

-----------------------------------------------------------------------------------------------------

Hi!
Thank you!!!
dependencywalker really helped!
My mistake was that my project used my old dll not a new one. now everything is ok!

原创粉丝点击