前一陣子,實驗室老師個了個小命題,就是如何提取一段AVI視頻中的圖片,或者說視頻幀的提取。雖然是第一次接觸OPENCV,可是做起來也是不難的,自己的代碼就不拿出來了,寫的很亂,網(wǎng)上的這個代碼比較不錯,為了說明我們的主題,姑且拿這段代碼做個試驗。
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>
#define NUM_FRAME 5591 //只處理前300幀,根據(jù)視頻幀數(shù)可修改
int frameH;
int frameW;
int fps;
int numFrames;
void Video_to_image(char* filename)
{
printf("------------- video to image ... ----------------\n");
//初始化一個視頻文件捕捉器
CvCapture* capture = cvCaptureFromAVI(filename);
//獲取視頻信息
cvQueryFrame(capture);
frameH = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
frameW = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
fps = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
numFrames = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT);
printf("\tvideo height : %d\n\tvideo width : %d\n\tfps : %d\n\tframe numbers : %d\n", frameH, frameW, fps, numFrames);
//定義和初始化變量
int i = 0;
IplImage* img = 0;
char image_name[13];
cvNamedWindow( "mainWin", CV_WINDOW_AUTOSIZE );
//讀取和顯示
while(1)
{
img = cvQueryFrame(capture); //獲取一幀圖片
cvShowImage( "mainWin", img ); //將其顯示
char key = cvWaitKey(20);
sprintf(image_name, "%s%d%s", "image", ++i, ".bmp");//保存的圖片名
cvSaveImage( image_name, img); //保存一幀圖片
if(i >=numFrames || i >= NUM_FRAME ) break;
}
cvReleaseCapture(&capture);
cvDestroyWindow("mainWin");
}
void Image_to_video()
{
int i = 0;
IplImage* img = 0;
char image_name[13];
printf("------------- image to video ... ----------------\n");
//初始化視頻編寫器,參數(shù)根據(jù)實際視頻文件修改
CvVideoWriter *writer = 0;
int isColor = 1;
writer=cvCreateVideoWriter("out.avi",CV_FOURCC('X','V','I','D'),fps,cvSize(frameW,frameH),isColor);
printf("\tvideo height : %d\n\tvideo width : %d\n\tfps : %d\n", frameH, frameW, fps);
//創(chuàng)建窗口
cvNamedWindow( "mainWin", CV_WINDOW_AUTOSIZE );
while(i<NUM_FRAME)
{
sprintf(image_name, "%s%d%s", "image", ++i, ".bmp");
img = cvLoadImage(image_name);
if(!img)
{
printf("Could not load image file...\n");
exit(0);
}
cvShowImage("mainWin", img);
char key = cvWaitKey(20);
cvWriteFrame(writer, img);
}
cvReleaseVideoWriter(&writer);
cvDestroyWindow("mainWin");
}
int main(int argc, char *argv[])
{
char filename[23] = "F:\\1_Xvid.avi";
Video_to_image(filename); //視頻轉(zhuǎn)圖片
Image_to_video(); //圖片轉(zhuǎn)視頻
return 0;
}
配置好OPENCV環(huán)境(WIN7 + VS2010)之后,這段代碼是可以運行的,可是,實驗室?guī)熜謳熃銈兊闹髁鲗嵱肰C6開發(fā)的,所以老師讓我把代碼在VC6下調(diào)試出來。
結(jié)果配置好VC6之后,一運行出現(xiàn)這個錯誤:Null pointer in function cvGetMat
首先找資料是怎么回事,有的人說是內(nèi)存不足之類的原因,建議在循環(huán)體里面釋放窗體資源,我照做了,可是還是不行。
郁悶了老半天,還是沒有結(jié)果。。。。。
后來我發(fā)現(xiàn)一個細(xì)節(jié),就是說,視頻的信息壓根就沒有讀進來,可以看看控制臺。
找到原因之后,后來就相對好辦了,其實也花了很長時間去做。
?
網(wǎng)上很多人說是解碼器的問題,建議安裝K-Lite_Codec_Pack_3.9.5Full,我也試了,在實驗室蛋疼的網(wǎng)速之下,苦苦等待,安裝,結(jié)果不知道為什么還是不行,。
最后階段,一個偶然的機會,我看到這篇文章 http://hqs2892805.blog.163.com/blog/static/379968312010722915630/
結(jié)果按照這篇文章這么做,就實現(xiàn)了。。。
?
如果AVI文件打不開,請下載VIRTUALDUB圖像處理軟件,然后把AVI文件用XVID編碼,編碼后的文件不會太大。我自己用攝像頭拍攝的AVI有5兆,編碼后只有不到2兆,而且能夠用VC打開。
http://www.xvidmovies.com/codec/ ??? 可以從這個網(wǎng)站下載xvid解編碼器
方法:file——open video file?
?????????? video——compression——選擇XVIDMPEG CODEC
?
哈哈,慶祝一下
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

