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
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
|