2008年6月19日 星期四

GUI介面的製作-"cvcam.h"視訊函式庫(3)

"cvcam.h"也可以做AVI檔的播放,它也可以同樣利用方法呼叫來做frame的修改,而他同樣的,也是使用到IplImage的資料結構,這邊做一個播放檔案的程式

使用cvcam.h做AVI檔播放
#include <cvcam.h>
#include <cv.h>
#include <highgui.h>
#include <windows.h>

void CaptureCallback(IplImage *image);

int main()
{
    HWND CaptureWindow;
    cvNamedWindow("AVIplayer",0);
    CaptureWindow =(HWND)cvGetWindowHandle("AVIplayer");
    cvcamPlayAVI("Output.avi",CaptureWindow,640,480,(void *)&CaptureCallback);

    cvWaitKey(0);

}
void CaptureCallback(IplImage *frame)
{
}

執行結果:
video

在這邊,CaptureCallback內沒有任何程式碼,因為他的IplImage資料結構的Frame受到AVI檔案的格式影響,如果說要用一般Capture的檔案格式,則在檔案寫入時要選擇用全畫面(未壓縮),不過這樣付出的代價是很驚人的,不用幾秒鐘就超過50MB的檔案,而如果選擇壓縮格式的話,IplImage資料結構就要符合該壓縮格式的讀檔方式來對IplImage資料結構存取,因此,CaptureCallback()的框頁製作,要符合使用的壓縮格式來做畫面的修改.除了這個,cvcamPlayAVI()也提供了對HWND的支援,因此可以選定目標視窗來做AVI檔影片播放的動作.

cvcamPlayAVI()
播放AVI檔案的函式,它可以藉由自己定義的方法呼叫來修改frame的內容,但是要符合AVI壓縮檔案的檔案格式.假如檔案名稱的地方改成0,則他會出現開啟檔案的視窗由使用者選擇目標的AVI檔,
cvcamPlayAVI("檔案名稱",視窗ID,播放寬度,播放高度,自行定義的方法呼叫名稱);

再來用的是另一個AVI播放的函式,這個函式使用起來有點特別,有些地方要注意一下,這邊拿兩個AVI檔案播放來做比較.

cvcam.h的AVI播放函式
#include <cvcam.h>
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <windows.h>


void CaptureCallback(IplImage *image);
void onMouse(int Event,int x,int y,int flags,void *param);

cvcamAVIFILE cvcamAVIFILE1;
cvcamAVIFILE cvcamAVIFILE2;
int main()
{
    HWND CaptureWindow;
    cvNamedWindow("AVIplayer",0);
    CaptureWindow = (HWND)cvGetWindowHandle("AVIplayer");
    char AVIFileName1[]="Output.avi";
    char AVIFileName2[]="Output2.avi";

    cvcamAVIFILE1=cvcamAVIOpenFile(AVIFileName1);
    printf("%d\n",cvcamAVIFILE1);
    cvcamAVIFILE2=cvcamAVIOpenFile(AVIFileName2);
    printf("%d\n",cvcamAVIFILE2);

    cvcamAVISetWindow(1,(void *)CaptureWindow);
    cvcamAVISetCallback(1,(void *)&CaptureCallback);
    cvcamAVISetSize(1,320,240);

    cvSetMouseCallback("AVIplayer",onMouse,NULL);

    cvcamAVIRun(1);

    cvWaitKey(0);

    cvcamAVIStop(1);
    cvcamAVICloseFile(0);
    cvcamAVICloseFile(1);
}

void CaptureCallback(IplImage *frame)
{

}
void onMouse(int Event,int x,int y,int flags,void* param )
{
    if(Event==CV_EVENT_LBUTTONDOWN)
    {
        cvcamAVIPause(1);

    }
    else if(Event==CV_EVENT_RBUTTONDOWN)
    {
        cvcamAVIResume(1);
    }
}

執行結果:
video
(中間用滑鼠暫停了兩次)

為什麼要用兩個AVI檔案來測試呢?因為在"cvcam.h"內定義的使用格式為

int cvcamAVICloseFile(cvcamAVIFILE file);
int cvcamAVISetWindow(cvcamAVIFILE file, void* window);
int cvcamAVISetCallback(cvcamAVIFILE file, void* callback);
int cvcamAVISetSize(cvcamAVIFILE file, int width, int height);
int cvcamAVIRun(cvcamAVIFILE file);
int cvcamAVIStop(cvcamAVIFILE file);
int cvcamAVIPause(cvcamAVIFILE file);
int cvcamAVIResume(cvcamAVIFILE file);
int cvcamAVIWaitCompletion(cvcamAVIFILE file);
int cvcamAVIIsRunning(cvcamAVIFILE file);

這將會產生一個很嚴重的衝突,實際上,OpenCV的程式人員是想讓被開啟的AVI檔能像視訊播放程式的方式用裝置代碼表示,也就是,第一個avi檔出現的時候就用代號0,第二個就用代號1,但不幸的,直接把cvcamAVIFILE丟給它會給它的數字是1000,而第二個數字是1001,這將會造成AVI函式無法執行,而這邊的程式,就用第二的AVI檔來做影片播放,這邊的功能使用上也是很方便,跟前面的視訊播放一樣,可以開始,暫停,繼續,結束等操作,也可以藉由HWND來做嵌入視窗,這邊的設計就沿用了之前滑鼠事件的做法.而他的框頁修改的部份(CaptureCallback())也必須要參考AVI檔的檔案格式.

cvcamAVIOpenFile()
開啟AVI檔案,要用cvcamAVIFILE資料結構接收,但實際上,可以不需要用到cvcamAVIFILE資料結構就可以執行,cvcamAVIOpenFile()之後的程式只要輸入檔案代碼即可,就像視訊的cvcamGetCamerasCount()使用方法一樣.
cvcamAVIOpenFile("AVI檔案名稱");

cvcamAVICloseFile()
關閉AVI檔案,如果不做這個動作的話程式執行結束會當掉,參數要傳給它AVI檔案的代號.
cvcamAVICloseFile(AVI檔案代號)

cvcamAVISetWindow()
設定程式要嵌入的視窗,給它AVI檔案的代號,及視窗的HWND視窗ID.
cvcamAVISetWindow(AVI檔案代號,HWND視窗代號);

cvcamAVISetCallback()
可以藉由方法呼叫修改AVI檔的frame,但是要符合AVI檔的檔案格式.
cvcamAVISetCallback(AVI檔案代號,自行定義的副程式名稱);

cvcamAVISetSize()
設定AVI檔案的播放大小.
cvcamAVISetSize(AVI檔案代號,畫面寬度,畫面高度);

cvcamAVIRun()
選定目標要播放的AVI檔案
cvcamAVIRun(AVI檔案代號);

cvcamAVIStop()
停止目標AVI檔案的播放.
cvcamAVIStop(AVI檔案代號);

cvcamAVIPause()
暫停目標正在播放的AVI檔案.
cvcamAVIPause(AVI檔案代號);

cvcamAVIResume()
繼續執行目標被暫停的AVI檔案.
cvcamAVIResume(AVI檔案代號);

--
附註:Opencv1.0 only,如果opencv 1.1想要使用的話,可以到sourceforge的opencv網站上下載

3 意見:

Yu Liu 提到...

请问:为什么没有播放第一个视频呢?

Yu Liu 提到...

再请问:如果我需要播放第一视频之后,连续播放第二个视频,可以吗?

匿名 提到...

無法開啟包含檔案: 'cvcam.h'
這是要怎樣解決???

Copyright 2008-2009,yester