Update to 2.0.0 tree from current Fremantle build
[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 // 2009-01-07  Added numpy array interface, Mark Asbach <asbach@ient.rwth-aachen.de>
45
46 /*M//////////////////////////////////////////////////////////////////////////////////////////
47 // Macros for extending CvMat and IplImage -- primarily for operator overloading 
48 //////////////////////////////////////////////////////////////////////////////////////////M*/
49
50 // Macro to define python function of form B = A.f(c)
51 // where A is a CvArr type, c and B are arbitrary types
52 %define %wrap_cvGeneric_CvArr(cname, rettype, pyfunc, argtype, cvfunc, newobjcall)
53 %newobject cname::pyfunc(argtype arg);
54 %extend cname { 
55         rettype pyfunc(argtype arg){
56                 rettype retarg = newobjcall;
57                 cvfunc;
58                 return retarg;
59         }
60 }
61 %enddef
62
63 // Macro to define python function of the form B = A.f(c) 
64 // where A and B are both CvArr of same size and type
65 %define %wrap_cvArr_binaryop(pyfunc, argtype, cvfunc)
66 %wrap_cvGeneric_CvArr(CvMat, CvMat *, pyfunc, argtype, cvfunc, 
67                                           cvCreateMat(self->rows, self->cols, self->type));
68 %wrap_cvGeneric_CvArr(IplImage, IplImage *, pyfunc, argtype, cvfunc,
69                                           cvCreateImage(cvGetSize(self), self->depth, self->nChannels));
70 %enddef
71
72 // Macro to define python function of the form A = A.f(c) 
73 // where f modifies A inplace
74 // use for +=, etc
75 %define %wrap_cvGeneric_InPlace(cname, rettype, pyfunc, argtype, cvfunc)
76 %wrap_cvGeneric_CvArr(cname, rettype, pyfunc, argtype, cvfunc, self);
77 %enddef
78
79 /*M//////////////////////////////////////////////////////////////////////////////////////////
80 // Macros to map operators to specific OpenCV functions
81 //////////////////////////////////////////////////////////////////////////////////////////M*/
82
83 // map any OpenCV function of form cvFunc(src1, src2, dst)
84 %define %wrap_cvArith(pyfunc, cvfunc)
85 %wrap_cvArr_binaryop(pyfunc, CvArr *, cvfunc(self, arg, retarg));
86 %enddef
87
88 // map any OpenCV function of form cvFunc(src1, value, dst)
89 %define %wrap_cvArithS(pyfunc, cvfuncS)
90 %wrap_cvArr_binaryop(pyfunc, CvScalar, cvfuncS(self, arg, retarg));
91 %wrap_cvArr_binaryop(pyfunc, double, cvfuncS(self, cvScalar(arg), retarg));
92 %enddef
93
94 // same as wrap_cvArith
95 %define %wrap_cvLogic(pyfunc, cvfunc)
96 %wrap_cvArr_binaryop(pyfunc, CvArr *, cvfunc(self, arg, retarg))
97 %enddef
98
99 // same as wrap_cvArithS
100 %define %wrap_cvLogicS(pyfunc, cvfuncS)
101 %wrap_cvArr_binaryop(pyfunc, CvScalar, cvfuncS(self, arg, retarg));
102 %wrap_cvArr_binaryop(pyfunc, double, cvfuncS(self, cvScalar(arg), retarg));
103 %enddef
104
105 // Macro to map logical operations to cvCmp
106 %define %wrap_cvCmp(pyfunc, cmp_op)
107 %wrap_cvGeneric_CvArr(CvMat, CvMat *, pyfunc, CvMat *, 
108                       cvCmp(self, arg, retarg, cmp_op), 
109                                           cvCreateMat(self->rows, self->cols, CV_8U));
110 %wrap_cvGeneric_CvArr(IplImage, IplImage *, pyfunc, IplImage *, 
111                       cvCmp(self, arg, retarg, cmp_op), 
112                                           cvCreateImage(cvGetSize(self), 8, 1));
113 %enddef
114
115 %define %wrap_cvCmpS(pyfunc, cmp_op)
116 %wrap_cvGeneric_CvArr(CvMat, CvMat *, pyfunc, double, 
117                       cvCmpS(self, arg, retarg, cmp_op), 
118                                           cvCreateMat(self->rows, self->cols, CV_8U));
119 %wrap_cvGeneric_CvArr(IplImage, IplImage *, pyfunc, double, 
120                       cvCmpS(self, arg, retarg, cmp_op), 
121                                           cvCreateImage(cvGetSize(self), 8, 1));
122 %enddef
123
124 // special case for cvScale, /, * 
125 %define %wrap_cvScale(pyfunc, scale)
126 %wrap_cvGeneric_CvArr(CvMat, CvMat *, pyfunc, double,
127                 cvScale(self, retarg, scale),
128                 cvCreateMat(self->rows, self->cols, self->type));
129 %wrap_cvGeneric_CvArr(IplImage, IplImage *, pyfunc, double,
130                 cvScale(self, retarg, scale),
131                 cvCreateImage(cvGetSize(self), self->depth, self->nChannels));
132 %enddef
133
134 /*M//////////////////////////////////////////////////////////////////////////////////////////
135 // Actual Operator Declarations
136 //////////////////////////////////////////////////////////////////////////////////////////M*/
137
138 // Arithmetic operators 
139 %wrap_cvArith(__radd__, cvAdd);
140
141 // special case for reverse operations
142 %wrap_cvArr_binaryop(__rsub__, CvArr *, cvSub(arg, self, retarg));
143 %wrap_cvArr_binaryop(__rdiv__, CvArr *, cvDiv(arg, self, retarg));
144 %wrap_cvArr_binaryop(__rmul__, CvArr *, cvMul(arg, self, retarg));
145
146 %wrap_cvArithS(__radd__, cvAddS);
147 %wrap_cvArithS(__rsub__, cvSubRS);
148
149 %wrap_cvScale(__rmul__, arg);
150
151 %wrap_cvLogicS(__ror__, cvOrS)
152 %wrap_cvLogicS(__rand__, cvAndS)
153 %wrap_cvLogicS(__rxor__, cvXorS)
154
155 %wrap_cvCmpS(__req__, CV_CMP_EQ);
156 %wrap_cvCmpS(__rgt__, CV_CMP_GT);
157 %wrap_cvCmpS(__rge__, CV_CMP_GE);
158 %wrap_cvCmpS(__rlt__, CV_CMP_LT);
159 %wrap_cvCmpS(__rle__, CV_CMP_LE);
160 %wrap_cvCmpS(__rne__, CV_CMP_NE);
161
162 // special case for scalar-array division
163 %wrap_cvGeneric_CvArr(CvMat, CvMat *, __rdiv__, double, 
164     cvDiv(NULL, self, retarg, arg),
165     cvCreateMat(self->rows, self->cols, self->type));
166
167 // misc operators for python
168 %wrap_cvArr_binaryop(__pow__, double, cvPow(self, retarg, arg))
169
170 // TODO -- other Python operators listed below and at:
171 // http://docs.python.org/ref/numeric-types.html
172
173 // __abs__ -- cvAbs
174 // __nonzero__
175 // __hash__ ??
176 // __repr__  -- full string representation
177 // __str__  -- compact representation
178 // __call__ -- ??
179 // __len__ -- number of rows? or elements?
180 // __iter__ -- ??
181 // __contains__ -- cvCmpS, cvMax ?
182 // __floordiv__ ??
183 // __mul__ -- cvGEMM
184 // __lshift__ -- ??
185 // __rshift__ -- ??
186 // __pow__ -- cvPow
187
188 // Called to implement the unary arithmetic operations (-, +, abs() and ~). 
189 //__neg__(  self)
190 //__pos__(  self)
191 //__abs__(  self)
192 //__invert__(  self)
193
194 // 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.
195 // __complex__( self )
196 // __int__( self )
197 // __long__( self )
198 // __float__( self )
199
200 /*M//////////////////////////////////////////////////////////////////////////////////////////
201 // Slice access and assignment for CvArr types
202 //////////////////////////////////////////////////////////////////////////////////////////M*/
203
204 // TODO: CvMatND
205
206 %newobject CvMat::__getitem__(PyObject * object);
207 %newobject _IplImage::__getitem__(PyObject * object);
208
209 %header %{
210 int checkSliceBounds(const CvRect & rect, int w, int h){
211         //printf("__setitem__ slice(%d:%d, %d:%d) array(%d,%d)", rect.x, rect.y, rect.x+rect.width, rect.y+rect.height, w, h);
212         if(rect.width<=0 || rect.height<=0 ||
213                 rect.width>w || rect.height>h ||
214                 rect.x<0 || rect.y<0 ||
215                 rect.x>= w || rect.y >=h){
216                 char errstr[256];
217
218                 // previous function already set error string
219                 if(rect.width==0 && rect.height==0 && rect.x==0 && rect.y==0) return -1;
220
221                 sprintf(errstr, "Requested slice [ %d:%d %d:%d ] oversteps array sized [ %d %d ]", 
222                         rect.x, rect.y, rect.x+rect.width, rect.y+rect.height, w, h);
223                 PyErr_SetString(PyExc_IndexError, errstr);
224                 //PyErr_SetString(PyExc_ValueError, errstr);
225                 return -1;
226         }
227     return 0;
228 }
229 %}
230 // Macro to check bounds of slice and throw error if outside
231 %define CHECK_SLICE_BOUNDS(rect,w,h,retval)
232     if(CheckSliceBounds(&rect,w,h)==-1){ return retval; } else{}
233 %enddef
234
235 // slice access and assignment for CvMat
236 %extend CvMat
237 {
238         char * __str__(){
239                 static char str[8];
240                 cvArrPrint( self );
241                 str[0]=0;
242                 return str;
243         }
244     
245
246         // scalar assignment
247         void __setitem__(PyObject * object, double val){
248                 CvMat tmp;
249                 CvRect subrect = PySlice_to_CvRect( self, object );
250                 CHECK_SLICE_BOUNDS( subrect, self->cols, self->rows, );
251                 cvGetSubRect(self, &tmp, subrect);
252                 cvSet(&tmp, cvScalarAll(val));
253         }
254         void __setitem__(PyObject * object, CvPoint val){
255                 CvMat tmp;
256                 CvRect subrect = PySlice_to_CvRect( self, object );
257                 CHECK_SLICE_BOUNDS( subrect, self->cols, self->rows, );
258                 cvGetSubRect(self, &tmp, subrect);
259                 cvSet(&tmp, cvScalar(val.x, val.y));
260         }
261         void __setitem__(PyObject * object, CvPoint2D32f val){
262                 CvMat tmp;
263                 CvRect subrect = PySlice_to_CvRect( self, object );
264                 cvGetSubRect(self, &tmp, subrect);
265                 CHECK_SLICE_BOUNDS( subrect, self->cols, self->rows, );
266                 cvSet(&tmp, cvScalar(val.x, val.y));
267         }
268         void __setitem__(PyObject * object, CvScalar val){
269                 CvMat tmp;
270                 CvRect subrect = PySlice_to_CvRect( self, object );
271                 cvGetSubRect(self, &tmp, subrect);
272                 CHECK_SLICE_BOUNDS( subrect, self->cols, self->rows, );
273                 cvSet(&tmp, val);
274         }
275
276         // array slice assignment
277         void __setitem__(PyObject * object, CvArr * arr){
278                 CvMat tmp, src_stub, *src;
279                 CvRect subrect = PySlice_to_CvRect( self, object );
280                 CHECK_SLICE_BOUNDS( subrect, self->cols, self->rows, );
281                 cvGetSubRect(self, &tmp, subrect);
282                 
283                 // Reshape source array to fit destination
284                 // This will be used a lot for small arrays b/c
285                 // PyObject_to_CvArr tries to compress a 2-D python
286                 // array with 1-4 columns into a multichannel vector
287                 src=cvReshape(arr, &src_stub, CV_MAT_CN(tmp.type), tmp.rows);
288
289                 cvConvert(src, &tmp);
290         }
291         
292         // slice access
293         PyObject * __getitem__(PyObject * object){
294                 CvMat * mat;
295                 CvRect subrect = PySlice_to_CvRect( self, object );
296                 CHECK_SLICE_BOUNDS( subrect, self->cols, self->rows, NULL );
297                 if(subrect.width==1 && subrect.height==1){
298                         CvScalar * s; 
299             int type = cvGetElemType( self );
300             if(CV_MAT_CN(type) > 1){
301                 s = new CvScalar; 
302                 *s = cvGet2D( self, subrect.y, subrect.x );
303                 return SWIG_NewPointerObj( s, $descriptor(CvScalar *), 1 );
304             }
305             switch(CV_MAT_DEPTH(type)){
306             case CV_8U:
307                 return PyLong_FromUnsignedLong( CV_MAT_ELEM(*self, uchar, subrect.y, subrect.x ) );
308             case CV_8S:
309                 return PyLong_FromLong( CV_MAT_ELEM(*self, char, subrect.y, subrect.x ) );
310             case CV_16U:
311                 return PyLong_FromUnsignedLong( CV_MAT_ELEM(*self, ushort, subrect.y, subrect.x ) );
312             case CV_16S:
313                 return PyLong_FromLong( CV_MAT_ELEM(*self, short, subrect.y, subrect.x ) );
314             case CV_32S:
315                 return PyLong_FromLong( CV_MAT_ELEM(*self, int, subrect.y, subrect.x ) );
316             case CV_32F:
317                 return PyFloat_FromDouble( CV_MAT_ELEM(*self, float, subrect.y, subrect.x) );
318             case CV_64F:
319                 return PyFloat_FromDouble( CV_MAT_ELEM(*self, double, subrect.y, subrect.x) );
320             }
321                 }
322                 mat = (CvMat *) cvAlloc(sizeof(CvMat));
323                 cvGetSubRect(self, mat, subrect);
324                 
325                 // cvGetSubRect doesn't do this since it assumes mat lives on the stack
326                 mat->hdr_refcount = self->hdr_refcount;
327                 mat->refcount = self->refcount;
328                 cvIncRefData(mat);
329
330                 return SWIG_NewPointerObj( mat, $descriptor(CvMat *), 1 );
331         }
332
333         // ~ operator -- swig doesn't generate this from the C++ equivalent
334         CvMat * __invert__(){
335                 CvMat * res = cvCreateMat(self->rows, self->cols, self->type);
336                 cvNot( self, res );
337                 return res;
338         }
339
340 %pythoncode %{
341 def __iter__(self):
342         """
343         generator function iterating through rows in matrix or elements in vector
344         """
345         if self.rows==1:
346                 return self.colrange()
347         return self.rowrange()
348
349 def rowrange(self):
350     """
351     generator function iterating along rows in matrix
352     """
353         for i in range(self.rows):
354                 yield self[i]
355
356 def colrange(self):
357     """
358     generator function iterating along columns in matrix
359     """
360         for i in range(self.cols):
361                 yield self[:,i]
362
363 # if arg is None, python still calls our operator overloads
364 # but we want
365 # if mat != None
366 # if mat == None
367 # to do the right thing -- so redefine __ne__ and __eq__
368
369 def __eq__(self, arg):
370     """
371         __eq__(self, None)
372         __eq__(self, CvArr src)
373         __eq__(self, double val)
374     """
375
376         if not arg:
377                 return False 
378         return _cv.CvMat___eq__(self, arg)
379 def __ne__(self, arg):
380     """
381         __ne__(self, None)
382         __ne__(self, CvArr src)
383         __ne__(self, double val)
384     """
385
386         if not arg:
387                 return True
388         return _cv.CvMat___ne__(self, arg)
389
390 def __get_array_interface__ (self):
391   """Compose numpy array interface
392   
393   Via the numpy array interface, OpenCV data structures can be directly passed to numpy
394   methods without copying / converting. This tremendously speeds up mixing code from
395   OpenCV and numpy.
396   
397   See: http://numpy.scipy.org/array_interface.shtml
398   
399   @author Mark Asbach <asbach@ient.rwth-aachen.de>
400   @date   2009-01-07
401   """
402   
403   if   self.depth == IPL_DEPTH_8U:
404     typestr = '|u1'
405     bytes_per_pixel = 1
406   elif self.depth == IPL_DEPTH_8S:
407     typestr = '|i1'
408     bytes_per_pixel = 1
409   elif self.depth == IPL_DEPTH_16U:
410     typestr = '|u2'
411     bytes_per_pixel = 2
412   elif self.depth == IPL_DEPTH_16S:
413     typestr = '|i2'
414     bytes_per_pixel = 2
415   elif self.depth == IPL_DEPTH_32S:
416     typestr = '|i4'
417     bytes_per_pixel = 4
418   elif self.depth == IPL_DEPTH_32F:
419     typestr = '|f4'
420     bytes_per_pixel = 4
421   elif self.depth == IPL_DEPTH_64F:
422     typestr = '|f8'
423     bytes_per_pixel = 8
424   else:
425     raise TypeError("unknown resp. unhandled OpenCV image/matrix format")
426   
427   if self.nChannels == 1:
428     # monochrome image, matrix with a single channel
429     return {'shape':  (self.height, self.width), 
430            'typestr': typestr, 
431            'version': 3,
432            
433            'data':    (int (self.data.ptr), False),
434            'strides': (int (self.widthStep), int (bytes_per_pixel))}
435   else:
436     # color image, image with alpha, matrix with multiple channels
437     return {'shape':  (self.height, self.width, self.nChannels), 
438            'typestr': typestr, 
439            'version': 3,
440            
441            'data':    (int (self.data.ptr), False),
442            'strides': (int (self.widthStep), int (self.nChannels * bytes_per_pixel), int (bytes_per_pixel))}
443
444 __array_interface__ = property (__get_array_interface__, doc = "numpy array interface description")
445
446 %}
447
448 } //extend CvMat
449
450 // slice access and assignment for IplImage 
451 %extend _IplImage
452 {
453         char * __str__(){
454                 static char str[8];
455                 cvArrPrint( self );
456                 str[0]=0;
457                 return str;
458         }
459
460         // scalar assignment
461         void __setitem__(PyObject * object, double val){
462                 CvMat tmp;
463                 CvRect subrect = PySlice_to_CvRect( self, object );
464                 cvGetSubRect(self, &tmp, subrect);
465                 cvSet(&tmp, cvScalarAll(val));
466         }
467         void __setitem__(PyObject * object, CvPoint val){
468                 CvMat tmp;
469                 CvRect subrect = PySlice_to_CvRect( self, object );
470                 cvGetSubRect(self, &tmp, subrect);
471                 cvSet(&tmp, cvScalar(val.x, val.y));
472         }
473         void __setitem__(PyObject * object, CvPoint2D32f val){
474                 CvMat tmp;
475                 CvRect subrect = PySlice_to_CvRect( self, object );
476                 cvGetSubRect(self, &tmp, subrect);
477                 cvSet(&tmp, cvScalar(val.x, val.y));
478         }
479         void __setitem__(PyObject * object, CvScalar val){
480                 CvMat tmp;
481                 CvRect subrect = PySlice_to_CvRect( self, object );
482                 cvGetSubRect(self, &tmp, subrect);
483                 cvSet(&tmp, val);
484         }
485
486         // array slice assignment
487         void __setitem__(PyObject * object, CvArr * arr){
488                 CvMat tmp;
489                 CvRect subrect = PySlice_to_CvRect( self, object );
490                 cvGetSubRect(self, &tmp, subrect);
491                 cvConvert(arr, &tmp);
492         }
493
494         // slice access
495         PyObject * __getitem__(PyObject * object){
496                 CvMat mat;
497                 IplImage * im;
498                 CvRect subrect = PySlice_to_CvRect( self, object );
499                 
500                 // return scalar if single element
501                 if(subrect.width==1 && subrect.height==1){
502                         CvScalar * s;
503                         int type = cvGetElemType( self );
504                         if(CV_MAT_CN(type) > 1){
505                                 s = new CvScalar;
506                             *s = cvGet2D( self, subrect.y, subrect.x );
507                                 return SWIG_NewPointerObj( s, $descriptor(CvScalar *), 1 );
508                         }
509                         switch(CV_MAT_DEPTH(type)){
510                         case CV_8U:
511                                 return PyLong_FromUnsignedLong( CV_IMAGE_ELEM(self, uchar, subrect.y, subrect.x ) );
512                         case CV_8S:
513                                 return PyLong_FromLong( CV_IMAGE_ELEM(self, char, subrect.y, subrect.x ) );
514                         case CV_16U:
515                                 return PyLong_FromUnsignedLong( CV_IMAGE_ELEM(self, ushort, subrect.y, subrect.x ) );
516                         case CV_16S:
517                                 return PyLong_FromLong( CV_IMAGE_ELEM(self, short, subrect.y, subrect.x ) );
518                         case CV_32S:
519                                 return PyLong_FromLong( CV_IMAGE_ELEM(self, int, subrect.y, subrect.x ) );
520                         case CV_32F:
521                                 return PyFloat_FromDouble( CV_IMAGE_ELEM(self, float, subrect.y, subrect.x) );
522                         case CV_64F:
523                                 return PyFloat_FromDouble( CV_IMAGE_ELEM(self, double, subrect.y, subrect.x) );
524                         }
525                 }
526                 
527                 // otherwise return array
528                 im = (IplImage *) cvAlloc(sizeof(IplImage));
529                 cvGetSubRect(self, &mat, subrect);
530                 im = cvGetImage(&mat, im);
531                 return SWIG_NewPointerObj( im, $descriptor(_IplImage *), 1 );
532         }
533 }
534