7

C++コードで「engine.h」を使用してMatrixをMatlabに送信したいと思います。実際、私は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));

誰かが変換を行う正しい方法を知っていますか?どんな助けでも感謝されるでしょう。ありがとう。

編集

私はこの方法を見つけました: https ://stackoverflow.com/a/8848711/744859

4

3 に答える 3

11

コタヤマグチによって開発されたライブラリが http://github.com/kyamagu/mexopencvにあります 。パッケージには、Matlabのネイティブデータ型(mxArray)とOpenCVデータ型の間で変換するC ++クラス(MxArrayと呼ばれる)が含まれています。ライブラリはOpenCV(Open CVバージョン2.0以降)のC ++ APIを直接サポートしているため、追加の変換(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 
}

それでおしまい。ライブラリのMxArray.cppファイルと一緒にmex関数をコンパイルしてください。これは、MATLABコマンドラインで実行できます。

    mex yourmexfile.cpp MxArray.cpp
于 2012-02-24T13:15:25.470 に答える
4

このスレッドは、をに変換する方法を示してい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;
}
于 2012-01-12T12:11:24.237 に答える
3

少し努力した後、この変換を行うためのより簡単な方法を見つけました。私がしているのは、次のような関数を作成することです。

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);
}
于 2012-01-13T09:57:56.653 に答える