views:

107

answers:

2

Hello,

i am developing an application using opencv that manages a set of jpg images (user specifies the folder) and generates a video chronoconically based on EXIF date. my application must fullfilth the condition:

1) allow any fps value passed by user as parameter (any value between 1 and 100).

at the moment i choosed the CV_FOURCC('I', '4', '2', '0') codec and it works for any fps in that range, which is very cool.

however, im having problems with the size of the videos, they are uncompressed, and weight alot. any ideas on a compressed codec that satisfies the condition??

best regards Cristobal

A: 

I would suggest checking out the WebM VP8 Encoder although it really depends on the audience for the video. Obviously you would prefer to use a codec that the end user has installed.

If I understand what you are implying when you say you pass a frames per second value, you are specifying a JPG image and then saying, show that image for X number of frames?

Perhaps you should just build the video first and then compress it?

So, I guess the question would be -- does it need to be real time?

If not, you could batch process with FFmpeg.

Timothy Lee Russell
thanks for reply,
Cristobal
A: 

i checked for VP8 encoder on opencv but unfortenately it is not supported :(. About the framerate, yes, sometimes imput is a small subset of images (around 10 or 20), so on those cases they do not want 25fps, and will want to put 2fps for example. I checked the command "mencoder out.avi -ovc lavc -lavcopts vcodec=mpeg4:vqscale=4 -ffourcc DX50 -o comp.avi" and it worked, and maintained the framerate of the original video wherere it was 1 or 25 or 100. Strangely, when i converted with openCV using the same codec, it does not allow me to set 1fps. its weird. Thinking now, i have a last option, to compress each image before sending it as a videoframe, i found that higuiui.h header of opencv support encoding into memory, but i cannot find a single example where they use it. I think im having problems with the first parameter.

bool imencode( const string& ext,
const Mat& img,
vector<uchar>& buf,
const vector<int>& params=vector<int>());

//ext The file extension that defines the output format
//img The image to be written
//buf The output buffer; resized to fit the compressed image
//params The format-specific save parameters, encoded as pairs paramId 1, paramValue 1,
//paramId 2, paramValue 2, .... The following parameters are currently supported:
//• In the case of JPEG it can be a quality (CV IMWRITE JPEG QUALITY), from 0 to 100
//(the higher is the better), 95 by default.
//• In the case of PNG it can be the compression level (CV IMWRITE PNG COMPRESSION),
//from 0 to 9 (the higher value means smaller size and longer compression time), 3 by
//default.
//• In the case of PPM, PGM or PBM it can a binary format flag (CV IMWRITE PXM BINARY),
//0 or 1, 1 by default.

i tried to use it this way:

//frame is an IplImage*
vector<int> p;
p.push_back(CV_IMWRITE_JPEG_QUALITY);
p.push_back(10);
vector<unsigned char> buf;
cv::imencode("JPEG", frame, buf, p);

but i get error:

Main::Creating video (480x270)......
Output #0, avi, to 'out.avi':
    Stream #0.0: Video: rawvideo, yuv420p, 480x270, q=2-31, 8294 kb/s, 90k tbn, 1 tbc
writing frame 0 from block... 2010:02:08 20:54:47
OpenCV Error: Unspecified error (could not find encoder for the specified extension) in imencode, file /home/neoideo/OpenCV-2.1.0/src/highgui/loadsave.cpp, line 409
terminate called after throwing an instance of 'cv::Exception'
  what():  /home/neoideo/OpenCV-2.1.0/src/highgui/loadsave.cpp:409: error: (-2) could not find encoder for the specified extension in function imencode

i think im not using the parameters correctly, any help welcome, this can be the solution!

must it be realtime? not sure what you menat, the speed in realtime? the goal is i need to integrate the compression into my c++ program, so it is one packed program only.

sorry for bad engliss

Cristobal
What I meant by real time is does the compression need to work on a stream or can you build the entire video first and then compress it?
Timothy Lee Russell
My (admittedly basic) understanding of video compression is that it works by comparing differences between frames and then removes duplicate information. In other words, compressing individual frames and then appending them does not do the trick.
Timothy Lee Russell
it doesnt need to be realtime, is just that i would preffer to have the compression inside the program and not need to build a script around it with the compression command.
Cristobal
From what i understand (very basic too), if i compress each jpeg image with a lower value (95 is by default), i could end up with lighter videos eventually, even when its not video compression, it still satisfies the need, im just trying to make that code work, thanks for everything already Timothy!
Cristobal
i just checked and you were right Tim, even when i reduced the quality of each image (from 500kb to 40kb), the video size was the same,so the only option is a good video compressor. ill have to keep looking for a C/C++ type solution gogogogo
Cristobal
if someone knows any codec, supported by opencv, with compression and framerate values between [1, 100], i would be very thankful by knowning its fourcc code.
Cristobal
I guess I would re-suggest VP8. Check the source -- you should be able to integrate it, as it is in C. http://review.webmproject.org/gitweb?p=libvpx.git;a=blob;f=examples/encoder_tmpl.c;h=fdfc3af8f2e9a9987b1c8edef6008532d1c3b512;hb=7fed3832e7703628cd5ac595c4cb1f9c0ee5c7ce
Timothy Lee Russell
thanks, i will definetly take a look and in the worst case i will wrap a script around with a mencoder compression step.
Cristobal