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 comentarios

James Tursa
James Tursa el 28 de Mzo. de 2018
Editada: James Tursa el 28 de Mzo. de 2018
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.
Eddie Chiou
Eddie Chiou el 29 de Mzo. de 2018
Editada: Eddie Chiou el 29 de Mzo. de 2018
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;
}
Is channels always either going to be 1 or 3?
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.

Iniciar sesión para comentar.

Respuestas (0)

Productos

Etiquetas

Preguntada:

el 28 de Mzo. de 2018

Comentada:

el 29 de Mzo. de 2018

Community Treasure Hunt

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

Start Hunting!

Translated by