Dynamic Multi-dimensional array in MEX

Hey! I am working on reading back images taken from external hardware. The idea is for this particular MEX function to take in N number of images, and return to MATLAB an array of size (imageWidth, imageHeight, N).
In the beginning of the code I pre-allocate the multidimensional array. Then within a for-loop I allocate memory for next image, acquire image, copy data into output matrix, and free the memory allocated.
Everything actually works just fine! Except, I am blanking on how I can instantiate the multidimensional array using the number N given as an argument.
Removing camera related stuff, it boils down to something like this:
size_t N = (size_t)mxGetScalar(prhs[1]);
int64_t width, height, offx, offy;
// Get the dimensions of images that will be returned
err = acNodeMapGetIntegerValue(hNodeMap, "Width", &width) |
acNodeMapGetIntegerValue(hNodeMap, "Height", &height) |
acNodeMapGetIntegerValue(hNodeMap, "OffsetX", &offx) |
acNodeMapGetIntegerValue(hNodeMap, "OffsetY", &offy);
// Create Array for Storing image data
mwSize dims[3];
dims[0] = width;
dims[1] = height;
dims[2] = N;
plhs[1] = mxCreateNumericArray(3, dims, mxUINT16_CLASS, mxREAL);
uint16_t (*imagesOut)[N] = (uint16_t (*)[N]) mxGetPr(plhs[1]); // N isnt a const, so this Doesnt work :(
// Wait for Image Trigger
for (int i = 0; i < N; i++){
// tons of code would go here to wait for trigger,
// acquire image and get the dimensions of buffer and bits per pixel
// Allocate Memory Dynamically for image recieved
size_t dstDataSize = width * height * dstBitsPerPixel / 8;
uint8_t* image = (uint8_t*)malloc(dstDataSize);
memset(image, 0, dstDataSize);
uint64_t imageSize = imageWidth * imageHeight;
printf(" - Image Acquired [%d, %d]\n", imageWidth, imageHeight);
for (int j=0; j < imageSize; j++)
imagesOut[i][j] = ((((uint16_t) image[j*2]))>> 4) + (((uint16_t)image[j*2 + 1])<<4); // bit twiddling and copying data over
// More code snipped, but clean up hardware resources here
free(image);
}
If instead I have N be #define'd the code works fine. I saw people elsewhere using mxSetPr instead of what I've done to with (uint16_t (*)[N]) mxGetPr(plhs[1])?
Edit: Sorry the indentation looks weird on that inner forloop. This was heavily trimmed to try and highlight my issue but the source formatting isn't a problem.

4 Comments

Some questions first about the image aquisition process and sizes. I don't yet see the connections. It appears you
create an mxArray up front that is dimensions (width,height,N)
for loop N iterations
acquire an image
allocate image pointer to hold width * height * dstBitsPerPixel / 8 bytes
set this allocated memory to 0
use variable imageWidth, imageHeight, and imageSize to copy from image to mxArray
endloop
The following points are unclear to me:
Looks like you are trying to create imagesOut as a pointer to an array of N uint16_t. I normally would have expected you to be creating imagesOut as a pointer to an array of width X height uint16_t, or something like that. Then in your loop you would be filling in each width X height page with an acquired image. But I don't see that, so I am confused as to what you are intending for this pointer.
How are imageWidth, imageHeight, and imageSize related to width, height, and N?
Can imageWidth, imageHeight, and imageSize change values within the loop?
How is the acquired image getting into the memory behind the image pointer?
What values can dstBitsPerPixel take? 1 or 2 or 4 or 8? I.e., will an integer number of pixels always fit in a single byte?
You have hardcoded 4 bit shifting of adjacent image bytes. How is this related to dstBitsPerPixel? And why do you need to combine 4 bits from two different bytes of image?
I can probably figure out how to get a pointer definition that works for you, but not until I understand how you intend to fill the pages of the mxArray first, and not until I know how all of these sizes are related to each other. Maybe you can describe briefly how the image data is packed within the bytes of the acquired image.
Thanks for the reply!
The image data is returned from camera as a uint8_t* but I need to do some per-pixel unpacking (every 12bits of image* contains 8bits of pixel data).
imageWidth = width and imageHeight = height. and N is the number of images total.
dstBitsPerPixel can be either 12 or 16.
Does this help?
*Edit: The image width and height probably isnt going to change during the loop. At least it shouldnt!
And the image* is getting data from methods I've omitted here to try and make this a shorter question, but it's filled using the API provided by vendor.
Can dstBitsPerPixel change within the loop? Do you first copy the camera memory into the memory behind the image pointer, and then copy that (with bit shifting etc) into the mxArray? Is that what is going on?
dstBitsPerPixel shouldnt change, though it might be one of two different values.
Yes the camera memory is first copied into the memory behind image pointer (not shown here). And then I am copying into the array to return to MATLAB.

Sign in to comment.

Answers (0)

Categories

Find more on Images in Help Center and File Exchange

Asked:

on 26 Feb 2021

Commented:

on 26 Feb 2021

Community Treasure Hunt

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

Start Hunting!