Convert data from cv :: Mat to mxArray

I want to send a matrix to Matlab using "engine.h" in C ++ code. The thing is, I have data inside cv :: Mat, and I need to send mxArray. I tried using this expression, but it does not work:

cv::Mat _priorP; _priorP = Mat::eye(13, 13, CV_32FC1); mxArray *mat; mat = mxCreateDoubleMatrix(13, 13, mxREAL); memcpy(mxGetPr(mat),_priorP.data, 13*13*sizeof(double)); 

Does anyone know the right way to do the conversion? Any help would be appreciated. Thanks.

EDIT

I found this way: stack overflow

+7
source share
3 answers

This thread shows how to convert CvMat to mxArray . Although this is not the conversion code you are looking for, it is pretty close.

This is a simple conversion, and you should be able to configure the code to work with cv::Mat instead of CvMat . If you can’t, a quick hack is to convert your cv::Mat data to CvMat , and then use the code below as is (taken from the link I suggested):

 mxArray* CvMat_to_new_mxArr (const CvMat* mat) { const int TYPE = cvGetElemType (mat); // 2-d image if (CV_64FC1 == TYPE) { return helper_2dcvmat_to_mat<CV_64FC1> (mat); } else if (CV_32FC1 == TYPE) { return helper_2dcvmat_to_mat<CV_32FC1> (mat); } else if (CV_32SC1 == TYPE) { return helper_2dcvmat_to_mat<CV_32SC1> (mat); } else if (CV_16SC1 == TYPE) { return helper_2dcvmat_to_mat<CV_16SC1> (mat); } else if (CV_16UC1 == TYPE) { return helper_2dcvmat_to_mat<CV_16UC1> (mat); } else if (CV_8UC1 == TYPE) { return helper_2dcvmat_to_mat<CV_8UC1> (mat); } else if (CV_8SC1 == TYPE) { return helper_2dcvmat_to_mat<CV_8SC1> (mat); } //Multi-dimensional arrays not supported, yet. /* // 3-d image else if (CV_64FC3 == TYPE) { return helper_rgbimage_to_mat<IPL_DEPTH_64F> (img); } else if (CV_32FC3 == TYPE) { return helper_rgbimage_to_mat<IPL_DEPTH_32F> (img); } else if (CV_8UC3 == TYPE) { return helper_rgbimage_to_mat<IPL_DEPTH_8U> (img); } */ // unsupported conversion, return null mxArray return mxCreateDoubleMatrix(0,0,mxREAL); } template<int TYPE> mxArray* helper_2dcvmat_to_mat (const CvMat* mat) { void* pBeg; int pitch; cvGetRawData(mat, (uchar**)&pBeg,&pitch); CvSize size = cvGetSize (mat); const mxClassID cid = cvm_traits<TYPE>::CID; mxArray* pArrOut = mxCreateNumericMatrix(size.height,size.width,cid,mxREAL); void* pBegOut = mxGetData(pArrOut); typedef mc_traits<cid>::CT T; pix_iterator_2d<T,eRowWise> it_src1(static_cast<T*>(pBeg), size.width,size.height,pitch); pix_iterator_2d<T,eRowWise> it_src2(static_cast<T*>(pBeg), size.width,size.height,pitch); it_src2.end (); pix_iterator_2d<T,eColWise> it_dest(static_cast<T*>(pBegOut), size.width,size.height); std::copy (it_src1,it_src2,it_dest); return pArrOut; } 
+4
source

There is a library developed by Kota Yamaguchi at http://github.com/kyamagu/mexopencv. The package contains a C ++ class (called MxArray) that converts the Matlab native (mxArray) data type and OpenCV data types. The library directly supports the C ++ API for OpenCV (Open CV version 2.0 and higher), so there is no need to do additional conversions (for example, from cvMat to cv :: Mat or from IplImage to cv :: Mat). Using an example:

 #include "mexopencv.hpp" // include the library #include "highgui.h" void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { cv::Mat image; image = imread("filename"); // read an image from file plhs[0] = MxArray(image); // convert from cv::Mat to mxArray } 

What is it. Be sure to compile your mex function along with the MxArray.cpp file from the library; you can do this on MATLAB command line:

  mex yourmexfile.cpp MxArray.cpp 
+9
source

I found an easier way to do this conversion after some effort. I create a function like this:

 void arithmetic::cvLoadMatrixToMatlab( Engine *ep, const Mat& m, string name) { int rows=m.rows; int cols=m.cols; //Mat data is float, and mxArray uses double, so we need to convert. mxArray *T=mxCreateDoubleMatrix(cols, rows, mxREAL); double *buffer=(double*)mxGetPr(T); for(int i=0; i<rows; i++){ for(int j=0; j<cols; j++){ buffer[i*(cols)+j]= (double)m.at<float>(i, j); } } //memcpy((char*)mxGetPr(T), (char*)m.data, rows*cols*sizeof(double)); engPutVariable(ep, name.c_str(), T); name=name+"="+name+"'"; // Column major to row major (mat=mat') engEvalString(ep, name.c_str()); mxDestroyArray(T); } 
+3
source

All Articles