You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

215 lines
6.9 KiB

/** @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 <sonots(at)sonots.com>
*
* 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