Update the trunk to the OpenCV's CVS (2008-07-14)
[opencv] / interfaces / swig / python / cvarr.i
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
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.
8 //
9 //
10 //                        Intel License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 //   * Redistribution's of source code must retain the above copyright notice,
20 //     this list of conditions and the following disclaimer.
21 //
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.
25 //
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.
28 //
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.
39 //
40 //M*/
41
42 // 2006-02-17  Roman Stanchak <rstancha@cse.wustl.edu>
43 // 2006-07-19  Moved most operators to general/cvarr_operators.i for use with other languages
44
45 /*M//////////////////////////////////////////////////////////////////////////////////////////
46 // Macros for extending CvMat and IplImage -- primarily for operator overloading 
47 //////////////////////////////////////////////////////////////////////////////////////////M*/
48
49 // Macro to define python function of form B = A.f(c)
50 // where A is a CvArr type, c and B are arbitrary types
51 %define %wrap_cvGeneric_CvArr(cname, rettype, pyfunc, argtype, cvfunc, newobjcall)
52 %newobject cname::pyfunc(argtype arg);
53 %extend cname { 
54         rettype pyfunc(argtype arg){
55                 rettype retarg = newobjcall;
56                 cvfunc;
57                 return retarg;
58         }
59 }
60 %enddef
61
62 // Macro to define python function of the form B = A.f(c) 
63 // where A and B are both CvArr of same size and type
64 %define %wrap_cvArr_binaryop(pyfunc, argtype, cvfunc)
65 %wrap_cvGeneric_CvArr(CvMat, CvMat *, pyfunc, argtype, cvfunc, 
66                                           cvCreateMat(self->rows, self->cols, self->type));
67 %wrap_cvGeneric_CvArr(IplImage, IplImage *, pyfunc, argtype, cvfunc,
68                                           cvCreateImage(cvGetSize(self), self->depth, self->nChannels));
69 %enddef
70
71 // Macro to define python function of the form A = A.f(c) 
72 // where f modifies A inplace
73 // use for +=, etc
74 %define %wrap_cvGeneric_InPlace(cname, rettype, pyfunc, argtype, cvfunc)
75 %wrap_cvGeneric_CvArr(cname, rettype, pyfunc, argtype, cvfunc, self);
76 %enddef
77
78 /*M//////////////////////////////////////////////////////////////////////////////////////////
79 // Macros to map operators to specific OpenCV functions
80 //////////////////////////////////////////////////////////////////////////////////////////M*/
81
82 // map any OpenCV function of form cvFunc(src1, src2, dst)
83 %define %wrap_cvArith(pyfunc, cvfunc)
84 %wrap_cvArr_binaryop(pyfunc, CvArr *, cvfunc(self, arg, retarg));
85 %enddef
86
87 // map any OpenCV function of form cvFunc(src1, value, dst)
88 %define %wrap_cvArithS(pyfunc, cvfuncS)
89 %wrap_cvArr_binaryop(pyfunc, CvScalar, cvfuncS(self, arg, retarg));
90 %wrap_cvArr_binaryop(pyfunc, double, cvfuncS(self, cvScalar(arg), retarg));
91 %enddef
92
93 // same as wrap_cvArith
94 %define %wrap_cvLogic(pyfunc, cvfunc)
95 %wrap_cvArr_binaryop(pyfunc, CvArr *, cvfunc(self, arg, retarg))
96 %enddef
97
98 // same as wrap_cvArithS
99 %define %wrap_cvLogicS(pyfunc, cvfuncS)
100 %wrap_cvArr_binaryop(pyfunc, CvScalar, cvfuncS(self, arg, retarg));
101 %wrap_cvArr_binaryop(pyfunc, double, cvfuncS(self, cvScalar(arg), retarg));
102 %enddef
103
104 // Macro to map logical operations to cvCmp
105 %define %wrap_cvCmp(pyfunc, cmp_op)
106 %wrap_cvGeneric_CvArr(CvMat, CvMat *, pyfunc, CvMat *, 
107                       cvCmp(self, arg, retarg, cmp_op), 
108                                           cvCreateMat(self->rows, self->cols, CV_8U));
109 %wrap_cvGeneric_CvArr(IplImage, IplImage *, pyfunc, IplImage *, 
110                       cvCmp(self, arg, retarg, cmp_op), 
111                                           cvCreateImage(cvGetSize(self), 8, 1));
112 %enddef
113
114 %define %wrap_cvCmpS(pyfunc, cmp_op)
115 %wrap_cvGeneric_CvArr(CvMat, CvMat *, pyfunc, double, 
116                       cvCmpS(self, arg, retarg, cmp_op), 
117                                           cvCreateMat(self->rows, self->cols, CV_8U));
118 %wrap_cvGeneric_CvArr(IplImage, IplImage *, pyfunc, double, 
119                       cvCmpS(self, arg, retarg, cmp_op), 
120                                           cvCreateImage(cvGetSize(self), 8, 1));
121 %enddef
122
123 // special case for cvScale, /, * 
124 %define %wrap_cvScale(pyfunc, scale)
125 %wrap_cvGeneric_CvArr(CvMat, CvMat *, pyfunc, double,
126                 cvScale(self, retarg, scale),
127                 cvCreateMat(self->rows, self->cols, self->type));
128 %wrap_cvGeneric_CvArr(IplImage, IplImage *, pyfunc, double,
129                 cvScale(self, retarg, scale),
130                 cvCreateImage(cvGetSize(self), self->depth, self->nChannels));
131 %enddef
132
133 /*M//////////////////////////////////////////////////////////////////////////////////////////
134 // Actual Operator Declarations
135 //////////////////////////////////////////////////////////////////////////////////////////M*/
136
137 // Arithmetic operators 
138 %wrap_cvArith(__radd__, cvAdd);
139
140 // special case for reverse operations
141 %wrap_cvArr_binaryop(__rsub__, CvArr *, cvSub(arg, self, retarg));
142 %wrap_cvArr_binaryop(__rdiv__, CvArr *, cvDiv(arg, self, retarg));
143 %wrap_cvArr_binaryop(__rmul__, CvArr *, cvMul(arg, self, retarg));
144
145 %wrap_cvArithS(__radd__, cvAddS);
146 %wrap_cvArithS(__rsub__, cvSubRS);
147
148 %wrap_cvScale(__rmul__, arg);
149
150 %wrap_cvLogicS(__ror__, cvOrS)
151 %wrap_cvLogicS(__rand__, cvAndS)
152 %wrap_cvLogicS(__rxor__, cvXorS)
153
154 %wrap_cvCmpS(__req__, CV_CMP_EQ);
155 %wrap_cvCmpS(__rgt__, CV_CMP_GT);
156 %wrap_cvCmpS(__rge__, CV_CMP_GE);
157 %wrap_cvCmpS(__rlt__, CV_CMP_LT);
158 %wrap_cvCmpS(__rle__, CV_CMP_LE);
159 %wrap_cvCmpS(__rne__, CV_CMP_NE);
160
161 // special case for scalar-array division
162 %wrap_cvGeneric_CvArr(CvMat, CvMat *, __rdiv__, double, 
163     cvDiv(NULL, self, retarg, arg),
164     cvCreateMat(self->rows, self->cols, self->type));
165
166 // misc operators for python
167 %wrap_cvArr_binaryop(__pow__, double, cvPow(self, retarg, arg))
168
169 // TODO -- other Python operators listed below and at:
170 // http://docs.python.org/ref/numeric-types.html
171
172 // __abs__ -- cvAbs
173 // __nonzero__
174 // __hash__ ??
175 // __repr__  -- full string representation
176 // __str__  -- compact representation
177 // __call__ -- ??
178 // __len__ -- number of rows? or elements?
179 // __iter__ -- ??
180 // __contains__ -- cvCmpS, cvMax ?
181 // __floordiv__ ??
182 // __mul__ -- cvGEMM
183 // __lshift__ -- ??
184 // __rshift__ -- ??
185 // __pow__ -- cvPow
186
187 // Called to implement the unary arithmetic operations (-, +, abs() and ~). 
188 //__neg__(  self)
189 //__pos__(  self)
190 //__abs__(  self)
191 //__invert__(  self)
192
193 // Called to implement the built-in functions complex(), int(), long(), and float(). Should return a value of the appropriate type.  Can I abuse this to return an array of the correct type??? scipy only allows return of length 1 arrays.
194 // __complex__( self )
195 // __int__( self )
196 // __long__( self )
197 // __float__( self )
198
199 /*M//////////////////////////////////////////////////////////////////////////////////////////
200 // Slice access and assignment for CvArr types
201 //////////////////////////////////////////////////////////////////////////////////////////M*/
202
203 // TODO: CvMatND
204
205 %newobject CvMat::__getitem__(PyObject * object);
206 %newobject _IplImage::__getitem__(PyObject * object);
207
208 // Macro to check bounds of slice and throw error if outside
209 %define CHECK_SLICE_BOUNDS(rect,w,h,retval)
210         //printf("__setitem__ slice(%d:%d, %d:%d) array(%d,%d)", rect.x, rect.y, rect.x+rect.width, rect.y+rect.height, w, h);
211         if(rect.width<=0 || rect.height<=0 ||
212                 rect.width>w || rect.height>h ||
213                 rect.x<0 || rect.y<0 ||
214                 rect.x>= w || rect.y >=h){
215                 char errstr[256];
216                 // previous function already set error string
217                 if(rect.width==0 && rect.height==0 && rect.x==0 && rect.y==0) return retval;
218                 sprintf(errstr, "Requested slice [ %d:%d %d:%d ] oversteps array sized [ %d %d ]", 
219                         rect.x, rect.y, rect.x+rect.width, rect.y+rect.height, w, h);
220                 PyErr_SetString(PyExc_IndexError, errstr);
221                 //PyErr_SetString(PyExc_ValueError, errstr);
222                 return retval;
223         }
224 else{}
225 %enddef
226
227 // slice access and assignment for CvMat
228 %extend CvMat
229 {
230         char * __str__(){
231                 static char str[8];
232                 cvArrPrint( self );
233                 str[0]=0;
234                 return str;
235         }
236
237         // scalar assignment
238         void __setitem__(PyObject * object, double val){
239                 CvMat tmp;
240                 CvRect subrect = PySlice_to_CvRect( self, object );
241                 CHECK_SLICE_BOUNDS( subrect, self->cols, self->rows, );
242                 cvGetSubRect(self, &tmp, subrect);
243                 cvSet(&tmp, cvScalarAll(val));
244         }
245         void __setitem__(PyObject * object, CvPoint val){
246                 CvMat tmp;
247                 CvRect subrect = PySlice_to_CvRect( self, object );
248                 CHECK_SLICE_BOUNDS( subrect, self->cols, self->rows, );
249                 cvGetSubRect(self, &tmp, subrect);
250                 cvSet(&tmp, cvScalar(val.x, val.y));
251         }
252         void __setitem__(PyObject * object, CvPoint2D32f val){
253                 CvMat tmp;
254                 CvRect subrect = PySlice_to_CvRect( self, object );
255                 cvGetSubRect(self, &tmp, subrect);
256                 CHECK_SLICE_BOUNDS( subrect, self->cols, self->rows, );
257                 cvSet(&tmp, cvScalar(val.x, val.y));
258         }
259         void __setitem__(PyObject * object, CvScalar val){
260                 CvMat tmp;
261                 CvRect subrect = PySlice_to_CvRect( self, object );
262                 cvGetSubRect(self, &tmp, subrect);
263                 CHECK_SLICE_BOUNDS( subrect, self->cols, self->rows, );
264                 cvSet(&tmp, val);
265         }
266
267         // array slice assignment
268         void __setitem__(PyObject * object, CvArr * arr){
269                 CvMat tmp, src_stub, *src;
270                 CvRect subrect = PySlice_to_CvRect( self, object );
271                 CHECK_SLICE_BOUNDS( subrect, self->cols, self->rows, );
272                 cvGetSubRect(self, &tmp, subrect);
273                 
274                 // Reshape source array to fit destination
275                 // This will be used a lot for small arrays b/c
276                 // PyObject_to_CvArr tries to compress a 2-D python
277                 // array with 1-4 columns into a multichannel vector
278                 src=cvReshape(arr, &src_stub, CV_MAT_CN(tmp.type), tmp.rows);
279
280                 cvConvert(src, &tmp);
281         }
282         
283         // slice access
284         PyObject * __getitem__(PyObject * object){
285                 CvMat * mat;
286                 CvRect subrect = PySlice_to_CvRect( self, object );
287                 CHECK_SLICE_BOUNDS( subrect, self->cols, self->rows, NULL );
288                 if(subrect.width==1 && subrect.height==1){
289                         CvScalar * s; 
290             int type = cvGetElemType( self );
291             if(CV_MAT_CN(type) > 1){
292                 s = new CvScalar; 
293                 *s = cvGet2D( self, subrect.y, subrect.x );
294                 return SWIG_NewPointerObj( s, $descriptor(CvScalar *), 1 );
295             }
296             switch(CV_MAT_DEPTH(type)){
297             case CV_8U:
298                 return PyLong_FromUnsignedLong( CV_MAT_ELEM(*self, uchar, subrect.y, subrect.x ) );
299             case CV_8S:
300                 return PyLong_FromLong( CV_MAT_ELEM(*self, char, subrect.y, subrect.x ) );
301             case CV_16U:
302                 return PyLong_FromUnsignedLong( CV_MAT_ELEM(*self, ushort, subrect.y, subrect.x ) );
303             case CV_16S:
304                 return PyLong_FromLong( CV_MAT_ELEM(*self, short, subrect.y, subrect.x ) );
305             case CV_32S:
306                 return PyLong_FromLong( CV_MAT_ELEM(*self, int, subrect.y, subrect.x ) );
307             case CV_32F:
308                 return PyFloat_FromDouble( CV_MAT_ELEM(*self, float, subrect.y, subrect.x) );
309             case CV_64F:
310                 return PyFloat_FromDouble( CV_MAT_ELEM(*self, double, subrect.y, subrect.x) );
311             }
312                 }
313                 mat = (CvMat *) cvAlloc(sizeof(CvMat));
314                 cvGetSubRect(self, mat, subrect);
315                 
316                 // cvGetSubRect doesn't do this since it assumes mat lives on the stack
317                 mat->hdr_refcount = self->hdr_refcount;
318                 mat->refcount = self->refcount;
319                 cvIncRefData(mat);
320
321                 return SWIG_NewPointerObj( mat, $descriptor(CvMat *), 1 );
322         }
323
324         // ~ operator -- swig doesn't generate this from the C++ equivalent
325         CvMat * __invert__(){
326                 CvMat * res = cvCreateMat(self->rows, self->cols, self->type);
327                 cvNot( self, res );
328                 return res;
329         }
330
331 %pythoncode %{
332 def __iter__(self):
333         """
334         generator function iterating through rows in matrix or elements in vector
335         """
336         if self.rows==1:
337                 return self.colrange()
338         return self.rowrange()
339
340 def rowrange(self):
341     """
342     generator function iterating along rows in matrix
343     """
344         for i in range(self.rows):
345                 yield self[i]
346
347 def colrange(self):
348     """
349     generator function iterating along columns in matrix
350     """
351         for i in range(self.cols):
352                 yield self[:,i]
353
354 # if arg is None, python still calls our operator overloads
355 # but we want
356 # if mat != None
357 # if mat == None
358 # to do the right thing -- so redefine __ne__ and __eq__
359
360 def __eq__(self, arg):
361     """
362         __eq__(self, None)
363         __eq__(self, CvArr src)
364         __eq__(self, double val)
365     """
366
367         if not arg:
368                 return False 
369         return _cv.CvMat___eq__(self, arg)
370 def __ne__(self, arg):
371     """
372         __ne__(self, None)
373         __ne__(self, CvArr src)
374         __ne__(self, double val)
375     """
376
377         if not arg:
378                 return True
379         return _cv.CvMat___ne__(self, arg)
380
381 %}
382
383 } //extend CvMat
384
385 // slice access and assignment for IplImage 
386 %extend _IplImage
387 {
388         char * __str__(){
389                 static char str[8];
390                 cvArrPrint( self );
391                 str[0]=0;
392                 return str;
393         }
394
395         // scalar assignment
396         void __setitem__(PyObject * object, double val){
397                 CvMat tmp;
398                 CvRect subrect = PySlice_to_CvRect( self, object );
399                 cvGetSubRect(self, &tmp, subrect);
400                 cvSet(&tmp, cvScalarAll(val));
401         }
402         void __setitem__(PyObject * object, CvPoint val){
403                 CvMat tmp;
404                 CvRect subrect = PySlice_to_CvRect( self, object );
405                 cvGetSubRect(self, &tmp, subrect);
406                 cvSet(&tmp, cvScalar(val.x, val.y));
407         }
408         void __setitem__(PyObject * object, CvPoint2D32f val){
409                 CvMat tmp;
410                 CvRect subrect = PySlice_to_CvRect( self, object );
411                 cvGetSubRect(self, &tmp, subrect);
412                 cvSet(&tmp, cvScalar(val.x, val.y));
413         }
414         void __setitem__(PyObject * object, CvScalar val){
415                 CvMat tmp;
416                 CvRect subrect = PySlice_to_CvRect( self, object );
417                 cvGetSubRect(self, &tmp, subrect);
418                 cvSet(&tmp, val);
419         }
420
421         // array slice assignment
422         void __setitem__(PyObject * object, CvArr * arr){
423                 CvMat tmp;
424                 CvRect subrect = PySlice_to_CvRect( self, object );
425                 cvGetSubRect(self, &tmp, subrect);
426                 cvConvert(arr, &tmp);
427         }
428
429         // slice access
430         PyObject * __getitem__(PyObject * object){
431                 CvMat mat;
432                 IplImage * im;
433                 CvRect subrect = PySlice_to_CvRect( self, object );
434                 
435                 // return scalar if single element
436                 if(subrect.width==1 && subrect.height==1){
437                         CvScalar * s;
438                         int type = cvGetElemType( self );
439                         if(CV_MAT_CN(type) > 1){
440                                 s = new CvScalar;
441                             *s = cvGet2D( self, subrect.y, subrect.x );
442                                 return SWIG_NewPointerObj( s, $descriptor(CvScalar *), 1 );
443                         }
444                         switch(CV_MAT_DEPTH(type)){
445                         case CV_8U:
446                                 return PyLong_FromUnsignedLong( CV_IMAGE_ELEM(self, uchar, subrect.y, subrect.x ) );
447                         case CV_8S:
448                                 return PyLong_FromLong( CV_IMAGE_ELEM(self, char, subrect.y, subrect.x ) );
449                         case CV_16U:
450                                 return PyLong_FromUnsignedLong( CV_IMAGE_ELEM(self, ushort, subrect.y, subrect.x ) );
451                         case CV_16S:
452                                 return PyLong_FromLong( CV_IMAGE_ELEM(self, short, subrect.y, subrect.x ) );
453                         case CV_32S:
454                                 return PyLong_FromLong( CV_IMAGE_ELEM(self, int, subrect.y, subrect.x ) );
455                         case CV_32F:
456                                 return PyFloat_FromDouble( CV_IMAGE_ELEM(self, float, subrect.y, subrect.x) );
457                         case CV_64F:
458                                 return PyFloat_FromDouble( CV_IMAGE_ELEM(self, double, subrect.y, subrect.x) );
459                         }
460                 }
461                 
462                 // otherwise return array
463                 im = (IplImage *) cvAlloc(sizeof(IplImage));
464                 cvGetSubRect(self, &mat, subrect);
465                 im = cvGetImage(&mat, im);
466                 return SWIG_NewPointerObj( im, $descriptor(_IplImage *), 1 );
467         }
468 }
469