/** @file * OpenCV versus Matlab C Library (MEX) interfaces * verified under OpenCV 1.00 and Matlab 2007b * * Matrix conversion */ /* The MIT License * * Copyright (c) 2008, Naotoshi Seo * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #ifndef CVMX_MATCONV_INCLUDED #define CVMX_MATCONV_INCLUDED #include "cv.h" #include "mat.h" #include "matrix.h" #include "cvmxtypeconv.h" /** * Convert IplImage to mxArray. Allocate memory too * * Currently support only uint8, float, double * Currently support only 1 channel (grayscale) and 3 channels (rgb etc) * * @param img * @return mxArray* */ #define cvmxArrayFromIplImage(img) (cvmxArrayFromCvArr(img)) /** * Convert CvMat to mxArray. Allocate memory too * * Currently support only uint8, float, double * Currently support only 1 channel (grayscale) and 3 channels (rgb etc) * * @param mat * @return mxArray* */ #define cvmxArrayFromCvMat(mat) (cvmxArrayFromCvArr(mat)) /** * Convert CvArr to mxArray. Allocate memory too * * Currently support only uint8, float, double * Currently support only 1 channel (grayscale) and 3 channels (rgb etc) * * @param arr * @return mxArray* */ CVAPI(mxArray*) cvmxArrayFromCvArr(const CvArr* arr) { CV_FUNCNAME( "cvmxArraFromCvArr" ); IplImage imghdr, *img = (IplImage*)arr; int nChannel, nRow, nCol, nDim; mwSize dims[3]; mxClassID classid; mxArray* mxarr = NULL; int row, col, ch; __CV_BEGIN__; if (!CV_IS_IMAGE(img)) { CV_CALL(img = cvGetImage(img, &imghdr)); } nChannel = img->nChannels; nRow = img->height; nCol = img->width; nDim = 2; classid = cvmxClassIDFromIplDepth(img->depth); dims[0] = nRow; dims[1] = nCol; dims[2] = nChannel; if (nChannel > 1) nDim = 3; mxarr = mxCreateNumericArray(nDim, dims, classid, mxREAL); if (classid == mxUINT8_CLASS) { unsigned char *mxData = (unsigned char*)mxGetData(mxarr); for (ch = 0; ch < nChannel; ch++) { for (row = 0; row < dims[0]; row++) { for (col = 0; col < dims[1]; col++) { mxData[dims[0] * dims[1] * ch + dims[0] * col + row] = CV_IMAGE_ELEM(img, unsigned char, row, nChannel * col + ch); } } } } else if (classid == mxDOUBLE_CLASS) { double *mxData = (double*)mxGetData(mxarr); for (ch = 0; ch < nChannel; ch++) { for (row = 0; row < dims[0]; row++) { for (col = 0; col < dims[1]; col++) { mxData[dims[0] * dims[1] * ch + dims[0] * col + row] = CV_IMAGE_ELEM(img, double, row, nChannel * col + ch); } } } } else if (classid == mxSINGLE_CLASS) { float *mxData = (float*)mxGetData(mxarr); for (ch = 0; ch < nChannel; ch++) { for (row = 0; row < dims[0]; row++) { for (col = 0; col < dims[1]; col++) { mxData[dims[0] * dims[1] * ch + dims[0] * col + row] = CV_IMAGE_ELEM(img, float, row, nChannel * col + ch); } } } } __CV_END__; return mxarr; } /** * Convert mxArray to IplImage. Allocate memory too * * Currently support only uint8, float, double * Currently support only 1 channel (grayscale) and 3 channels (rgb etc) * * @param mxarr * @return IplImage* */ CVAPI(IplImage*) cvmxArrayToIplImage(const mxArray* mxarr) { CV_FUNCNAME( "cvmxArrayToCvArr" ); IplImage *img = NULL; int depth; mwSize nChannel = 1; mwSize nDim; const mwSize *dims; mxClassID classid; int row, col, ch; __CV_BEGIN__; classid = mxGetClassID(mxarr); nDim = mxGetNumberOfDimensions(mxarr); dims = mxGetDimensions(mxarr); if (nDim >= 3) nChannel = dims[2]; depth = cvmxClassIDToIplDepth(mxGetClassID(mxarr)); img = cvCreateImage(cvSize(dims[1], dims[0]), depth, nChannel); if (classid == mxUINT8_CLASS) { unsigned char *mxData = (unsigned char*)mxGetData(mxarr); for (ch = 0; ch < nChannel; ch++) { for (row = 0; row < dims[0]; row++) { for (col = 0; col < dims[1]; col++) { CV_IMAGE_ELEM(img, unsigned char, row, nChannel * col + ch) = mxData[dims[0] * dims[1] * ch + dims[0] * col + row]; } } } } else if (classid == mxDOUBLE_CLASS) { double *mxData = (double*)mxGetData(mxarr); for (ch = 0; ch < nChannel; ch++) { for (row = 0; row < dims[0]; row++) { for (col = 0; col < dims[1]; col++) { CV_IMAGE_ELEM(img, double, row, nChannel * col + ch) = mxData[dims[0] * dims[1] * ch + dims[0] * col + row]; } } } } else if (classid == mxSINGLE_CLASS) { float *mxData = (float*)mxGetData(mxarr); for (ch = 0; ch < nChannel; ch++) { for (row = 0; row < dims[0]; row++) { for (col = 0; col < dims[1]; col++) { CV_IMAGE_ELEM(img, float, row, nChannel * col + ch) = mxData[dims[0] * dims[1] * ch + dims[0] * col + row]; } } } } __CV_END__; return img; } /** * Convert mxArray to CvMat. Allocate memory too * * Currently support only uint8, float, double * Currently support only 1 channel (grayscale) and 3 channels (rgb etc) * * @param mxarr * @return CvMat* */ CVAPI(CvMat*) cvmxArrayToCvMat(const mxArray* mxarr) { IplImage* img = cvmxArrayToIplImage(mxarr); CvMat *mat = cvCreateMat(img->height, img->width, CV_MAKETYPE(cvmxIplToCvDepth(img->depth), img->nChannels)); cvConvert(img, mat); cvReleaseImage(&img); // @todo: why cvGetMat results in error? //int coi = 0; //IplImage *img = cvmxArrayToIplImage(mxarr); //CvMat *mat, mathdr; //mat = cvGetMat(mat, &mathdr, &coi, 0); return mat; } #endif