OpenCV讀取視訊、OpenCV提取視訊每一幀、每一幀圖片合成新的AVI視訊
CvCapture 是視訊獲取結構 被用來作為視訊獲取函式的一個引數 比如 CvCapture* cap; IplImage* cvQueryFrame( cap ); 從攝像頭或者檔案中抓取並返回一幀
- #include "stdafx.h"
- #include"highgui.h"
- int main(int argc,char* argv[])
- {
- cvNamedWindow( "avi");
- CvCapture* capture = cvCreateFileCapture( "sample.avi");
- IplImage* frame;
- while(1)
- {
- frame = cvQueryFrame(capture);
- if(!frame) break ;
- cvShowImage( "avi",frame);
- char c = cvWaitKey(33);
- if(c == 27)
- break;
- }
- cvReleaseCapture(&capture);
- cvDestroyWindow( "avi");
- return 0;
- }
結構體 CvCapture
CvCapture 是一個結構體,用來儲存影象捕獲所需要的資訊。 opencv提供兩種方式從外部捕獲影象:
一種是從攝像頭中,
一種是通過解碼視訊得到影象。
兩種方式都必須從第一幀開始一幀一幀的按順序獲取,因此每獲取一幀後都要儲存相應的狀態和引數。
比如從視訊檔案中獲取,需要儲存視訊檔案的檔名,相應的解碼器型別,下一次如果要
獲取將需要解碼哪一幀等。 這些資訊都儲存在CvCapture結構中,每獲取一幀後,這些資訊
都將被更新,獲取下一幀需要將新資訊傳給獲取的 api介面
cvCreateFileCapture(char*name)
通過輸入要讀取的avi檔案的路徑,然後,該函式返回一個指向 CvCapture結構體的指標。
cvQueryFrame(capture)
輸入一個CvCapture 型別的指標,該函式主要功能是將視訊檔案的下一幀載入到記憶體。與 cvLoadImage的不同之處是,該函式不重新分配記憶體空間。
C=cvWaitKey(33)
當前幀被顯示後,等待 33毫秒。如果使用者觸發了一個按鍵, c會被設定成這個按鍵的 ASCII碼,否則會被設定成 -1。
cvWaitKey(33) 在此處的另外一個作用是,控制幀率。
cvReleaseCapture(&capture)
釋放為 CvCapture結構體開闢的記憶體空間
關閉開啟的 AVI檔案相關的檔案控制代碼
讀取攝像頭
只需把 cvCreateFileCapture 改成cvCreateCameraCapture即可。
該函式的輸入引數是一個 ID號,只有存在多個攝像頭時才起作用。當 ID=-1時,表示
隨機選擇一個。 HighGUI做了很多工作,使得攝像機影象序列像一個視訊檔案一樣。
常見問題
cvCreateFileCapture返回空的問題
- ( 1)視訊檔案路徑沒寫對
- ( 2)沒有安裝解碼器
- ( 3)如果使用的是 Opencv2.0或更高版本,那麼,能否正確載入 opencv_ffmpeg210.dll
- ( 4)儘管是 AVI檔案,但也可能使用了某種 codec,例如 :MJPEG Decompressor。 需要把它轉換 OpenCV支援的 AVI檔案 . OpenCV支援的AVI。例如使用狸窩全能視訊轉換器,在《預置方案》處,選擇 AVI-Audio_Video Interleaved(*.avi)。或者使用格式工廠也可以。
- ( 5)讀攝像頭資料,需要安裝與攝像頭相應的驅動程式。
————————————————————
cvQueryFrame
OpenCV中一個函式cvQueryFrame
從攝像頭或者檔案中抓取並返回一幀
IplImage* cvQueryFrame( CvCapture* capture );
capture
視訊獲取結構。
函式cvQueryFrame從攝像頭或者檔案中抓取一幀,然後解壓並返回這一幀。 這個函式僅僅是函式cvGrabFrame和 函式cvRetrieveFrame在一起呼叫的組合。 返回的影象不可以被使用者釋放或者修改。
cvQueryFrame的引數為CvCapture結構的指標。用來將下一幀視訊檔案載入記憶體,返回一個對應當前幀的指標。與cvLoadImage不同的是cvLoadIamge為影象分配記憶體空間,而cvQueryFrame使用已經在cvCapture結構中分配好的記憶體。這樣的話,就沒有必要通過cvReleaseImage()對這個返回的影象指標進行釋放,當CvCapture結構被釋放後,每一幀影象所對應的記憶體空間即會被釋放。
________________________________________________________________________________
opencv提取視訊每一幀
[cpp] view plaincopy
- // test3.cpp
- //
- // 該程式實現視訊和圖片的相互轉換.
- // Image_to_video()函式將一組圖片合成AVI視訊檔案.
- // Video_to_image()函式將AVI視訊檔案讀入,將每一幀儲存為jpg檔案.
- //
- ////////////////////////////////////////////////////////////////////////
- #include <stdlib.h>
- #include <stdio.h>
- #include <math.h>
- #include <cv.h>
- #include <highgui.h>
- #define NUM_FRAME 300 //只處理前300幀,根據視訊幀數可修改
- void Video_to_image(char* filename)
- {
- printf("------------- video to image ... ----------------n");
- //初始化一個視訊檔案捕捉器
- CvCapture* capture = cvCaptureFromAVI(filename);
- //獲取視訊資訊
- cvQueryFrame(capture);
- int frameH = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
- int frameW = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
- int fps = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
- int numFrames = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT);
- printf("tvideo height : %dntvideo width : %dntfps : %dntframe numbers : %dn", 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, ".jpg");//儲存的圖片名
- cvSaveImage( image_name, img); //儲存一幀圖片
- if(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");
- //初始化視訊編寫器,引數根據實際視訊檔案修改
- CvVideoWriter *writer = 0;
- int isColor = 1;
- int fps = 30; // or 25
- int frameW = 400; // 744 for firewire cameras
- int frameH = 240; // 480 for firewire cameras
- writer=cvCreateVideoWriter("out.avi",CV_FOURCC('X','V','I','D'),fps,cvSize(frameW,frameH),isColor);
- printf("tvideo height : %dntvideo width : %dntfps : %dn", frameH, frameW, fps);
- //建立視窗
- cvNamedWindow( "mainWin", CV_WINDOW_AUTOSIZE );
- while(i<NUM_FRAME)
- {
- sprintf(image_name, "%s%d%s", "image", ++i, ".jpg");
- 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[13] = "infile.avi";
- Video_to_image(filename); //視訊轉圖片
- Image_to_video(); //圖片轉視訊
- return 0;
- }