将数据从cv :: Mat转换为mxArray
我想使用C++代码中的“engine.h”将矩阵发送到Matlab。事实是,我有一个cv :: Mat中的数据,我需要发送一个mxArray。我试图用这个表达,但它doesn't工作:将数据从cv :: Mat转换为mxArray
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));
任何人都知道正确的方式做转换?任何帮助都会有所帮助。谢谢。
编辑
This thread显示了如何转换CvMat
到mxArray
。尽管它不完全是您正在寻找的转换代码,但它非常接近。
这是一个简单的转换,您应该能够调整代码以使用cv::Mat
而不是CvMat
。如果不能,快速黑客对你的cv::Mat
数据转换为CvMat
然后用下面的代码为是(从我所建议的链接所):
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;
}
我发现了一个更简单的方法来做到这一点皈依经过一番努力。我要做的就是创建这样的功能:
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);
}
有一个在 http://github.com/kyamagu/mexopencv 包中包含一个C++是Matlab的原始数据类型(mxArray)之间转换类(称为MxArray)哥打山口开发的库OpenCV数据类型。该库直接支持OpenCV的C++ API(Open CV版本2.0及更高版本),因此不需要进行额外的转换(例如,从cvMat到cv :: Mat或从IplImage到cv :: Mat)。示例用法:
#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
}
就是这样。确保一起编译你的mex函数和 MxArray.cpp文件;你可以在MATLAB命令行中这样做:
mex yourmexfile.cpp MxArray.cpp
源代码对我来说已经足够了,我只想做出自己的功能。非常感谢,非常有用.. – 2012-06-05 10:23:17
@Jav_Rock很高兴听到! MxArray.cpp对我也很有帮助。考虑对这个答案进行投票,让其他人可以看到这个解决方案。 – Alexey 2012-06-05 20:48:48
是的,我已经做到了! – 2012-06-05 22:38:33
谢谢。所以在openCV中使用engine.h总是很麻烦,不是吗?我期待更直接的东西,但如果没有更简单的解决方案,我会尝试这一个。 – 2012-01-12 12:31:58
一个问题。你是否考虑opencv按列存储数据行和matlab? – 2012-01-12 12:36:35
我必须坚持你打开我建议的线程,并看看那里提供的** complete **源代码。根据其他用户,该代码有效。但如果没有,至少是你的开始。 – karlphillip 2012-01-12 15:37:16