Just a Computer Graphics Studio & My Life

由於專案需求,需要以程式來播放影片,希望能在高解析度下,還能流暢地播放影片~原本還以為OpenCV只有處理影像比較強,而處理影片則比較弱,其實不然,還是由自己親自實驗後,才知道只有跟影像有關的應用,OpenCV都有可能辦到!

OpenCV 播放影片 Display Video (1)

程式碼有兩個版本,這是其一:

/**
	Theme: Video Player
	compiler: Dev C++ 4.9.9.2
	Date: 102/03/21
	Author: HappyMan
	Blog: https://cg2010studio.wordpress.com/
*/
#include <cv.h>
#include <highgui.h>
#include<iostream>
using namespace std;

int main()
{
    CvCapture *capture;
    IplImage *frame;
    char AviFileName[]="Happy Game Animation.avi";
    capture = cvCaptureFromAVI(AviFileName);
    //得到總幀數
    int frames = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT);
    //獲得幀率
    int fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
	cout<<"frames:"<<frames<<endl;
	cout<<"fps:"<<fps<<endl;
    cvNamedWindow("Video Player",0);

    while(true)
    {
        if(cvGrabFrame(capture))
        {
            frame=cvRetrieveFrame(capture);
            cvShowImage("Video Player",frame);

            if(cvWaitKey(10)>=0) break;
        }
        else
        {
            break;
        }
    }
    cvReleaseCapture(&capture);
    cvDestroyWindow("Video Player");
    return 0;
}

執行結果:

frames:4496
fps:29

並開啟一個視窗播放仙劍奇俠傳五宣傳短片,我擷取某一幀的畫面如最上圖。原本以為只能處理avi檔,然而我測試了mp4檔mkv檔都可以播放,函式名稱真會讓人疑惑呢!

這則程式碼中cvNamedWindow第二個參數設為0,使得視窗可以隨意調整大小~

此版本雖然可以調整視窗大小,不過在視窗縮小的時候播放速度會變快,而視窗放大的時候播放速度會變慢。

第二版本程式碼:

/**
	Theme: Video Player
	compiler: Dev C++ 4.9.9.2
	Date: 102/03/21
	Author: HappyMan
	Blog: https://cg2010studio.wordpress.com/
*/
#include <cv.h>
#include <highgui.h>
#include<iostream>
using namespace std;

int AVI_position = 0;
CvCapture* capture = NULL;
void on_track_bar_slide(int pos){
    cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, pos);
}
int main(){
    capture = cvCreateFileCapture("Happy Game Animation.avi");
    //得到總幀數
    int frames = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT);
    //獲得幀率
    int fps = cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
    cvNamedWindow("Video Player", CV_WINDOW_AUTOSIZE);
    if (frames != 0){
		//建立時間軸
        cvCreateTrackbar("postion", "Video Player", &AVI_position, frames, on_track_bar_slide);
    }
    IplImage* frame;
    frames = 0;
    while(true){
		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_FOURCC : %.2f\n",cvGetCaptureProperty(capture,6));
        printf("CV_CAP_PROP_FRAME_COUNT : %.2f\n",cvGetCaptureProperty(capture,7));
        frame = cvQueryFrame(capture);
        if (!frame) break;
        cvShowImage("Video Player", frame);
        cvSetTrackbarPos("postion", "Video Player", AVI_position++);
        //1000毫秒60幀圖像 (1幀圖像 = 16.6毫秒)
        char c = cvWaitKey(16);
        //按ESC退出
        if (c == 27) break;
    }
    AVI_position = 0;
    cvReleaseCapture(&capture);
    cvDestroyWindow("Video Player");
    return 0;
}

執行結果不斷更新顯示:

CV_CAP_PROP_POS_MSEC : 2869.53
CV_CAP_PROP_POS_FRAMES : 86.00
CV_CAP_PROP_POS_AVI_RATIO : 0.02
CV_CAP_PROP_FRAME_WIDTH : 1280.00
CV_CAP_PROP_FRAME_HEIGHT : 720.00
CV_CAP_PROP_FPS : 29.97
CV_CAP_PROP_FOURCC : 1482049860.00
CV_CAP_PROP_FRAME_COUNT : 4496.00

以上參數意義分別代表:經過時間(毫秒)、經過Frame數、AVI檔播放百分比、寬度、高度、每秒經過幾張Frame、(不知道)、Frame的總數。

此範例設定一條時間軸,可以像播放器一樣點選某一時間點來放映。

cvWaitKey函式為等待按鍵事件,delay參數為延遲毫秒數

  • int cvWaitKey( int delay=0 );

函式cvWaitKey無限制的等待按鍵事件(delay<=0時);或者延遲delay毫秒。返回值為被按鍵的值,如果超過指定時間則返回-1。

可以透過上述函式設定延遲時間,來達到720p(1280×720)每秒播放60張frame的需求!

OpenCV 播放影片 Display Video

參考:GUI介面的製作-AVI檔案開啟GUI介面的製作-視訊,AVI檔案屬性控制利用OpenCV播放AVI的例子Displaying AVI Video using OpenCV

Advertisements

Comments on: "[OpenCV] 播放影片 (Display Video)" (9)

  1. 請問影片檔釋放哪裡呢 我是以用visul studio 2012

    喜歡

  2. 您好,請問為什麼編譯時,#include 這行一直有錯誤呢?然後using namespace std;這行是什麼意思?

    喜歡

  3. 請問大大
    我最近學習使用opencv 並用2012開發,可是撥放影片時,遇到一個很離奇的問題
    “第一次"編譯會過並且順利執行,可是"第二次"編譯時,是有過,可是一執行就遇到記憶體存取的問體,而且屢試不爽,敢問大大是我哪裡設定出了問題嗎@@

    喜歡

發表留言

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s

標籤雲

%d 位部落客按了讚: