1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
42 // 2008-04-07, Xavier Delacour <xavier.delacour@gmail.com>
45 // The trouble here is that Octave arrays are in Fortran order, while OpenCV
46 // arrays are in C order. Neither Octave nor OpenCV seem to provide n-dim
47 // transpose, so we do that here.
49 // For images, we also scale the result to lie within [0-1].
52 // * add support for sparse matrices
54 // * add support for complex matrices
56 // * add support for roi and coi, or complain if either is set
58 // * test case for channel==1
59 // * test case for channel=={2,3,4}
60 // * test case for 2 dim, 1 dim, n dim cases
74 ndim_iterator(CvMat* m) {
75 int c = CV_MAT_CN(m->type);
76 int elem_size = CV_ELEM_SIZE1(m->type);
82 step[1] = c * elem_size;
84 curr[0] = curr[1] = curr[2] = 0;
89 ndim_iterator(CvMatND* m) {
90 int c = CV_MAT_CN(m->type);
91 int elem_size = CV_ELEM_SIZE1(m->type);
92 nd = m->dims + (c == 1 ? 0 : 1);
93 for (int j = 0; j < m->dims; ++j) {
94 dims[j] = m->dim[j].size;
95 step[j] = m->dim[j].step;
100 step[m->dims] = elem_size;
107 ndim_iterator(IplImage* img) {
108 nd = img->nChannels == 1 ? 2 : 3;
109 dims[0] = img->height;
110 dims[1] = img->width;
111 dims[2] = img->nChannels;
113 switch (img->depth) {
114 case IPL_DEPTH_8U: _type = CV_8U; break;
115 case IPL_DEPTH_8S: _type = CV_8S; break;
116 case IPL_DEPTH_16U: _type = CV_16U; break;
117 case IPL_DEPTH_16S: _type = CV_16S; break;
118 case IPL_DEPTH_32S: _type = CV_32S; break;
119 case IPL_DEPTH_32F: _type = CV_32F; break;
120 case IPL_DEPTH_1U: _type = CV_64F; break;
122 error("unsupported image depth");
126 int elem_size = CV_ELEM_SIZE1(_type);
127 step[0] = img->widthStep;
128 step[1] = img->nChannels * elem_size;
130 curr[0] = curr[1] = curr[2] = 0;
131 _data = (uchar*)img->imageData;
134 ndim_iterator(NDArray& nda) {
135 dim_vector d(nda.dims());
137 int last_step = sizeof(double);
138 for (int j = 0; j < d.length(); ++j) {
141 last_step *= dims[j];
144 _data = (uchar*)const_cast<double*>(nda.data());
149 operator bool () const {
158 ndim_iterator& operator++ () {
161 _data += step[curr_dim];
162 if (++curr[curr_dim] < dims[curr_dim])
165 _data -= step[curr_dim] * dims[curr_dim];
167 if (curr_dim == nd) {
176 template <class T1, class T2>
177 void transpose_copy_typed(ndim_iterator src_it, ndim_iterator dst_it,
179 assert(sizeof(T1) == CV_ELEM_SIZE1(src_it.type()));
180 assert(sizeof(T2) == CV_ELEM_SIZE1(dst_it.type()));
183 *(T2*)dst_it.data() = (T2)*(T1*)src_it.data();
189 *(T2*)dst_it.data() = (T2)(scale * (*(T1*)src_it.data()));
197 void transpose_copy2(ndim_iterator src_it, ndim_iterator dst_it,
199 switch (CV_MAT_DEPTH(dst_it.type())) {
200 case CV_8U: transpose_copy_typed<T1,unsigned char>(src_it,dst_it,scale); break;
201 case CV_8S: transpose_copy_typed<T1,signed char>(src_it,dst_it,scale); break;
202 case CV_16U: transpose_copy_typed<T1,unsigned short>(src_it,dst_it,scale); break;
203 case CV_16S: transpose_copy_typed<T1,signed short>(src_it,dst_it,scale); break;
204 case CV_32S: transpose_copy_typed<T1,signed int>(src_it,dst_it,scale); break;
205 case CV_32F: transpose_copy_typed<T1,float>(src_it,dst_it,scale); break;
206 case CV_64F: transpose_copy_typed<T1,double>(src_it,dst_it,scale); break;
208 error("unsupported dest array type (supported types are CV_8U, CV_8S, "
209 "CV_16U, CV_16S, CV_32S, CV_32F, CV_64F)");
213 void transpose_copy(ndim_iterator src_it, ndim_iterator dst_it,
215 switch (CV_MAT_DEPTH(src_it.type())) {
216 case CV_8U: transpose_copy2<unsigned char>(src_it,dst_it,scale); break;
217 case CV_8S: transpose_copy2<signed char>(src_it,dst_it,scale); break;
218 case CV_16U: transpose_copy2<unsigned short>(src_it,dst_it,scale); break;
219 case CV_16S: transpose_copy2<signed short>(src_it,dst_it,scale); break;
220 case CV_32S: transpose_copy2<signed int>(src_it,dst_it,scale); break;
221 case CV_32F: transpose_copy2<float>(src_it,dst_it,scale); break;
222 case CV_64F: transpose_copy2<double>(src_it,dst_it,scale); break;
224 error("unsupported source array type (supported types are CV_8U, CV_8S, "
225 "CV_16U, CV_16S, CV_32S, CV_32F, CV_64F)");
229 octave_value cv2mat(CvArr* arr) {
233 if (CV_IS_MAT(arr)) {
235 CvMat* m = (CvMat*)arr;
237 int c = CV_MAT_CN(m->type);
250 transpose_copy(m, nda);
252 else if (CV_IS_MATND(arr)) {
253 // m1 x m2 x ... x mn x c
254 CvMatND* m = (CvMatND*)arr;
256 int c = CV_MAT_CN(m->type);
259 for (int j = 0; j < m->dims; ++j)
260 d(j) = m->dim[j].size;
262 d.resize(m->dims + 1);
263 for (int j = 0; j < m->dims; ++j)
264 d(j) = m->dim[j].size;
269 transpose_copy(m, nda);
271 else if (CV_IS_IMAGE(arr)) {
273 IplImage* img = (IplImage*)arr;
275 if (img->nChannels == 1) {
283 d(2) = img->nChannels;
287 transpose_copy(img, nda);
290 error("unsupported array type (supported types are CvMat, CvMatND, IplImage)");
291 return octave_value();
297 octave_value mat2cv(const octave_value& ov, int type) {
298 NDArray nda(ov.array_value());
302 dim_vector d = ov.dims();
303 assert(d.length() > 0);
306 int last_dim = d(d.length() - 1);
307 int c = CV_MAT_CN(type);
308 if (c != 1 && c != last_dim) {
309 error("last dimension and channel must agree, or channel must equal one");
316 CvMat *m = cvCreateMat(d(0), d(1), type);
317 transpose_copy(nda, m);
318 return SWIG_NewPointerObj(m, SWIGTYPE_p_CvMat, SWIG_POINTER_OWN);
322 for (int j = 0; j < nd; ++j)
324 CvMatND *m = cvCreateMatND(nd, tmp, type);
325 transpose_copy(nda, m);
326 return SWIG_NewPointerObj(m, SWIGTYPE_p_CvMatND, SWIG_POINTER_OWN);
330 octave_value cv2im(CvArr* arr) {
331 if (!CV_IS_IMAGE(arr) && !CV_IS_MAT(arr)) {
332 error("input is not an OpenCV image or 2D matrix");
333 return octave_value();
339 if (CV_IS_MAT(arr)) {
341 CvMat* m = (CvMat*)arr;
343 int c = CV_MAT_CN(m->type);
356 transpose_copy(m, nda, 1/256.0);
358 else if (CV_IS_IMAGE(arr)) {
360 IplImage* img = (IplImage*)arr;
362 if (img->nChannels == 1) {
370 d(2) = img->nChannels;
374 transpose_copy(img, nda, 1/256.0);
380 CvMat* im2cv(const octave_value& ov, int depth) {
381 NDArray nda(ov.array_value());
385 dim_vector d = ov.dims();
386 assert(d.length() > 0);
388 if (d.length() != 2 && d.length() != 3 &&
389 !(d.length() == 3 && d(2) <= 4)) {
390 error("input must be m x n or m x n x c matrix, where 1<=c<=4");
394 int channels = d.length() == 2 ? 1 : d(2);
395 int type = CV_MAKETYPE(depth, channels);
397 CvMat *m = cvCreateMat(d(0), d(1), type);
398 transpose_copy(nda, m, 256);
407 %feature("autodoc", 0) cv2mat;
408 %feature("autodoc", 0) mat2cv;
409 %feature("autodoc", 0) cv2im;
410 %feature("autodoc", 0) im2cv;
413 @deftypefn {Loadable Function} @var{m1} = cv2mat (@var{m2})
414 Convert the CvMat, CvMatND, or IplImage @var{m2} into an Octave real matrix @var{m1}.
415 The dimensions @var{m1} are those of @var{m2}, plus an addition dimension
416 if @var{m2} has more than one channel.
421 @deftypefn {Loadable Function} @var{m1} = mat2cv (@var{m2}, @var{type})
422 Convert the Octave array @var{m2} into either a CvMat or a CvMatND of type
424 @var{type} is one of CV_8UC(n), CV_8SC(n), CV_16UC(n), CV_16SC(n), CV_32SC(n),
425 CV_32FC(n), CV_64FC(n), where n indicates channel and is between 1 and 4.
426 If the dimension of @var{m2} is equal to 2 (not counting channels),
427 a CvMat is returned. Otherwise, a CvMatND is returned.
432 @deftypefn {Loadable Function} @var{im} = cv2im (@var{I})
433 Convert the OpenCV image or 2D matrix @var{I} into an Octave image @var{im}.
434 @var{im} is a real matrix of dimension height x width or
435 height x width x channels, with values within the interval [0,1]).
440 @deftypefn {Loadable Function} @var{I} = im2cv (@var{im}, @var{depth})
441 Convert the Octave image @var{im} into the OpenCV image @var{I} of depth
443 @var{im} is a real matrix of dimension height x width or
444 height x width x channels, with values within the interval [0,1].
445 @var{depth} must be one of CV_8U, CV_8S, CV_16U, CV_16S, CV_32S, CV_32F, CV_64F.
449 octave_value cv2mat(CvArr* arr);
450 octave_value mat2cv(const octave_value& ov, int type);
451 octave_value cv2im(CvArr* arr);
452 CvMat* im2cv(const octave_value& ov, int depth);