/** * Convert cv::MatND to MxArray * @param mat cv::MatND object * @param classid classid of mxArray. e.g., mxDOUBLE_CLASS. When mxUNKNOWN_CLASS * is specified, classid will be automatically determined from * the type of cv::Mat. default: mxUNKNOWN_CLASS * @return MxArray object */ MxArray::MxArray(const cv::MatND& mat, mxClassID classid) { if (mat.datastart==mat.dataend) { p_ = mxCreateNumericArray(0,0,mxDOUBLE_CLASS,mxREAL); return; } // Create a new mxArray int nchannels = mat.channels(); const int* dims_ = mat.size; vector<mwSize> d(dims_,dims_+mat.dims); d.push_back(nchannels); classid = (classid == mxUNKNOWN_CLASS) ? ClassIDOf[mat.depth()] : classid; std::swap(d[0],d[1]); p_ = mxCreateNumericArray(d.size(),&d[0],classid,mxREAL); if (!p_) mexErrMsgIdAndTxt("mexopencv:error","Allocation error"); // Copy int depth = CV_MAKETYPE(DepthOf[classid],1); cv::MatND m(mat.dims,mat.size,CV_MAKETYPE(depth,1)); uchar* _data = m.data; uchar* _datastart = m.datastart; uchar* _dataend = m.dataend; m.data = m.datastart = reinterpret_cast<uchar*>(mxGetData(p_)); m.dataend = reinterpret_cast<uchar*>( reinterpret_cast<size_t>(mxGetData(p_))+mxGetElementSize(p_)*numel()); mat.convertTo(m,CV_MAKETYPE(depth,1)); m.data = _data; m.datastart = _datastart; m.dataend = _dataend; }
// We don't know if MatND uses the little-endian dimension order (i.e. dim=0: lowest dimension, dim=nd-1: highest dimension) or the big-endian order. Therefore we will detect the order from the instance. // Note: http://code.google.com/p/pyopencv/issues/detail?id=18 bool get_array_data_arrangement(cv::MatND const &inst, sdcpp::array_data_arrangement &result) { if(!inst.flags) return false; bool endianness = (inst.dims >= 2) && (inst.step[0] > inst.step[1]); bool multichannel = inst.channels() > 1; int i; result.item_size = inst.elemSize1(); result.ndim = inst.dims + multichannel; result.size.resize(result.ndim); result.stride.resize(result.ndim); if(multichannel) { result.size[inst.dims] = inst.channels(); result.stride[inst.dims] = inst.elemSize1(); } if(endianness) { result.total_size = inst.size[0]*inst.step[0]; for(i = 0; i < inst.dims; ++i) { result.size[i] = inst.size[i]; result.stride[i] = inst.step[i]; } } else { result.total_size = inst.size[inst.dims-1]*inst.step[inst.dims-1]; for(i = 0; i < inst.dims; ++i) { result.size[i] = inst.size[inst.dims-1-i]; result.stride[i] = inst.step[inst.dims-1-i]; } } return true; }