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
How to Use Threads to Speed Up File Reading
What Is the Performance Impact of Using Int64_T Instead of Int32_T on 32-Bit Systems
How Much Overhead Is There When Creating a Thread
How to Make Function That Will Accept Multiple Data Types for Given Argument
Why Should I Initialize Member Variables in the Order They'Re Declared In
Check the File-Size Without Opening File in C++
Llvm Ir Back to Human-Readable Source Language
Inspecting Stl Containers in Visual Studio Debugging
Switch Passed Type from Template
Is It Legal for a C++ Optimizer to Reorder Calls to Clock()
C/C++ How to Copy a Multidimensional Char Array Without Nested Loops