How to appropriately destroy mxArray created by ocvMxArray​FromImage_​{DataType} functions

Dear all, I am trying to integrate Matlab code into C++ program with OpenCV. I found the program will gradually increase memory usage.
After some working around, I believe the problem has something to do with destroying mxArray. I wrote a simple test program with an infinite loop that keeps create mxArray and destroy it, as shown below
cv::Mat imageMat = cv::imread(imagePath);
while(true)
{
mxArray* imageMXA = ocvMxArrayFromImage_uint8(imageMat);
mxDestroyArray(imageMXA);
}
this program will gradually increase memory usage.
However, another test program that creates mxArray with mxCreateNumericArray does not have such problem. the code is shown below
while(true)
{
mxArray* imageMXA = mxCreateNumericArray(dimensionNumber, dimensions, mxDOUBLE_CLASS, mxREAL);
mxDestroyArray(imageMXA);
}
It seems that there is something wrong in the code that destroy the mxArray created by ocvMxArrayFromImage_{DataType} functions. My question is, how should I appropriately destroy such mxArray?

7 Comments

You would probably need to see the code for ocvMxArrayFromImage_uint8 to answer your question, and you don't have that. However, it looks like it is a simple nD transpose and reordering operation, so it wouldn't be too difficult to write your own conversion routine if needed.
Hi James,
Thanks for the suggestion.
I tried a manual conversion in c++ and the memory usage is stable so far. However, the speed is about 30 times slower. Is there any suggestion to efficiently convert the image?
Currently I assign the matrix element by element within 3 for-loop. Program will crash using MxArray of opencvmex, another library interfacing OpenCV and Matlab.
hmm... I tried another way to do the conversion. I first transpose the cv::Mat, split into 3 channels and then copy data into mxArray. This has similar speed as ocvMxArrayFromImage_uint8 and has no memory problem. Though the first time executing this function is very slow and I don't know why.
I can't offer any advice unless I see your code.
mxArray * ConvertMat(const cv::Mat & image)
{
cv::Mat imageT = image.t();
std::vector<cv::Mat> splitChannel;
cv::split(imageT, splitChannel);
size_t rows = image.rows;
size_t cols = image.cols;
size_t channels = image.channels();
mxArray *pMXA = NULL;
UINT8 *input = NULL;
{
const int dimensionNumber = 3;
mwSize dimension[dimensionNumber] = { rows, cols, channels };
pMXA = mxCreateNumericArray(dimensionNumber, dimension, mxUINT8_CLASS, mxREAL);
input = (UINT8 *)mxGetData(pMXA);
size_t step = rows * cols;
for(int channelIndex = 0; channelIndex < channels; channelIndex++)
{
memcpy(input + step * channelIndex, splitChannel[channels - channelIndex - 1].data, step);
}
}//3 channels
return pMXA;
}
In general case, yes. Both this function and ocvMxArrayFromImage_uint8 take about 0.001 sec converting 640x480 image. This function does not increase memory usage after destroy the mxArray. It takes ~0.25 sec the first time executed but this is not a big problem.

Sign in to comment.

Answers (0)

Products

Asked:

on 28 Mar 2018

Commented:

on 29 Mar 2018

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!