2011-02-02 145 views
12

我想寫一個程序來分析眼淚等情緒表達。作爲我的跟蹤器的一部分,我使用OpenCV來錄製示例視頻。特別是,我不確定如何正確選擇FPS(10FPS似乎應該工作)。我也不能肯定這 編解碼器,我應該在OS X上使用,我已經嘗試了從here所有可能CV_FOURCC很好,但返回以下錯誤:如何用OpenCV編寫視頻文件?

Stream #0.0: Video: rawvideo, yuv420p, 640x480, q=2-31, 19660 kb/s, 90k tbn, 10 tbc 
Assertion failed: (image->imageSize == avpicture_get_size((PixelFormat)input_pix_fmt, image->width, image->height)), function writeFrame, file /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_ports_graphics_opencv/work/OpenCV-2.2.0/modules/highgui/src/cap_ffmpeg.cpp, line 1085. 

你都與cvWriteFrame一些工作代碼?感謝您花時間看我的問題!

對於那些有興趣的整個程序是:

#include <cv.h> 
#include <cxcore.h> 
#include <highgui.h> 

int main (int argc, const char * argv[]) 
{ 
    CvCapture *capture; 
    IplImage *img; 
    int  key = 0; 
    CvVideoWriter *writer; 

    // initialize camera 
    capture = cvCaptureFromCAM(0); 
    // capture = cvCaptureFromAVI("AVIFile"); 

    // always check 
    assert(capture); 

    // create a window 
    cvNamedWindow("video", 1); 

    int color = 1; // 0 for black and white 

    // get the frame size 
    CvSize size = cvSize((int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH),(int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT)); 

    writer = cvCreateVideoWriter(argv[1], -1 , 10 , size, color); 

    while(key != 'q') { 
     // get a frame 
     img = cvQueryFrame(capture); 

     // always check 
     if(!img) break; 

     cvWriteFrame(writer, img);   
     cvShowImage("video", img); 

     // quit if user press 'q' 
     key = cvWaitKey(5); 
    } 

    // free memory 
    cvReleaseVideoWriter(&writer); 
    cvReleaseCapture(&capture); 
    cvDestroyWindow("video"); 

    return 0; 
} 
+1

什麼平臺/操作系統? – 2011-02-02 08:59:53

+1

您是否可以在SIGABRT之後編輯問題以包含打印在控制檯/終端中的錯誤消息?這將幫助我們更多地瞭解錯誤。 – speciousfool 2011-02-02 23:46:10

回答

17

看看here爲推薦使用的編解碼器。

基本上是:

  • 可以使用-1而不是CV_FOURCC(...)只有當你使用的是Windows(見manual)。既然你在OSX上,你不能使用它
  • 使用CV_FOURCC('I', 'Y', 'U', 'V')使用YUV420P到一個壓縮的AVI容器編碼 - 這是建議的方法
  • 如果你想壓縮視頻,那麼你可以使用工具,如ffmpeg通過OpenCV的

壓縮AVI輸出OpenCV不推薦使用壓縮編解碼器的原因可能是因爲每個編解碼器都有大量的編解碼器特定選項,並且通過簡單的OpenCV視頻編寫器界面處理所有這些選項是不可能的。

編輯

我有一些bad news

Unfortunately, we still have no working (i.e. native) video writer for Mac OS X. If you need video writing, you should currently configure for ffmpeg or xine and disable QuickTime.

聽起來像是你可能需要重新配置和重新編譯庫。

EDIT 2

或者,你可以只寫每一幀的JPEG文件,然後縫合這些JPEG文件到使用ffmpeg電影(即應在OS/X工作)。無論如何,這基本上就是MJPEG的。不過,使用時間冗餘的編解碼器(例如MPEG4,H.264等)可能會獲得更好的壓縮率。

0

我覺得CV_FOURCC行可能不正確。 A similar question建議使用-1作爲CV_FOURCC測試值來提示您在系統上的工作選擇。

您可以嘗試從該問題編譯程序,並告訴我們如果使用值-1而不是V_FOURCC('M', 'J', 'P', 'G')寫入AVI文件?

+1

大家好,感謝您的反饋。 我已經將值編輯爲-1而不是V_FOURCC('M','J','P','G')。程序現在可以執行並退出狀態值:0。 但是,該程序保存了一個顯然爲空的AVI電影文件(8 KB在磁盤上)。 我使用OS X/X代碼/ OpenCV 2.2。你們是否都有一些使用cvWriteFrame的工作代碼?感謝您花時間看我的問題!「 – CCS 2011-02-03 05:36:22

+0

我與@CCS有同樣的問題 – Lepi 2011-11-25 15:42:05

0

我認爲這是因爲視頻的大小 - 嘗試其他人,更常見的像640X480320X240

它適用於我。

3

聲明表明發送到視頻編寫器的圖像與初始化視頻編寫器時指定的大小之間存在大小不匹配。我會建議添加一些調試語句如下:

cout << "Video Size: " << size.width << "," << size.height << endl; 
cout << "Image Size: " << img.cols << "," << img.rows << endl; 

這應該會幫助您找出尺寸是否不同。

關於fourcc問題,看起來您正在使用cap_ffmpeg而不是cap_qtkit。您可能想嘗試使用ffmpeg進行重新編譯,因爲qtkit版本的捕獲在OS X上運行得很好。您可以直接從sourceforge下載opencv2.2,並使用ccmake配置opencv不使用ffmpeg,而不使用ffmpeg案例qtkit將是默認的。

如果你使用qtkit,那麼你需要使用fourcc('j','p','e','g');

幀頻應該與輸入的幀頻匹配。您可以使用這些屬性來獲得與幀寬和幀高相似的幀速率,但是由於您是從相機捕捉的,因此您可能必須通過在代碼中使用計時器來測試捕捉速率,並從那。

這是基於starter_video.cpp一個例子,將與qtkit工作:

/* 
* starter_video_write.cpp 
* 
* Created on: Nov 23, 2010 
*  Author: Ethan Rublee 
* Modified on: Aug 3, 2011 by David Cooper 
* 
* A starter sample for using opencv, get a video stream and display the images 
* easy as CV_PI right? 
* edited to add writing capability for OS X using qtkit. 
*/ 
#include "opencv2/highgui/highgui.hpp" 
#include <iostream> 
#include <vector> 
#include <stdio.h> 

using namespace cv; 
using namespace std; 



//hide the local functions in an anon namespace 
namespace { 
    void help(char** av) { 
     cout << "\nThis program justs gets you started reading images from video\n" 
      "Usage:\n./" << av[0] << " <video device number>\n" 
      << "q,Q,esc -- quit\n" 
      << "space -- save frame\n\n" 
      << "\tThis is a starter sample, to get you up and going in a copy pasta fashion\n" 
      << "\tThe program captures frames from a camera connected to your computer.\n" 
      << "\tTo find the video device number, try ls /dev/video* \n" 
      << "\tYou may also pass a video file, like my_vide.avi instead of a device number" 
      << endl; 
    } 

    int process(VideoCapture& capture) { 
     int n = 0; 
     char filename[200]; 
     string window_name = "video | q or esc to quit"; 
     cout << "press space to save a picture. q or esc to quit" << endl; 
     namedWindow(window_name, CV_WINDOW_KEEPRATIO); //resizable window; 
     Mat frame; 
    double frameRate = 15.0; 
    capture >> frame; 
    VideoWriter* writer = NULL; 
    // FIXME: need to change this to an absolute path that exists on this system 
    string outputFile = "/tmp/test.mov"; 
    writer = new VideoWriter(outputFile, 
       CV_FOURCC('j','p','e','g'), 
       frameRate,Size(frame.cols,frame.rows)); 


     for (;;) { 
      capture >> frame; 
      if (frame.empty()) 
       continue; 
      imshow(window_name, frame); 
     writer->write(frame); 
      char key = (char)waitKey(5); //delay N millis, usually long enough to display and capture input 
      switch (key) { 
     case 'q': 
     case 'Q': 
     case 27: //escape key 
      if(writer != NULL) { 
     delete writer; 
      } 
      return 0; 
     case ' ': //Save an image 
      sprintf(filename,"filename%.3d.jpg",n++); 
      imwrite(filename,frame); 
      cout << "Saved " << filename << endl; 
      break; 
     default: 
      break; 
      } 
     } 
     return 0; 
    } 

} 

int main(int ac, char** av) { 

    if (ac != 2) { 
     help(av); 
     return 1; 
    } 
    std::string arg = av[1]; 
    VideoCapture capture(arg); //try to open string, this will attempt to open it as a video file 
    if (!capture.isOpened()) //if this fails, try to open as a video camera, through the use of an integer param 
     capture.open(atoi(arg.c_str())); 
    if (!capture.isOpened()) { 
     cerr << "Failed to open a video device or video file!\n" << endl; 
     help(av); 
     return 1; 
    } 
    return process(capture); 
} 
0

閱讀Misha的答案後。 我通過使用Homebrew重新安裝opencv,在Mac OS 10.9 Mavericks和XCode 5下解決了這個問題。

brew安裝opencv --with-ffmpeg

2

我有同樣的問題。 我通過使用平面RGB編解碼器解決了它。

outputVideo.open(PathName, CV_FOURCC('8','B','P','S'), myvideo.get(CV_CAP_PROP_FPS),CvSize(outputframe.size())); 

輸出大小很重要,但它的工作原理沒有安裝任何東西。