Converting C++ bits packed int** to MATLAB unisgned char mxArray using mex?
1 visualización (últimos 30 días)
Mostrar comentarios más antiguos
Dejan Dimitrijevic
el 8 de Jun. de 2019
Editada: Dejan Dimitrijevic
el 20 de Jun. de 2019
Hi,
Could someone help as I'm loosing my mind in determining what's wrong here...I have a C++ array of int values (int** pColors - provided from the Kinect SDK mesh->getColors(&pColors) call - but that shouldn't matter IMHO) which are just triplets of byte sized 0-255 (0xFF) rgb color values (that work and can be read/unpacked fine in the C++) that I would like to now read into and use in MATLAB as a mxArray which will be part of a struct that also holds a number of coresponding vertices that have those coresponding rgb colors each (so the number of vertices equals number of colors i.e. numVertices=numColors)...I have tried preety much anything and almost everyting fails and/or brings down MATLAB (no doubt I try to access parts of memory that aren't reserved).
This is what I have used to create a colors mxArray to store the valid C++ data (I can read and unpack it fine in some C++ code):
int colorsIndSize[2]={1,numColors};
colors = mxCreateNumericArray(3, colorsIndSize, mxUINT8_CLASS, mxREAL);
But after that I had to use this to get a C++ pointer for use in my mex code (mxGetPr instead of mxGetUint8s because I can't use '-R2018a' as I inherited a lot of code and adding that gets a lot of errors):
unsigned char* colorsptr = (unsigned char*)mxGetPr(colors);
So now to traverse a real C++ data and store that in the colors mxArray using the corolsptr pointer (by staying in line with the coresponding vertexIndex) I use:
for (unsigned int t = 0, vertexIndex = 0; t < numVertices / 3; ++t, vertexIndex++)mex
{
unsigned int color0 = pColors[vertexIndex];
if(color0>0) mexPrintf("Found one?\n");
colorsptr[t*3] = ((color0 >> 16) & 0xFF);
colorsptr[t*3 + 1] = ((color0 >> 8) & 0xFF);
colorsptr[t*3 + 2] = (color0 & 0xFF);
}
But this just won't give me the result (it just hangs, it seems to start as it writes out something mexPrintf once but I never see it finish now)...I have also tried a number of other values for dimension sizes and I just can't figure out what is the problem...can anyone please help?
Maybe I should focus on debug via Visual Studio but I can't attach to the MATLAB process for now for some reason, even though I tried, or maybe I'm just not understanding the pointer arithmetic right and what mxArray the mxCreateNumericArray creates and how to access it's items by adding and multiplication yet, or is that use of unsigned char instead of uint8 which I think are the same size is doing something bad?
TIA
P.S.
At one point as I used various sizes and traversing options I did get an output from the code in question but it was crazy sized like 3 x numVertices x 129 (which I don't get how would I get 129 if this was supposed to be 8 bit colors)...althought that code variant was traversing 3 colors at the time as does some original code that works on C++, but in this case I'd settle for just getting even a simple 1 x (numVertices*3) or 3 x numVertices which has the colors unpacked from the C++ int** array.
0 comentarios
Respuesta aceptada
James Tursa
el 9 de Jun. de 2019
Editada: James Tursa
el 9 de Jun. de 2019
Some issues:
1) The signature of mxCreateNumericArray according to the doc is:
mxArray *mxCreateNumericArray(mwSize ndim, const mwSize *dims,
mxClassID classid, mxComplexity ComplexFlag);
So why are you using an int for that second argument when it should be mwSize? This may be a 4-byte vs 8-byte integer size mismatch. Could easily be the cause of a crash.
2) This code:
int colorsIndSize[2]={1,numColors};
colors = mxCreateNumericArray(3, colorsIndSize, mxUINT8_CLASS, mxREAL);
The colorsIndSize array has two elements, but on the very next line you tell mxCreateNumericArray that it has three elements. This will cause mxCreateNumericArray to read off the end of the array into invalid memory. This could also easily cause a crash. You probably meant this instead:
mwSize colorsIndSize[2]={3,numColors}; // changed 1 to 3, and int to mwSize
colors = mxCreateNumericArray(2, colorsIndSize, mxUINT8_CLASS, mxREAL); // changed 3 to 2
3) I'm confused. You mention more than once that you have a C++ int** array, but I don't see any such thing in your code. What exactly is the definition of pColors?
4) Is numColors equal to numVertices/3? If it isn't then you have another problem.
3 comentarios
James Tursa
el 10 de Jun. de 2019
Editada: James Tursa
el 10 de Jun. de 2019
Can you post your current code? Typically when I see outlandish array size allocation errors it is because the requested sizes are still not being passed in correctly.
Generic comments on pointers returned by API functions: For mxArrays the mxGetPr( ) function (and friends) always returns a pointer to the first element of the array, regardless of the number of dimensions. You can always use linear indexing with this pointer to access all of the array elements. The elements are always arranged in "column" order ... i.e. the first index varies fastest, etc.
"... I see now in matlab documentation 1's become 2 automagically if the *dims has more than 1 element ..."
So, this information is simply telling you that all mxArrays have a minimimum of two dimensions, and if you only give a mxCreateEtc function one dimension then the function will automatically create two dimensions with the 2nd dimension set to 1. You do not have this situation in the code you have posted.
Más respuestas (2)
Dejan Dimitrijevic
el 10 de Jun. de 2019
Editada: Dejan Dimitrijevic
el 10 de Jun. de 2019
2 comentarios
James Tursa
el 10 de Jun. de 2019
Editada: James Tursa
el 10 de Jun. de 2019
Does the definition of pColors look like this?
int *pColors;
Dejan Dimitrijevic
el 14 de Jun. de 2019
Editada: Dejan Dimitrijevic
el 15 de Jun. de 2019
2 comentarios
Guillaume
el 15 de Jun. de 2019
"or anyone else has any ideas"
When I saw this question is the list of recent questions, it showed that it had 3 answers with an answer by James Tursa accepted. To me that says, no need to look at it, it's already been looked at by at least 3 people and solved by James, who knows what he's talking about. So, I suspect there won't be many anyone else looking at it.
The only reason I looked at it is because it mentions C++, but I don't see any C++, just plain C.
Ver también
Categorías
Más información sobre Kinect For Windows Sensor en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!