Download: https://github.com/dimitrs/video_coding
OpenCV provides a very simple api to connect to a camera and show the images in a window. It is also very simple to encode those images and store them on disk. However, the simple api provides no means by which to encode an image without storing it on disk and even worse, no means to decode an image stored in memory instead of on disk. Assuming I want to capture an image from a camera and send it over a socket to a receiver, one might want to first compress the image before sending it. A simple test I did indicated that an image can be compressed by a factor of 10 using the mpeg-4 codec. This is really important for streaming applications.
On Linux and Windows, OpenCV’s underlying implementation uses the ffmpeg library to encode/decode frames to and from disk. I found the implementation in opencv\modules\highgui\src\cap_ffmpeg_impl.hpp. In this post, I provide a small test project with a modified version of cap_ffmpeg_impl.hpp. This version allows you to encode/decode images to and from a buffer instead of disk. Warning: The code is a proof of concept and not production ready. You can find the project in github.
Below, you can see how to encode/decode video:
Initializing capture from a camera:
CvCapture* capture = cvCaptureFromCAM(CV_CAP_ANY);
Capturing a frame:
cvGrabFrame(capture); // capture a frame
IplImage* img = cvRetrieveFrame(capture); // retrieve the captured frame
Initialize a video encoder:
int fps = 10;
int width = 320;
int height = 320;
CvVideoWriter_FFMPEG writer;
writer.init();
writer.open("x.mpg", CV_FOURCC('D', 'I', 'V', 'X'), fps, width, height, true);
Encoding the previously captured image:
int wStep = img->widthStep;
int w = img->width;
int h = img->height;
int c = img->nChannels;
writer.writeFrame((const uchar*)img->imageData, wStep, w, h, c, img->origin);
Initialize a video decoder:
CvCapture_FFMPEG cap;
cap.open(width, height);
Decoding the previously encoded image:
uint8_t* buffer = &writer.outbuf[0];
int length = writer.out_size;
cap.grabFrame(buffer, length);
IplImage* img2 = cap.retrieveFrame();
Show image in a window:
if (img2)
{
cvShowImage("My Window", img2 );
cvWaitKey();
}
Wednesday, February 22, 2012
Encode and Decode Video from Memory
Subscribe to:
Post Comments (Atom)
WOW THIS IS SO INTERESTING AND THIS CAN ALSO BE USED IN LINUX HURRAYYYYYYYYYYYYY
ReplyDeleteimage decoding
This comment has been removed by the author.
ReplyDeletewonderful!!!
ReplyDeletethe great blog.thanks for sharing information about linux.
keep blogging.
captcha solving
can we capture audio and video through these lines of code?
ReplyDelete