Opencv to Use in Memory Buffers or File Pointers

OpenCV to use in memory buffers or file pointers

There are a couple of undocumented functions in the SVN version of the libary:

CV_IMPL CvMat* cvEncodeImage( const char* ext, 
const CvArr* arr, const int* _params )

CV_IMPL IplImage* cvDecodeImage( const CvMat* _buf, int iscolor )

Latest check in message states that they are for native encoding/decoding for bmp, png, ppm and tiff (encoding only).

Alternatively you could use a standard image encoding library (e.g. libjpeg) and manipulate the data in the IplImage to match the input structure of the encoding library.

Writing video on memory OpenCV 2

In OpenCV, every video is treated as a collection of frames(images). Depending on your cameras' FPS you can capture frames periodically and fill the buffer with them. Meanwhile you can destroy the oldest frame(taken 1 min before). So a FIFO data structure can be implemented to achieve your goal. Getting a 13 second sample is easy, just jump to a random frame and write 13*FPS frames sequentially to a video file.

But there will be some sync and timing problems AFAIK and as far as I've used OpenCV.

Here is the link of OpenCV documentation about video i/o. Especially the last chunk of code is what you will use for writing.

TL;DR : There is no video, there are sequential images with little differences. So you need to treat them as such.

OpenCV jpeg format image in memory

How did you want to code the image in the string?

You could just store red,green,blue values as comma separated strings but coding the image binary as something like base64 would be more compact.

Edit: if you mean a jpeq format in memory see - OpenCV to use in memory buffers or file pointers

OpenCV: cvCloneImage and memory leak

For your memory leak issue:

cvCreateImage allocated memoryA for the image, and cvCloneImage allocated memoryB (and cloning whatever value stored in img as stated in your code). cvReleaseImage(&img_dest) only deallocate memoryB thus memoryA is left unreferenced but not deallocated.

For your IPL Image copying:

Declare another memory and use command cvCopy, i dont see any difficulties in using it and it is safe and efficient.

If you wish to declare an IPL image header without allocating data byte for storing image value, use CreateImageHeader instead. I would advise you to spend some time mastering cvCreateImage, cvCreateImageHeader, cvCreateData, cvReleaseImage, cvReleaseImageHeader, cvReleaseImageData and cvCloneImage.

process video stream from memory buffer

I had a similar need recently. I was looking for a way in OpenCV to play a video that was already in memory, but without ever having to write the video file to disk. I found out that the FFMPEG interface already supports this through av_open_input_stream. There is just a little more prep work required compared to the av_open_input_file call used in OpenCV to open a file.

Between the following two websites I was able to piece together a working solution using the ffmpeg calls. Please refer to the information on these websites for more details:

http://ffmpeg.arrozcru.org/forum/viewtopic.php?f=8&t=1170

http://cdry.wordpress.com/2009/09/09/using-custom-io-callbacks-with-ffmpeg/

To get it working in OpenCV, I ended up adding a new function to the CvCapture_FFMPEG class:

virtual bool openBuffer( unsigned char* pBuffer, unsigned int bufLen );

I provided access to it through a new API call in the highgui DLL, similar to cvCreateFileCapture. The new openBuffer function is basically the same as the open( const char* _filename ) function with the following difference:

err = av_open_input_file(&ic, _filename, NULL, 0, NULL);

is replaced by:

ic = avformat_alloc_context();
ic->pb = avio_alloc_context(pBuffer, bufLen, 0, pBuffer, read_buffer, NULL, NULL);

if(!ic->pb) {
// handle error
}

// Need to probe buffer for input format unless you already know it
AVProbeData probe_data;
probe_data.buf_size = (bufLen < 4096) ? bufLen : 4096;
probe_data.filename = "stream";
probe_data.buf = (unsigned char *) malloc(probe_data.buf_size);
memcpy(probe_data.buf, pBuffer, probe_data.buf_size);

AVInputFormat *pAVInputFormat = av_probe_input_format(&probe_data, 1);

if(!pAVInputFormat)
pAVInputFormat = av_probe_input_format(&probe_data, 0);

// cleanup
free(probe_data.buf);
probe_data.buf = NULL;

if(!pAVInputFormat) {
// handle error
}

pAVInputFormat->flags |= AVFMT_NOFILE;

err = av_open_input_stream(&ic , ic->pb, "stream", pAVInputFormat, NULL);

Also, make sure to call av_close_input_stream in the CvCapture_FFMPEG::close() function instead of av_close_input_file in this situation.

Now the read_buffer callback function that is passed in to avio_alloc_context I defined as:

static int read_buffer(void *opaque, uint8_t *buf, int buf_size)
{
// This function must fill the buffer with data and return number of bytes copied.
// opaque is the pointer to private_data in the call to avio_alloc_context (4th param)

memcpy(buf, opaque, buf_size);
return buf_size;
}

This solution assumes the entire video is contained in a memory buffer and would probably have to be tweaked to work with streaming data.

So that's it! Btw, I'm using OpenCV version 2.1 so YMMV.

Copying OpenCV mat to a known address with memcpy

Ok. I solved this issue ;

    Mat img = Mat(height, width, CV_8UC4, address);
cv::imshow("Image from GM", img);
// same image copy to buffer back;
memcpy(&address[0], &img.data[0], width*height*4.);

Convert YUV to lossy compression with OpenCV

OpenCV itself does not export this functionality. Cleanest is to use libjpeg for encoding. See the answers to these questions:

  • Convert IplImage into a JPEG without using CvSaveImage in OpenCV
  • OpenCV to use in memory buffers or file pointers

opencv read jpeg image from buffer

I have decompressed the JPEG image using libjpeg using the standard procedure described in the libjpeg API documentation under 'Decompression details'.

After having decompressed the data you can use it to construct the cv::Mat. Mind you, the decompressed image is in RGB format, whereas openCV uses a BGR format so a cvtColor() operation with format CV_RGB2BGR is needed.

Change data of OpenCV matrix from pointer

You need to create a deep copy. You can use clone:

cv::Mat colorFrame = cv::Mat(height, width, CV_8UC3, pointerToMemoryOfCamera).clone();

You can also speed up the process of saving the images using matwrite and matread functions.



Related Topics



Leave a reply



Submit