示例#1
0
文件: MxArray.cpp 项目: HiDiYANG/gPb
/**
 * 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;
}