I am trying to write a program to analyze emotional expressions like tears. As part of my tracker I am using OpenCV to record sample videos. Particularly, I am not certain about how to correctly choose FPS (10FPS seems like it ought to work). I am also not sure which Codec I should use on OS X, I have tried all possible CV_FOURCC from here as well but returned the following error:
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.
Do you all have some working code with cvWriteFrame? Thanks for taking time to look at my problem!
For those interested the entire program is:
#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;
}
The assertion suggests that there is a size mismatch between the image being sent to the video writer, and the size specified when initializing the video writer. I would suggest adding some debug statements as follows:
That should help you find out if the sizes are different.
With regard to the fourcc question, it looks like you are using cap_ffmpeg instead of cap_qtkit. You may want to try recompiling with ffmpeg off, since the qtkit version of capture works pretty well on OS X. Rather than using macports, you can directly download opencv2.2 from sourceforge and use ccmake to configure opencv not to use ffmpeg, in that case qtkit will be the default.
If you do use qtkit, then you need to use the fourcc('j','p','e','g');
The frame rate should match the frame rate of the input. You can use the properties to get the frame rate similar to the way you got the frame width and height, however since you are capturing from the camera, you will probably have to test the capture rate by using a timer in your code and estimating from that.
Here is an example based on starter_video.cpp that will work with qtkit:
After reading misha's answer. I resolved this problem under Mac OS 10.9 Mavericks and XCode 5 by reinstall opencv using Homebrew.
brew install opencv --with-ffmpeg
Have a look here for the recommended codecs to use.
Basically:
-1
instead ofCV_FOURCC(...)
only if you're on Windows (see the manual). Since you're on OSX, you can't use it.CV_FOURCC('I', 'Y', 'U', 'V')
to encode using yuv420p into an uncompressed AVI container -- this is the recommended approachffmpeg
to compress the AVI output by OpenCVThe reason OpenCV doesn't recommend using compressor codecs is probably because each codec has a large number of codec-specific options, and dealing with all of them through the simple OpenCV video writer interface would be impossible.
EDIT
I have some bad news:
Sounds like you may need to reconfigure and recompile your library.
EDIT 2
Alternatively, you could just write each frame to a JPEG file, and then stitch those JPEG files into a movie using
ffmpeg
(that should work on OS/X). This is essentially what MJPEG is, anyway. You'll probably get better compression rates with codecs that exploit temporal redundancy (e.g. MPEG4, H.264, etc), though.I had the same problem. I solved it by using the Planar RGB Codec.
The output size is important, but it works without installing anything.
I think the
CV_FOURCC
line may be incorrect. A similar question suggests using-1
as aCV_FOURCC
test value to prompt you with the working choices on your system.Can you try to compile the program from that question and tell us if using a value of
-1
instead ofV_FOURCC('M', 'J', 'P', 'G')
writes an AVI file?I think that's because of the size of the video - try others, more common like
640X480
or320X240
.It works for me.