http://www.ninadthakoor.com/2012/03/03/matcv/
//Transpose the opencv data to get row major data for matlab
tmp=opencv.t();
opencv mat를 matlab mex 데이터로 변환할때는 .t()로 transpose시켜줘야 한다.
Using OpenCV functions in Matlab
I wrote Converter class few days back to simplify creating MEX files for OpenCV functions. Example of using the class follows in the next post.
Source for matcv.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #ifndef __MATCV__H__ #define __MATCV__H__ #include "mex.h" #include "matrix.h" #include <cstring> #include "opencvcv.h" #include "opencvhighgui.h" #include "boostbimap.hpp" class Converter{ public : Converter(mxArray* src, bool Interleve= true ); Converter(cv::Mat& src); operator cv::Mat(); operator mxArray*(); private : enum {MATLAB_MXARRAY,OPENCV_MAT} _id; bool _interleve; cv::Mat opencv; mxArray* matlab; typedef boost::bimap<mxClassID,unsigned char > bmtype; bmtype _idmap; void _initidmap(); void _matlab2opencv(); void _opencv2matlab(); }; #endif //__MATCV__H__ |
Source for matcv.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | #include "matcv.h" Converter::Converter(mxArray* src, bool Interleve):matlab(src),_id(MATLAB_MXARRAY),_interleve(Interleve){ _initidmap(); } Converter::Converter(cv::Mat& src):opencv(src),_id(OPENCV_MAT){ _initidmap(); } Converter::operator cv::Mat() { if (_id==OPENCV_MAT) return (opencv); _matlab2opencv(); return (opencv); } Converter::operator mxArray*() { if (_id==MATLAB_MXARRAY) return (matlab); _opencv2matlab(); return (matlab); } void Converter::_initidmap() { _idmap.insert(bmtype::value_type(mxINT8_CLASS,CV_8S)); _idmap.insert(bmtype::value_type(mxUINT8_CLASS,CV_8U)); _idmap.insert(bmtype::value_type(mxINT16_CLASS,CV_16S)); _idmap.insert(bmtype::value_type(mxUINT16_CLASS,CV_16U)); _idmap.insert(bmtype::value_type(mxINT32_CLASS,CV_32S)); _idmap.insert(bmtype::value_type(mxSINGLE_CLASS,CV_32F)); _idmap.insert(bmtype::value_type(mxDOUBLE_CLASS,CV_64F)); } void Converter::_opencv2matlab() { //Is the data type supported? bmtype::right_map::const_iterator itr=_idmap.right.find(opencv.depth()); //if not then if (itr==_idmap.right.end()) { mexErrMsgTxt("OpenCV2Matlab:Unsupported data type."); } //Find the matlab data type mxClassID type=itr->second; //We support max 3 dimensions mwSignedIndex dims[3]; dims[0]=opencv.rows; dims[1]=opencv.cols; dims[2]=opencv.channels(); //if number of channels is 1, its a 2D array if (dims[0]>0 && dims[1]>0 && dims[2]==1) { //Create the array to be returned matlab=mxCreateNumericArray(2,dims,type,mxREAL); //Create opencv header for the matlab data cv::Mat tmp=cv::Mat(dims[1],dims[0],CV_MAKETYPE(opencv.depth(),1),mxGetData(matlab),0); //Transpose the opencv data to get row major data for matlab tmp=opencv.t(); const mwSize* size=mxGetDimensions(matlab); mxAssert((opencv.rows==size[0])&(opencv.cols==size[1]),"OpenCV2Matlab:Conversion mismatch"); } else { //Create the array to be returned matlab=mxCreateNumericArray(3,dims,type,mxREAL); //Seperate the channels std::vector<cv::Mat> chans(dims[2]); //cv::split(opencv,&chans[0]); cv::split(opencv,chans); //Create opencv header as a "flat" image for the matlab data cv::Mat tmp=cv::Mat(dims[1]*dims[2],dims[0],CV_MAKETYPE(opencv.depth(),1),mxGetData(matlab),0); for ( int i=0;i<dims[2];i++) { //transpose the opencv channels image to row major matlab data cv::Mat tmp2=chans[i].t(); //Copy the data to the flat matlab data tmp2.copyTo(tmp.rowRange(i*dims[1],(i+1)*dims[1])); } const mwSize* size=mxGetDimensions(matlab); mxAssert((opencv.rows==size[0])&(opencv.cols==size[1])&(opencv.channels()==size[2]),"OpenCV2Matlab:Conversion mismatch"); } } void Converter::_matlab2opencv() { //find the corresponding corresponding opencv data type bmtype::left_map::const_iterator itr=_idmap.left.find(mxGetClassID(matlab)); //No corresponding type? if (itr==_idmap.left.end()| mxIsComplex(matlab) | mxIsSparse(matlab)) { std::string msg="Matlab2OpenCV:Unsupported data type:"+(itr==_idmap.left.end()?std::string(mxGetClassName(matlab)):"") +(mxIsComplex(matlab)?" Complex":"")+(mxIsSparse(matlab)?" Sparse":"."); mexErrMsgTxt(msg.c_str()); } unsigned char type=itr->second; //Get number of dimensions const mwSize dims=mxGetNumberOfDimensions(matlab); //Cannot handle more that 3 dimensions if (dims>3) { std::ostringstream o; o<<"Matlab2OpenCV:Supports upto 3 dimensions. You supplied "<<dims<<"."; mexErrMsgTxt(o.str().c_str()); } //Get actual dimensions const mwSize* size=mxGetDimensions(matlab); //Check if 2 or 3 dimentions if (dims==2) { //Create header for row major matlab data const cv::Mat donotmodify=cv::Mat(size[1],size[0],CV_MAKETYPE(type,1),mxGetData(matlab),0); //Transpose the data so that it is column major for opencv. opencv=donotmodify.t(); mxAssert((opencv.rows==size[0])&(opencv.cols==size[1]),"Matlab2OpenCV:Conversion mismatch"); } else { //Create header for the "flat" matlab data const cv::Mat donotmodify=cv::Mat(size[1]*size[2],size[0],CV_MAKETYPE(type,1),mxGetData(matlab),0); //Transpose the flat data cv::Mat flat=donotmodify.t(); //Create vector of channels to pass to opencv merge operataion std::vector<cv::Mat> chans(size[2]); for ( int i=0;i<size[2];i++) { chans[i]=flat.colRange(i*size[1],(i+1)*size[1]); } cv::merge(chans,opencv); mxAssert((opencv.rows==size[0])&(opencv.cols==size[1])&(opencv.channels()==size[2]),"Matlab2OpenCV:Conversion mismatch"); } } |
'Matlab > mex' 카테고리의 다른 글
Passing Two or More Inputs or Outputs (0) | 2016.09.30 |
---|---|
Way to send OpenCV Mat to MATLAB workspace without copying the data? (0) | 2016.09.29 |
cmake, visual studio로 mex파일 만들때, INSTALL 프로젝트를 빌드해줘야 생성됨 (0) | 2016.09.23 |
generate MEX-files using Visual Studio (0) | 2016.09.22 |
mex "example_mex_function.cpp" compile error (0) | 2016.09.13 |