一、openCv視頻處理

  視頻處理
[編輯]
一、從視頻流中捕捉一幀畫面
[編輯]
(1) OpenCV 支持從攝像頭或視頻文件(AVI格式)中捕捉幀畫面.
[編輯]
(2) 初始化一個攝像頭捕捉器:

CvCapture* capture = cvCaptureFromCAM(0); // capture from video device #0

[編輯]
(3) 初始化一個視頻文件捕捉器:

CvCapture* capture = cvCaptureFromAVI("infile.avi");

[編輯]
(4) 捕捉一幀畫面:

IplImage* img = 0; 
if(!cvGrabFrame(capture)){              // capture a frame 
printf("Could not grab a frame\n\7");
exit(0);
}
img=cvRetrieveFrame(capture);           // retrieve the captured frame

若要從多個攝像頭中同步捕捉畫面,則須首先從每一個攝像頭中抓取一幀,緊接着要將被捕捉的幀畫面恢復到一個IplImage*型圖像中。(譯註:這一過程其實能夠用 cvQueryFrame() 函數一步完成)
[編輯]
(5) 釋放視頻流捕捉器:

cvReleaseCapture(&capture);

注意由視頻流捕捉器獲得的圖像是由捕捉器分配和釋放內存的,不須要單獨對圖像進行釋放內存的操做。
[編輯]
二、獲取/設置視頻流信息
[編輯]
(1) 獲取視頻流設備信息:

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);

統計總幀數僅對視頻文件有效,但彷佛不太準確(譯註:也許OpenCV2.0中此問題已解決)
[編輯]
(2) 獲取幀圖信息:

float posMsec   =       cvGetCaptureProperty(capture, CV_CAP_PROP_POS_MSEC);
int posFrames   = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES);
float posRatio  =       cvGetCaptureProperty(capture, CV_CAP_PROP_POS_AVI_RATIO);

所抓取的幀的位置有三種表達方式:距離第一幀畫面的時間間隔(毫秒爲單位), 或者距離第一幀畫面(序列號爲0)的序列數. 第三種方式是按相對比率,第一幀的相對比率爲0,最後一幀的相對比率爲1. 此方式僅對讀取視頻文件時有效.
[編輯]
(3) 設置從視頻文件抓取的第一幀畫面的位置:

// start capturing from a relative position of 0.9 of a video file
cvSetCaptureProperty(capture, CV_CAP_PROP_POS_AVI_RATIO, (double)0.9);

注意此方法定位並不許確。
[編輯]
三、保存視頻文件
[編輯]
(1) 初始化視頻編寫器:

CvVideoWriter *writer = 0;
int isColor = 1;
int fps     = 25;  // or 30
int frameW  = 640; // 744 for firewire cameras
int frameH  = 480; // 480 for firewire cameras
writer=cvCreateVideoWriter("out.avi",CV_FOURCC('P','I','M','1'),
fps,cvSize(frameW,frameH),isColor);

其它的編碼器代號包括: CV_FOURCC('P','I','M','1') = MPEG-1 codec CV_FOURCC('M','J','P','G') = motion-jpeg codec (does not work well) CV_FOURCC('M', 'P', '4', '2') = MPEG-4.2 codec CV_FOURCC('D', 'I', 'V', '3') = MPEG-4.3 codec CV_FOURCC('D', 'I', 'V', 'X') = MPEG-4 codec CV_FOURCC('U', '2', '6', '3') = H263 codec CV_FOURCC('I', '2', '6', '3') = H263I codec CV_FOURCC('F', 'L', 'V', '1') = FLV1 codec 若編碼器代號爲 -1,則運行時會彈出一個編碼器選擇框.
[編輯]
(2) 保持視頻文件:

IplImage* img = 0; 
int nFrames = 50;
for(i=0;i<nFrames;i++){
cvGrabFrame(capture);          // capture a frame
img=cvRetrieveFrame(capture);  // retrieve the captured frame
// img = cvQueryFrame(capture);
cvWriteFrame(writer,img);      // add the frame to the file
}

要查看所抓取到的幀畫面,能夠在循環中加入如下語句:

cvShowImage("mainWin", img); 
key=cvWaitKey(20);           // wait 20 ms

注意 cvWaitKey 參數應該不小於 20 ms,不然畫面的顯示可能出錯.
[編輯]
(3) 釋放視頻編寫器:

cvReleaseVideoWriter(&writer);ide

相關文章
相關標籤/搜索