2011-02-02 112 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())); 

输出大小很重要,但它的工作原理没有安装任何东西。

相关问题