2008年6月18日 星期三

GUI介面的製作-視訊,AVI檔案屬性控制

接著介紹Capture屬性相關設定,在視訊相關的,cvGetCaptureProperty()是唯讀狀態,只能用的是檢視視訊寬高,及它的編碼類型也就是以下三項:

cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_WIDTH);
cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_HEIGHT);
cvGetCaptureProperty(capture,CV_CAP_PROP_FOURCC);

以下使用程式方法

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


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

        printf("CV_CAP_PROP_FRAME_WIDTH : %.2f\n",cvGetCaptureProperty(capture,3));
        printf("CV_CAP_PROP_FRAME_HEIGHT : %.2f\n",cvGetCaptureProperty(capture,4));
        printf("CV_CAP_PROP_FOURCC : %.2f\n",cvGetCaptureProperty(capture,6));

        cvShowImage("Webcam",frame);
        if(cvWaitKey(20)>0)     break;
        i++;
    }

    cvReleaseCapture(&capture);
    cvReleaseVideoWriter(&writer);
    cvDestroyWindow("Webcam");
}

執行結果:


而cvGetCaptureProperty()比較強大的功能就在讀取AVI檔的時候,它可以做操作的功能用cvSetCaptureProperty(),可作用的參數為經過時間(毫秒),經過Frame數,AVI檔播放百分比,寬度,高度,每秒經過幾張Frame,Frame的總數等.

cvGetCaptureProperty(capture,CV_CAP_PROP_POS_MSEC)
cvGetCaptureProperty(capture,CV_CAP_PROP_POS_FRAMES)
cvGetCaptureProperty(capture,CV_CAP_PROP_POS_AVI_RATIO)
cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_WIDTH)
cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_HEIGHT)
cvGetCaptureProperty(capture,CV_CAP_PROP_FPS)
cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_COUNT)

而它可以做操控的部份,分為重新設定秒數位置,重新設定目前Frame位置,重新設定AVI目前播放百分比

cvSetCaptureProperty(capture,CV_CAP_PROP_POS_MSEC,毫秒數)
cvSetCaptureProperty(capture,CV_CAP_PROP_POS_FRAMES,Frame數)
cvSetCaptureProperty(capture,CV_CAP_PROP_POS_AVI_RATIO,播放百分比)

AVI檔讀檔程式的屬性修改
#include <cv.h>
#include <highgui.h>
#include <stdio.h>

int main()
{
    CvCapture *capture;
    IplImage *frame;
    char AviFileName[]="Output.avi";
    capture = cvCaptureFromAVI(AviFileName);
    cvNamedWindow("AVI player",0);

    printf("CV_CAP_PROP_POS_MSEC : %.2f\n",cvGetCaptureProperty(capture,0));
    printf("CV_CAP_PROP_POS_FRAMES : %.2f\n",cvGetCaptureProperty(capture,1));
    printf("CV_CAP_PROP_POS_AVI_RATIO : %.2f\n",cvGetCaptureProperty(capture,2));
    printf("CV_CAP_PROP_FRAME_WIDTH : %.2f\n",cvGetCaptureProperty(capture,3));
    printf("CV_CAP_PROP_FRAME_HEIGHT : %.2f\n",cvGetCaptureProperty(capture,4));
    printf("CV_CAP_PROP_FPS : %.2f\n",cvGetCaptureProperty(capture,5));
    printf("CV_CAP_PROP_FRAME_COUNT : %.2f\n",cvGetCaptureProperty(capture,7));
    cvWaitKey(0);

    while(true)
    {
        if(cvGrabFrame(capture))
        {
            frame=cvRetrieveFrame(capture);
            cvShowImage("AVI player",frame);

            printf("CV_CAP_PROP_POS_MSEC : %.2f\n",cvGetCaptureProperty(capture,0));
            printf("CV_CAP_PROP_POS_FRAMES : %.2f\n",cvGetCaptureProperty(capture,1));
            printf("CV_CAP_PROP_POS_AVI_RATIO : %.2f\n",cvGetCaptureProperty(capture,2));
            printf("CV_CAP_PROP_FRAME_WIDTH : %.2f\n",cvGetCaptureProperty(capture,3));
            printf("CV_CAP_PROP_FRAME_HEIGHT : %.2f\n",cvGetCaptureProperty(capture,4));
            printf("CV_CAP_PROP_FPS : %.2f\n",cvGetCaptureProperty(capture,5));
            printf("CV_CAP_PROP_FRAME_COUNT : %.2f\n",cvGetCaptureProperty(capture,7));

            if(cvWaitKey(10)>=0)     cvSetCaptureProperty(capture,2,0);
        }
        else
        {
            break;
        }
    }
    cvWaitKey(0);

    cvReleaseCapture(&capture);
    cvDestroyWindow("AVI player");
}

執行結果:
(1)

(2)


由上面程式可以看出來,CV_CAP_PROP_FRAME_WIDTH,CV_CAP_PROP_FRAME_HEIGHT,CV_CAP_PROP_FPS,CV_CAP_PROP_FRAME_COUNT的數值是固定不變的,它也具有不可修改的特性,每當程式在播放的時候,只要GUI介面觸及鍵盤事件,AVI播放率就會變成0,因此,影片就會重新播放.接下來介紹全部的參數對照的代號.

#define CV_CAP_PROP_POS_MSEC 0
#define CV_CAP_PROP_POS_FRAMES 1
#define CV_CAP_PROP_POS_AVI_RATIO 2
#define CV_CAP_PROP_FRAME_WIDTH 3
#define CV_CAP_PROP_FRAME_HEIGHT 4
#define CV_CAP_PROP_FPS 5
#define CV_CAP_PROP_FOURCC 6
#define CV_CAP_PROP_FRAME_COUNT 7

"highgui.h"裡面cvSetCaptureProperty()有16種參數,但其它都無法在AVI及視訊底下使用,也許他在其他的檔案格式下有不錯的應用.

cvGetCaptureProperty()
取得CvCapture相關屬性,區分為視訊播放及AVI檔的應用.
cvGetCaptureProperty(CvCapture資料結構,屬性參數或代號);

cvSetCaptureProperty()
重新設立屬性參數的數據,可修改的為時間,框頁數,AVI百分比.
cvSetCaptureProperty(CvCapture資料結構,屬性參數或代號,修改後數據);



2 意見:

rodmen 提到...

我用筆電的攝影機去攝影然後存成avi,aviformt也是用-1這個參數,但是我的撥放器卻無法執行,最嚴重的是我用你寫的avireader去撥放但卻沒有畫面,不過我拿一般電影的aiv檔案去撥放卻沒問題,可以請問這是我攝影機的關係嗎?

yester 提到...

可能是opencv版本的問題,前一篇有做個簡單的說明~

Copyright 2008-2009,yester