4

This question comes after solving the problem I got in this question. I have a c++ code that processes frames from a camera and generates a matrix for each processed frame. I want to send to matlab engine each matrix, so at the end of the execution I have in stored all the matrices. I am conffused about how to do this, I send a matrix in each iteration but it is overwritting it all the time, so at the end I only have one. Here is a code example:

matrix.cpp

#include helper.h

mxArray *mat;   
mat = mxCreateDoubleMatrix(13, 13, mxREAL);     
memcpy(mxGetPr(mat),matrix.data, 13*13*sizeof(double));
engPutVariable(engine, "mat", mat);

I also tried to use a counter to dinamically name the different matrices, but it didn't work as matlab engine requires the variables to be defined first. Any help will be appreciated. Thanks.

Community
  • 1
  • 1
Jav_Rock
  • 22,059
  • 20
  • 123
  • 164
  • In matlab sure I can, what I don't know is how to define it in c++ using mex functions. I tried to create variables like mat[i] or mat(i), but matlab engine doesn't understand the i as an integer. You can only do engPutVariable for mxArray variables. – Jav_Rock Jan 13 '12 at 08:19

3 Answers3

5

You can create a cell array in matlab workspace like this:

    mwSize size = 10;
    mxArray* cell = mxCreateCellArray(1, &size);

    for(size_t i=0;i<10;i++)
    {
        mxArray *mat;   
        mat = mxCreateDoubleMatrix(13, 13, mxREAL);     
        memcpy(mxGetPr(mat),matrix.data, 13*13*sizeof(double));

        mwIndex subscript = i;
        int index = mxCalcSingleSubscript(cell , 1,&subscript); 
        mxSetCell(m_cell , index, mat);
   }

   engPutVariable(engine, "myCell", cell);
Philipp
  • 11,549
  • 8
  • 66
  • 126
  • 1
    So I would have to store al matrices in the cell array until the program ends, and then send it to matlab engine. I don't know a priori the number of iterations, would ir be necessary? – Jav_Rock Jan 13 '12 at 13:05
  • 1
    1.) In your question you said you *do* want to have all matrices in the engine workspace at the end, so what's wrong with it? 2.) As far as I know, you need to know the Cell size a priori. You might create a cell of a fixed size and start a new one if it's filled. – Philipp Jan 13 '12 at 14:41
  • 1
    another possibility is having engPutVariable(engine, stringConcat("mat",i), mat); (where you would have to build stringConcat by yourself...) – Philipp Jan 13 '12 at 14:41
4

If you don't know the number of frames a priori, don't try to expand the mxArray in C. It is not convenient. You were already close to start. All your problems can be solved with:

engEvalString(engine, "your command here")

Read more here.

The simplest approach is something like:

engPutVariable(engine, "mat", mat);
engEvalString("frames{length(frames)+1} = mat;");

Don't do it exactly that, it is an illustration and will be very slow. Much better to preallocate, say 1000 frames then expand it another 1000 (or a more appropriate number) when needed. Even better is to not use cell arrays which are slow. Instead you could use a 3D array, such as:

frames = zeros(13,13,1000);
frames(:,:,i) = mat;
i = i + 1;

Again, preallocate in blocks. You get the idea. If you really need to be fast, you could build the 3D arrays in C and ship them to MATLAB when they fill.

Jonathan
  • 616
  • 4
  • 7
  • ok, but how do put the variable frames, which is int, into matlab engine that only accepts mxArray. That's the compiling error I get when I try. – Jav_Rock Jan 16 '12 at 09:36
  • Nevermind, I finally managed to do it. It was that the variable frames wasn't initialized. Thanks – Jav_Rock Jan 16 '12 at 13:31
3

Maybe you can use vector<mxArray> from stdlib.

Oli
  • 15,935
  • 7
  • 50
  • 66