X-Git-Url: http://git.maemo.org/git/?p=opencv;a=blobdiff_plain;f=interfaces%2Fswig%2Foctave%2Fadapters.i;fp=interfaces%2Fswig%2Foctave%2Fadapters.i;h=b3d1c5f841578a852a4effe50572a1928cc8b043;hp=0000000000000000000000000000000000000000;hb=e4c14cdbdf2fe805e79cd96ded236f57e7b89060;hpb=454138ff8a20f6edb9b65a910101403d8b520643 diff --git a/interfaces/swig/octave/adapters.i b/interfaces/swig/octave/adapters.i new file mode 100644 index 0000000..b3d1c5f --- /dev/null +++ b/interfaces/swig/octave/adapters.i @@ -0,0 +1,452 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// Intel License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000, Intel Corporation, all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of Intel Corporation may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +// 2008-04-07, Xavier Delacour + + +// The trouble here is that Octave arrays are in Fortran order, while OpenCV +// arrays are in C order. Neither Octave nor OpenCV seem to provide n-dim +// transpose, so we do that here. + +// For images, we also scale the result to lie within [0-1]. + + +// * add support for sparse matrices + +// * add support for complex matrices + +// * add support for roi and coi, or complain if either is set + +// * test case for channel==1 +// * test case for channel=={2,3,4} +// * test case for 2 dim, 1 dim, n dim cases + +%{ + +class ndim_iterator { + int nd; + int dims[CV_MAX_DIM]; + int step[CV_MAX_DIM]; + int curr[CV_MAX_DIM]; + uchar* _data; + int _type; + bool done; + public: + ndim_iterator() {} + ndim_iterator(CvMat* m) { + int c = CV_MAT_CN(m->type); + int elem_size = CV_ELEM_SIZE1(m->type); + nd = c == 1 ? 2 : 3; + dims[0] = m->rows; + dims[1] = m->cols; + dims[2] = c; + step[0] = m->step; + step[1] = c * elem_size; + step[2] = elem_size; + curr[0] = curr[1] = curr[2] = 0; + _data = m->data.ptr; + _type = m->type; + done = false; + } + ndim_iterator(CvMatND* m) { + int c = CV_MAT_CN(m->type); + int elem_size = CV_ELEM_SIZE1(m->type); + nd = m->dims + (c == 1 ? 0 : 1); + for (int j = 0; j < m->dims; ++j) { + dims[j] = m->dim[j].size; + step[j] = m->dim[j].step; + curr[j] = 0; + } + if (c > 1) { + dims[m->dims] = c; + step[m->dims] = elem_size; + curr[m->dims] = 0; + } + _data = m->data.ptr; + _type = m->type; + done = false; + } + ndim_iterator(IplImage* img) { + nd = img->nChannels == 1 ? 2 : 3; + dims[0] = img->height; + dims[1] = img->width; + dims[2] = img->nChannels; + + switch (img->depth) { + case IPL_DEPTH_8U: _type = CV_8U; break; + case IPL_DEPTH_8S: _type = CV_8S; break; + case IPL_DEPTH_16U: _type = CV_16U; break; + case IPL_DEPTH_16S: _type = CV_16S; break; + case IPL_DEPTH_32S: _type = CV_32S; break; + case IPL_DEPTH_32F: _type = CV_32F; break; + case IPL_DEPTH_1U: _type = CV_64F; break; + default: + error("unsupported image depth"); + return; + } + + int elem_size = CV_ELEM_SIZE1(_type); + step[0] = img->widthStep; + step[1] = img->nChannels * elem_size; + step[2] = elem_size; + curr[0] = curr[1] = curr[2] = 0; + _data = (uchar*)img->imageData; + done = false; + } + ndim_iterator(NDArray& nda) { + dim_vector d(nda.dims()); + nd = d.length(); + int last_step = sizeof(double); + for (int j = 0; j < d.length(); ++j) { + dims[j] = d(j); + step[j] = last_step; + last_step *= dims[j]; + curr[j] = 0; + } + _data = (uchar*)const_cast(nda.data()); + _type = CV_64F; + done = false; + } + + operator bool () const { + return !done; + } + uchar* data() { + return _data; + } + int type() const { + return _type; + } + ndim_iterator& operator++ () { + int curr_dim = 0; + for (;;) { + _data += step[curr_dim]; + if (++curr[curr_dim] < dims[curr_dim]) + break; + curr[curr_dim] = 0; + _data -= step[curr_dim] * dims[curr_dim]; + ++curr_dim; + if (curr_dim == nd) { + done = true; + break; + } + } + return *this; + } +}; + +template + void transpose_copy_typed(ndim_iterator src_it, ndim_iterator dst_it, + double scale) { + assert(sizeof(T1) == CV_ELEM_SIZE1(src_it.type())); + assert(sizeof(T2) == CV_ELEM_SIZE1(dst_it.type())); + if (scale == 1) { + while (src_it) { + *(T2*)dst_it.data() = (T2)*(T1*)src_it.data(); + ++src_it; + ++dst_it; + } + } else { + while (src_it) { + *(T2*)dst_it.data() = (T2)(scale * (*(T1*)src_it.data())); + ++src_it; + ++dst_it; + } + } +} + +template +void transpose_copy2(ndim_iterator src_it, ndim_iterator dst_it, + double scale) { + switch (CV_MAT_DEPTH(dst_it.type())) { + case CV_8U: transpose_copy_typed(src_it,dst_it,scale); break; + case CV_8S: transpose_copy_typed(src_it,dst_it,scale); break; + case CV_16U: transpose_copy_typed(src_it,dst_it,scale); break; + case CV_16S: transpose_copy_typed(src_it,dst_it,scale); break; + case CV_32S: transpose_copy_typed(src_it,dst_it,scale); break; + case CV_32F: transpose_copy_typed(src_it,dst_it,scale); break; + case CV_64F: transpose_copy_typed(src_it,dst_it,scale); break; + default: + error("unsupported dest array type (supported types are CV_8U, CV_8S, " + "CV_16U, CV_16S, CV_32S, CV_32F, CV_64F)"); + } +} + +void transpose_copy(ndim_iterator src_it, ndim_iterator dst_it, + double scale = 1) { + switch (CV_MAT_DEPTH(src_it.type())) { + case CV_8U: transpose_copy2(src_it,dst_it,scale); break; + case CV_8S: transpose_copy2(src_it,dst_it,scale); break; + case CV_16U: transpose_copy2(src_it,dst_it,scale); break; + case CV_16S: transpose_copy2(src_it,dst_it,scale); break; + case CV_32S: transpose_copy2(src_it,dst_it,scale); break; + case CV_32F: transpose_copy2(src_it,dst_it,scale); break; + case CV_64F: transpose_copy2(src_it,dst_it,scale); break; + default: + error("unsupported source array type (supported types are CV_8U, CV_8S, " + "CV_16U, CV_16S, CV_32S, CV_32F, CV_64F)"); + } +} + +octave_value cv2mat(CvArr* arr) { + dim_vector d; + NDArray nda; + + if (CV_IS_MAT(arr)) { + // m x n x c + CvMat* m = (CvMat*)arr; + + int c = CV_MAT_CN(m->type); + if (c == 1) { + d.resize(2); + d(0) = m->rows; + d(1) = m->cols; + } else { + d.resize(3); + d(0) = m->rows; + d(1) = m->cols; + d(2) = c; + } + + nda = NDArray(d); + transpose_copy(m, nda); + } + else if (CV_IS_MATND(arr)) { + // m1 x m2 x ... x mn x c + CvMatND* m = (CvMatND*)arr; + + int c = CV_MAT_CN(m->type); + if (c == 1) { + d.resize(m->dims); + for (int j = 0; j < m->dims; ++j) + d(j) = m->dim[j].size; + } else { + d.resize(m->dims + 1); + for (int j = 0; j < m->dims; ++j) + d(j) = m->dim[j].size; + d(m->dims) = c; + } + + nda = NDArray(d); + transpose_copy(m, nda); + } + else if (CV_IS_IMAGE(arr)) { + // m x n x c + IplImage* img = (IplImage*)arr; + + if (img->nChannels == 1) { + d.resize(2); + d(0) = img->height; + d(1) = img->width; + } else { + d.resize(3); + d(0) = img->height; + d(1) = img->width; + d(2) = img->nChannels; + } + + nda = NDArray(d); + transpose_copy(img, nda); + } + else { + error("unsupported array type (supported types are CvMat, CvMatND, IplImage)"); + return octave_value(); + } + + return nda; +} + +octave_value mat2cv(const octave_value& ov, int type) { + NDArray nda(ov.array_value()); + if (error_state) + return 0; + + dim_vector d = ov.dims(); + assert(d.length() > 0); + + int nd = d.length(); + int last_dim = d(d.length() - 1); + int c = CV_MAT_CN(type); + if (c != 1 && c != last_dim) { + error("last dimension and channel must agree, or channel must equal one"); + return 0; + } + if (c > 1) + --nd; + + if (nd == 2) { + CvMat *m = cvCreateMat(d(0), d(1), type); + transpose_copy(nda, m); + return SWIG_NewPointerObj(m, SWIGTYPE_p_CvMat, SWIG_POINTER_OWN); + } + else { + int tmp[CV_MAX_DIM]; + for (int j = 0; j < nd; ++j) + tmp[j] = d(j); + CvMatND *m = cvCreateMatND(nd, tmp, type); + transpose_copy(nda, m); + return SWIG_NewPointerObj(m, SWIGTYPE_p_CvMatND, SWIG_POINTER_OWN); + } +} + +octave_value cv2im(CvArr* arr) { + if (!CV_IS_IMAGE(arr) && !CV_IS_MAT(arr)) { + error("input is not an OpenCV image or 2D matrix"); + return octave_value(); + } + + dim_vector d; + NDArray nda; + + if (CV_IS_MAT(arr)) { + // m x n x c + CvMat* m = (CvMat*)arr; + + int c = CV_MAT_CN(m->type); + if (c == 1) { + d.resize(2); + d(0) = m->rows; + d(1) = m->cols; + } else { + d.resize(3); + d(0) = m->rows; + d(1) = m->cols; + d(2) = c; + } + + nda = NDArray(d); + transpose_copy(m, nda, 1/256.0); + } + else if (CV_IS_IMAGE(arr)) { + // m x n x c + IplImage* img = (IplImage*)arr; + + if (img->nChannels == 1) { + d.resize(2); + d(0) = img->height; + d(1) = img->width; + } else { + d.resize(3); + d(0) = img->height; + d(1) = img->width; + d(2) = img->nChannels; + } + + nda = NDArray(d); + transpose_copy(img, nda, 1/256.0); + } + + return nda; +} + +CvMat* im2cv(const octave_value& ov, int depth) { + NDArray nda(ov.array_value()); + if (error_state) + return 0; + + dim_vector d = ov.dims(); + assert(d.length() > 0); + + if (d.length() != 2 && d.length() != 3 && + !(d.length() == 3 && d(2) <= 4)) { + error("input must be m x n or m x n x c matrix, where 1<=c<=4"); + return 0; + } + + int channels = d.length() == 2 ? 1 : d(2); + int type = CV_MAKETYPE(depth, channels); + + CvMat *m = cvCreateMat(d(0), d(1), type); + transpose_copy(nda, m, 256); + + return m; +} + +%} + +%newobject im2cv; + +%feature("autodoc", 0) cv2mat; +%feature("autodoc", 0) mat2cv; +%feature("autodoc", 0) cv2im; +%feature("autodoc", 0) im2cv; + +%docstring cv2mat { +@deftypefn {Loadable Function} @var{m1} = cv2mat (@var{m2}) +Convert the CvMat, CvMatND, or IplImage @var{m2} into an Octave real matrix @var{m1}. +The dimensions @var{m1} are those of @var{m2}, plus an addition dimension +if @var{m2} has more than one channel. +@end deftypefn +} + +%docstring mat2cv { +@deftypefn {Loadable Function} @var{m1} = mat2cv (@var{m2}, @var{type}) +Convert the Octave array @var{m2} into either a CvMat or a CvMatND of type +@var{type}. +@var{type} is one of CV_8UC(n), CV_8SC(n), CV_16UC(n), CV_16SC(n), CV_32SC(n), +CV_32FC(n), CV_64FC(n), where n indicates channel and is between 1 and 4. +If the dimension of @var{m2} is equal to 2 (not counting channels), +a CvMat is returned. Otherwise, a CvMatND is returned. +@end deftypefn +} + +%docstring cv2im { +@deftypefn {Loadable Function} @var{im} = cv2im (@var{I}) +Convert the OpenCV image or 2D matrix @var{I} into an Octave image @var{im}. +@var{im} is a real matrix of dimension height x width or +height x width x channels, with values within the interval [0,1]). +@end deftypefn +} + +%docstring im2cv { +@deftypefn {Loadable Function} @var{I} = im2cv (@var{im}, @var{depth}) +Convert the Octave image @var{im} into the OpenCV image @var{I} of depth +@var{depth}. +@var{im} is a real matrix of dimension height x width or +height x width x channels, with values within the interval [0,1]. +@var{depth} must be one of CV_8U, CV_8S, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F. +@end deftypefn +} + +octave_value cv2mat(CvArr* arr); +octave_value mat2cv(const octave_value& ov, int type); +octave_value cv2im(CvArr* arr); +CvMat* im2cv(const octave_value& ov, int depth);