CvCapture 是視頻獲取結構 被用來作為視頻獲取函數的一個參數 比如 CvCapture* cap; IplImage* cvQueryFrame( cap ); 從攝像頭或者文件中抓取並返回一幀
————————————————————————
Opencv讀取視頻代碼
[cpp]
view plain
copy
- #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)讀攝像頭數據,需要安裝與攝像頭相應的驅動程序。
————————————————————
Opencv讀取視頻代碼
[cpp]
view plain
copy
- #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結構中,每獲取一幀后,這些信息
都將被更新,獲取下一幀需要將新信息傳給獲取的 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 plain
copy
- // 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;
- }
