How to pass an image to a 2D array using Matlab MEX?

조회 수: 1 (최근 30일)
Aaronne
Aaronne 2014년 2월 13일
답변: Aaronne 2014년 2월 15일
I want to read some image to run a C++ MEX function to process this image. The image is originally stored as a Matlab 3D matrix, and then converted to a 2D matrix and each slice of the image is stored as a 1D vector. Here is some example codes below.
The MEX function:
include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
unsigned int** ubuff;
size_t col_ubuff = mxGetN(prhs[0]);
size_t row_ubuff = mxGetM(prhs[0]);
ubuff = (unsigned int **)mxCalloc(col_ubuff, row_ubuff);
for(int x = 0; x < col_ubuff; x++) {
ubuff[x] = (unsigned int *) mxCalloc(row_ubuff, sizeof(unsigned int));
}
for (int col=0; col < col_ubuff; col++) {
for (int row=0; row < row_ubuff; row++) {
ubuff[col][row] = mxGetPr(prhs[0])[row+col*row_ubuff];
}
}
unsigned int the_pixel_i_want = ubuff[16][2*32 + 2];
printf ("Debug: %d\n\n", the_pixel_i_want);
return;
}
2. The program can be compiled; however, the results of running the program is strange; for example, I have some test codes and test image with all pixels to be 188,
%%Test input image as 2D array clc; clf; clear all; close all;
volImage = 188.*ones(32,32,32);
volImageVec = reshape(volImage, 32*32, 32)';
volImageVec = uint32(volImageVec);
TestInputImage(volImageVec');
But the output sometimes be 188 and sometimes be 0. Is there a memory leak somewhere in my code? Thanks very much for your help.

채택된 답변

Aaronne
Aaronne 2014년 2월 13일
Thanks for editing. I found a way from other people. Just put it here for other people's interest.
1) The line
ubuff = (unsigned int **)mxCalloc(col_ubuff, row_ubuff);
should be
ubuff = (unsigned int **)mxCalloc(col_ubuff, sizeof(unsigned int *));
2) The line
ubuff[col][row] = mxGetPr(prhs[0])[row+col*row_ubuff];
should be
ubuff[col][row] = ((unsigned int *)mxGetData(prhs[0]))[row+col*row_ubuff];
  댓글 수: 5
James Tursa
James Tursa 2014년 2월 14일
Regarding the "free" question, yes you are correct that it will be garbage collected. But I think it is good programming practice to do it manually. To that end, what you are doing is inadequate ... you are only freeing the row pointers, not the rows themselves. To free everything you would need to do this (one mxFree for each mxCalloc):
for(int x = 0; x < col_ubuff; x++) {
mxFree(ubuff[x]);
}
mxFree(ubuff);
As to why you are getting 0's using the code I suggested, I would need to see exactly how you implemented it.
Aaronne
Aaronne 2014년 2월 15일
I got a follow up question about Matlab mex function input/output 2D array format. For example, I have a variable '`outputBuff`' defined as C++ 2D integer array. After processing it, I want to output it as a 'plhs' (parameter at left hand side). Not sure how to do this.
int** outputBuff;
size_t col_outputBuff = mxGetN(prhs[4]);
size_t row_outputBuff = mxGetM(prhs[4]);
// Allocate the memory for 2D array
outputBuff = (int **)mxCalloc(col_outputBuff, sizeof(int*));
for(int x = 0; x < col_outputBuff; x++) {
outputBuff[x] = (int *) mxCalloc(row_outputBuff, sizeof(int));
}
// Read in the data
for (int col=0; col < col_outputBuff; col++) {
for (int row=0; row < row_outputBuff; row++) {
outputBuff[col][row] = ((int *)mxGetPr(prhs[4]))[row+col*row_outputBuff];
}
}
Then output it as `plhs`
const mwSize dims[] = {col_outputBuff, row_outputBuff}; plhs[0] = mxCreateNumericArray(2, dims, mxINT32_CLASS, mxREAL);
mxArray *outputMatrix;
outputMatrix = mxCreateNumericMatrix(col_outputBuff, row_outputBuff, mxINT32_CLASS, mxREAL);
outputBuff[0] = (int *)mxGetPr(outputMatrix);
outputMatrix = (mxArray *)mxGetData(plhs[0]);
The codes can be compiled but output all zeros not as expected. Could you give me some hints? Thanks a lot.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Aaronne
Aaronne 2014년 2월 15일
I got the answer with the help from someone. I put it here for others' reference.
// Output the results
plhs[0] = mxCreateNumericMatrix(col_outputBuff, row_outputBuff, mxINT32_CLASS, mxREAL);
int* outputMatrix = (int *)mxGetData(plhs[0]);
// Read in the data
for (int col=0; col < col_outputBuff; col++) {
for (int row=0; row < row_outputBuff; row++) {
outputMatrix[row + col*row_outputBuff] = outputBuff[col][row];
}
}

카테고리

Help CenterFile Exchange에서 Write C Functions Callable from MATLAB (MEX Files)에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by