简体   繁体   中英

outputting image back to matlab Mex

I am trying to output an image from my mex file back to my matlab file, but when i open it in matlab it is not correct.

The output image withing the mex file is correct

I have tried switching the orientation of the mwSize as well as swapping i and j in new_img.at<int>(j, i) ;

Mat image = imread(mxArrayToString(prhs[0]));
Mat new_img(H,W, image.type(), Scalar(0));
// some operations on new_img
imshow( "gmm image", image ); //shows the original image
imshow( "gmm1 image", new_img ); //shows the output image
waitKey( 200 );  //both images are the same size as desired

mwSize nd = 2;
mwSize dims[] = {W, H};

plhs[0] = mxCreateNumericArray(nd, dims, mxUINT8_CLASS, mxREAL);
if(plhs == NULL) {
  mexErrMsgTxt("Could not create mxArray.\n");     
}     
char* outMat = (char*) mxGetData( plhs[0]);

for (int i= 0; i < H; i++)
{
  for (int j = 0; j < W; j++)
  {       
    outMat[i +j*image.rows] = new_img.at<int>(j, i);       
  }
}

this is in the mat file

gmmMask = GmmMex2(imgName,rect);
imshow(gmmMask); % not the same as the output image. somewhat resembles it, but not correct.

Because you have alluded to this being a colour image , this means that you have three slices of the matrix to consider. Your code only considers one slice. First off you need to make sure that you declare the right size of the image. In MATLAB, the first dimension is always the number of rows while the second dimension is the number of columns. Now you have to add the number of channels too on top of this. I'm assuming this is an RGB image so there are three channels.

Therefore, change your dims to:

mwSize nd = 3;
mwSize dims[] = {H, W, nd};

Changing nd to 3 is important as this will allow you to create a 3D matrix. You only have a 2D matrix. Next, make sure that you are accessing the image pixels at the right location in the cv::Mat object. The way you are accessing the image pixels in the nested pair of for loops assumes a row-major fashion (iterating over the columns first, then the rows). As such, you need to interchange i and j as i accesses the rows and j accesses the columns. You will also need to access the channel of the colour image so you'll need another for loop to compensate. For the grayscale case, you have properly compensated for the column-major memory configuration for the MATLAB MEX matrix though. This is verified because j accesses the columns and you need to skip over by rows amount in order to access the next column. However, to accommodate for a colour image, you must also skip over by image.rows*image.cols to go to the next layer of pixels.

Therefore your for loop should now be:

for (int k = 0; k < nd; k++) {
    for (int i = 0; i < H; i++) { 
        for (int j = 0; j < W; j++) {
            outMat[k*image.rows*image.cols + i + j*image.rows] = new_img.at<uchar>(i, j, k);
        }
    }
}

Take note that the container of pixels is most likely 8-bit unsigned character, and so you must change the template to uchar not int . This may also explain why your program is crashing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM