2016年3月15日 星期二

Capture Video from File using OpenCV

Capture Video from File using OpenCV

一般的影像來源分為兩種,一個是圖片(image),一個就是串流,雖然串流(stream)也是會切成一張一張的影像在做影像操作。
而串流(stream)又可分為視訊串流跟影片串流,這裡介紹如何從影片檔案得到串流,再切成影像進行操作。

C API

int main( int argc, const char** argv )
{
    IplImage* image;
    CvCapture* capture = cvCreateFileCapture("D:/Wildlife.wmv");

    if ( capture == NULL ) {
        std::cout << "Cannot open the video file on C API" << std::endl;
        return -1;
    }

    for (;;) {
        image = cvQueryFrame( capture );
        cvShowImage("Video Frame", image);
        cvWaitKey( 33 );
    }

    cvReleaseCapture( &capture );
    return 0;
}

C++ API

int main( int argc, const char** argv )
{
    cv::Mat frame;
    cv::VideoCapture cap("D:/Wildlife.wmv");

    if ( !cap.isOpened() ) {
        std::cout << "Cannot open the video file on C++ API" << std::endl;
        return -1;
    }

    for (;;) {
        cap.read(frame);
        cv::imshow("Video Frame", frame);
        cv::waitKey( 33 );
    }
    return 0;
}

如果一直無法開啟影片,請檢查是否有加入OpenCV的ffmpeg檔

更多OpenCV文章請參考:OpenCV Tutorial (學習筆記)

7 則留言:

  1. 你好
    我是opencv的新手
    我想請問一下
    要如何在opencv加入ffmpeg檔?

    回覆刪除
    回覆
    1. Hi, 我指的是Library中的opencv_ffmpeg248.dll。

      刪除
    2. 作者已經移除這則留言。

      刪除
    3. 我Library中已經有opencv_ffmpeg248.dll
      還是無法讀影片,跳出這段訊息
      warning: Error opening file (../../modules/highgui/src/cap_ffmpeg_impl.hpp:545)
      可以請問原因嗎???
      感謝

      刪除
    4. 我沒遇過這個問題,可能先確定路徑位置是不是確定有影片。
      或是換成播其他影片格式的影片試試。

      刪除
  2. 作者已經移除這則留言。

    回覆刪除
  3. 謝謝版大,我試過版大的code,發現會抓不到最後一張的資料,於是稍作調整,提供給需要的人
    #include
    #include
    #include
    #include
    #include
    using namespace cv;
    using namespace std ;


    void test(Mat&,int);
    void save(Mat&,int);
    int NumFrm=0;
    int n_save = 0;
    struct CvVideoWriter *writer = 0; //寫入影片

    int main()
    {
    cv::Mat frame;
    cv::VideoCapture cap("a.avi");
    if ( !cap.isOpened() ){std::cout << "Cannot open the video file on C++ API" << std::endl;return -1;}
    VideoWriter writer( "outputVideo.avi", CV_FOURCC('D','I','V','X'),25, cv::Size (320,240), true );
    //if (frame.empty()) { printf("empty img\n"); return -1; }
    while(true)
    {
    NumFrm++;
    if(NumFrm!=1&&!cap.read(frame))
    {
    printf("--------------------------NumFrm %d\n",NumFrm);
    break;
    }
    else
    {
    cap.read(frame);
    cv::imshow("C++ API Image", frame);
    cv::waitKey(10);
    }
    test(frame,NumFrm);
    save(frame,NumFrm);
    writer<(y);
    for( int x = 0; x < image.cols; x++ ) {
    // 値の取得
    // 対象のピクセルが赤だった場合、BGRの順に"0,0,255"と出力される。
    //if(NumFrm%2==0)
    //{
    //if (x%2==0 && y % 2 == 0)
    //if (y % 2 == 0)

    if ((x%2!=0)&&(y % 2 != 0))
    {
    ptr[x] = cv::Vec3b(0, 0, 0);
    }
    else
    {
    if((x%2==0)&&(y % 2 == 0))
    {
    ptr[x] = cv::Vec3b(0, 0, 0);
    }
    }

    //}
    //else
    //{
    // //if (x%2!=0 && y % 2 != 0)
    // //if (y % 2 != 0)
    // if ((x%2==0) && (y%2==0))
    // {
    // ptr[x] = cv::Vec3b(0, 0, 0);
    // }
    // else
    // {
    // if((x%2!=0)&&(y % 2!= 0))
    // {
    // ptr[x] = cv::Vec3b(0, 0, 0);
    // }
    // }

    //}
    //cv::Vec3b bgr = ptr[x];
    //printf("%d,%d,%d ", bgr[0], bgr[1], bgr[2]);
    }
    //printf("\n");
    }}
    void save(Mat& image, int NumFrm)
    {
    char filename[200];
    sprintf(filename, "./frame/frame_%d.jpg", NumFrm);
    imwrite(filename, image);
    cout << "save: " << filename << endl;
    }

    回覆刪除