00 GUI介面的製作-視訊,AVI檔案儲存,多視訊裝置

Post date: 2012/4/10 上午 09:18:50

視訊GUI介面程式設計,包括了捕捉視訊畫面,存取AVI檔案,將視訊畫面存成AVI檔,這邊先從視訊存成AVI開始,將最初的Webcam播放程式在做調整,並詳細說明所有capture類的副程式內容.

webcam程式碼存成AVI檔

#include <cv.h>

#include <highgui.h>

#include <stdio.h>

int main()

{

CvCapture *capture;

IplImage *frame;

capture=cvCreateCameraCapture(0);

cvNamedWindow("Webcam",0);

CvVideoWriter *writer;

char AviFileName[]="Output.avi";

int AviForamt = -1;

int FPS = 25;

CvSize AviSize = cvSize(640,480);

int AviColor = 1;

writer=cvCreateVideoWriter(AviFileName,AviForamt,FPS,AviSize,AviColor);

int i=0;

while(true)

{

frame = cvQueryFrame(capture);

cvWriteFrame(writer,frame);

cvShowImage("Webcam",frame);

printf("%d\n",i);

if(cvWaitKey(20)>0) break;

i++;

}

cvReleaseCapture(&capture);

cvReleaseVideoWriter(&writer);

cvDestroyWindow("Webcam");

}

執行結果:

先開一個CvCapture及IplImage,用cvCreateCameraCapture()選定視訊裝置編號,給視窗命名,接著,就是寫入AVI檔的重頭戲啦,用CvVideoWriter創立一個writer的資料結構,給它AVI檔名,AVI格式,FPS(Frame per second)每秒圖片播放頻率,CvSize資料結構及Avi檔的顏色種類,再用cvWriteFrame()寫入AVI檔,最後,記得用cvReleaseVideoWriter()把CvVideoWriter資料結構釋放,cvReleaseVideoWriter()非常的重要,因為AVI檔的檔案格式收尾就是要用到cvReleaseVideoWriter(),也就是說,如果不用到cvReleaseVideoWriter()AVI檔就無法開啟.這邊,先從cvCreateCameraCapture()詳細敘述.

多視訊介面的開啟,也是OpenCV不錯的應用,它的使用方法就是將cvCreateCameraCapture()的裝置代號重複使用,以下就是一個簡單的多視訊畫面開啟的實例.

多個Webcam的程式實作

#include <cv.h>

#include <highgui.h>

#include <stdio.h>

#include <windows.h>

int main()

{

CvCapture *capture0;

CvCapture *capture1;

IplImage *frame0;

IplImage *frame1;

capture0 =cvCaptureFromCAM(0);

capture1 =cvCaptureFromCAM(0);

cvNamedWindow("Webcam0",1);

cvNamedWindow("Webcam1",1);

while(true)

{

frame0 = cvQueryFrame(capture0);

frame1 = cvQueryFrame(capture1);

cvShowImage("Webcam0",frame0);

cvShowImage("Webcam1",frame1);

if(cvWaitKey(10)>=0)

{

break;

}

}

cvReleaseCapture(&capture0);

cvDestroyWindow("Webcam0");

}

執行結果:

(1)選擇視訊裝置

(2)兩台Webcam同步播放

上面的程式,會跳出一個介面讓人選擇視訊裝置,這時選擇其中一個裝置就可以同步播放啦,但是,對於兩個視訊裝置二擇一的寫法,cvCreateCameraCapture()是不支援的,如果要將裝置做二擇一個設定,可以參考後面"cvcam.h"的相關設定.

cvCreateCameraCapture()

其實跟cvCaptureFromCAM()是一樣的,它被OpenCV定義成

#define cvCaptureFromCAM cvCreateCameraCapture

所以,當用cvCaptureFromCAM()會自動取代成cvCreateCameraCapture(),而在視訊裝置的使用上也大有學問,一般視訊裝置是0是自動偵測,有兩台以上就用函式及它的裝置代號重複呼叫,而它可以支援各種特殊裝置,如下:

#define CV_CAP_ANY 0 // autodetect

#define CV_CAP_MIL 100 // MIL proprietary drivers

#define CV_CAP_VFW 200 // platform native

#define CV_CAP_V4L 200

#define CV_CAP_V4L2 200

#define CV_CAP_FIREWARE 300 // IEEE 1394 drivers

#define CV_CAP_IEEE1394 300

#define CV_CAP_DC1394 300

#define CV_CAP_CMU1394 300

#define CV_CAP_STEREO 400 // TYZX proprietary drivers

#define CV_CAP_TYZX 400

#define CV_TYZX_LEFT 400

#define CV_TYZX_RIGHT 401

#define CV_TYZX_COLOR 402

#define CV_TYZX_Z 403

#define CV_CAP_QT 500 // QuickTime

對於多視訊裝置的實作,假如,有兩Window XP(VFW)的視訊裝置要控制,則用兩個相同的cvCreateCameraCapture()函式及兩個相同的CV_CAP_VFW代號,而OpenCV會有介面來選擇目標裝置.

cvCreateCameraCapture(裝置數字代號);

cvCreateVideoWriter()

它要放的引數分別為AVI檔名,AVI格式,FPS,CvSize資料結構及Avi檔的顏色種類,AVI的格式有很多種,由於影片有很多各個不同的壓縮格式,因此,被分為非常多類,許多的種類也只是在學術界採用,real player及media player很多都不適用,這邊壓縮格式的規格分為:

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

它的壓縮格是參數方法被定義在"highgui.h"裡的

#define CV_FOURCC(c1,c2,c3,c4) \

(((c1)&255) + (((c2)&255)<<8) + (((c3)&255)<<16) + (((c4)&255)<<24))

如果要使用mpge-1則直接使用int AviForamt=CV_FOURCC('P','I','M','1');就好啦,不過光是mpge-1壓縮格式real play跟media play就不支援播放,比較建議的是直接用-1,會有GUI介面幫你自己選擇檔案格式.雖然有些格是很多播放程式也是不支援,不過用起來方便許多.再來,FPS,每秒Frame的播放速度,frame有很多的翻譯,也可以叫它做框頁,用來做每秒畫面顯示的速度.AVI顏色種類,這個其實就很簡單啦,只有0跟1,0是黑白,1是彩色.

cvCreateVideoWriter("AVI檔名",AVI格式參數或代號,FPS,AVI大小CvSize資料結構,AVI顏色種類代號);

cvQueryFrame()

其實這是兩個副程式組合而成的,分別是cvGrabFrame()+cvRetrieveFrame(),這兩個副程式的實作會在下面的程式碼用出.

IplImage* cvQueryFrame(capture資料結構);

cvWriteFrame()

將frame寫入writer資料結構.

cvWriteFrame(writer資料結構,frame資料結構);

cvReleaseVideoWriter()

釋放writer資料結構,這邊cvReleaseVideoWriter()不只做了釋放資料結構的功能,還包括的AVI檔案格式的結尾製作,再做寫入AVI檔時一定要有cvReleaseVideoWriter()做結尾.

cvReleaseVideoWriter(writer資料結構)

--

附註:opencv1.1取消了AviForamt=-1的功能,並且要掛上ffopencv的函式庫才能使用,關於avi檔案的存取,必須要去Yahoo Group下載ffopencv110.dll覆蓋到C:\Program Files\OpenCV\bin的目錄底下

然後只能在Visual Studio的平台才能使用.

ffopencv使用的是ffmpeg library,ffmpeg只支援gcc 4.3版以上的編譯器,而Dev-C++使用的是gcc 3.4.2版的編譯器,因此在Dev-C++使用Opencv 1.1播放avi檔還是會有Error.