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 // 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>
46 /*M//////////////////////////////////////////////////////////////////////////////////////////
47 // Macros for extending CvMat and IplImage -- primarily for operator overloading
48 //////////////////////////////////////////////////////////////////////////////////////////M*/
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);
55 rettype pyfunc(argtype arg){
56 rettype retarg = newobjcall;
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));
72 // Macro to define python function of the form A = A.f(c)
73 // where f modifies A inplace
75 %define %wrap_cvGeneric_InPlace(cname, rettype, pyfunc, argtype, cvfunc)
76 %wrap_cvGeneric_CvArr(cname, rettype, pyfunc, argtype, cvfunc, self);
79 /*M//////////////////////////////////////////////////////////////////////////////////////////
80 // Macros to map operators to specific OpenCV functions
81 //////////////////////////////////////////////////////////////////////////////////////////M*/
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));
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));
94 // same as wrap_cvArith
95 %define %wrap_cvLogic(pyfunc, cvfunc)
96 %wrap_cvArr_binaryop(pyfunc, CvArr *, cvfunc(self, arg, retarg))
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));
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));
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));
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));
134 /*M//////////////////////////////////////////////////////////////////////////////////////////
135 // Actual Operator Declarations
136 //////////////////////////////////////////////////////////////////////////////////////////M*/
138 // Arithmetic operators
139 %wrap_cvArith(__radd__, cvAdd);
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));
146 %wrap_cvArithS(__radd__, cvAddS);
147 %wrap_cvArithS(__rsub__, cvSubRS);
149 %wrap_cvScale(__rmul__, arg);
151 %wrap_cvLogicS(__ror__, cvOrS)
152 %wrap_cvLogicS(__rand__, cvAndS)
153 %wrap_cvLogicS(__rxor__, cvXorS)
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);
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));
167 // misc operators for python
168 %wrap_cvArr_binaryop(__pow__, double, cvPow(self, retarg, arg))
170 // TODO -- other Python operators listed below and at:
171 // http://docs.python.org/ref/numeric-types.html
176 // __repr__ -- full string representation
177 // __str__ -- compact representation
179 // __len__ -- number of rows? or elements?
181 // __contains__ -- cvCmpS, cvMax ?
188 // Called to implement the unary arithmetic operations (-, +, abs() and ~).
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 )
200 /*M//////////////////////////////////////////////////////////////////////////////////////////
201 // Slice access and assignment for CvArr types
202 //////////////////////////////////////////////////////////////////////////////////////////M*/
206 %newobject CvMat::__getitem__(PyObject * object);
207 %newobject _IplImage::__getitem__(PyObject * object);
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){
218 // previous function already set error string
219 if(rect.width==0 && rect.height==0 && rect.x==0 && rect.y==0) return -1;
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);
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{}
235 // slice access and assignment for CvMat
247 void __setitem__(PyObject * object, double val){
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));
254 void __setitem__(PyObject * object, CvPoint val){
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));
261 void __setitem__(PyObject * object, CvPoint2D32f val){
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));
268 void __setitem__(PyObject * object, CvScalar val){
270 CvRect subrect = PySlice_to_CvRect( self, object );
271 cvGetSubRect(self, &tmp, subrect);
272 CHECK_SLICE_BOUNDS( subrect, self->cols, self->rows, );
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);
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);
289 cvConvert(src, &tmp);
293 PyObject * __getitem__(PyObject * object){
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){
299 int type = cvGetElemType( self );
300 if(CV_MAT_CN(type) > 1){
302 *s = cvGet2D( self, subrect.y, subrect.x );
303 return SWIG_NewPointerObj( s, $descriptor(CvScalar *), 1 );
305 switch(CV_MAT_DEPTH(type)){
307 return PyLong_FromUnsignedLong( CV_MAT_ELEM(*self, uchar, subrect.y, subrect.x ) );
309 return PyLong_FromLong( CV_MAT_ELEM(*self, char, subrect.y, subrect.x ) );
311 return PyLong_FromUnsignedLong( CV_MAT_ELEM(*self, ushort, subrect.y, subrect.x ) );
313 return PyLong_FromLong( CV_MAT_ELEM(*self, short, subrect.y, subrect.x ) );
315 return PyLong_FromLong( CV_MAT_ELEM(*self, int, subrect.y, subrect.x ) );
317 return PyFloat_FromDouble( CV_MAT_ELEM(*self, float, subrect.y, subrect.x) );
319 return PyFloat_FromDouble( CV_MAT_ELEM(*self, double, subrect.y, subrect.x) );
322 mat = (CvMat *) cvAlloc(sizeof(CvMat));
323 cvGetSubRect(self, mat, subrect);
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;
330 return SWIG_NewPointerObj( mat, $descriptor(CvMat *), 1 );
333 // ~ operator -- swig doesn't generate this from the C++ equivalent
334 CvMat * __invert__(){
335 CvMat * res = cvCreateMat(self->rows, self->cols, self->type);
343 generator function iterating through rows in matrix or elements in vector
346 return self.colrange()
347 return self.rowrange()
351 generator function iterating along rows in matrix
353 for i in range(self.rows):
358 generator function iterating along columns in matrix
360 for i in range(self.cols):
363 # if arg is None, python still calls our operator overloads
367 # to do the right thing -- so redefine __ne__ and __eq__
369 def __eq__(self, arg):
372 __eq__(self, CvArr src)
373 __eq__(self, double val)
378 return _cv.CvMat___eq__(self, arg)
379 def __ne__(self, arg):
382 __ne__(self, CvArr src)
383 __ne__(self, double val)
388 return _cv.CvMat___ne__(self, arg)
390 def __get_array_interface__ (self):
391 """Compose numpy array interface
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
397 See: http://numpy.scipy.org/array_interface.shtml
399 @author Mark Asbach <asbach@ient.rwth-aachen.de>
403 if self.depth == IPL_DEPTH_8U:
406 elif self.depth == IPL_DEPTH_8S:
409 elif self.depth == IPL_DEPTH_16U:
412 elif self.depth == IPL_DEPTH_16S:
415 elif self.depth == IPL_DEPTH_32S:
418 elif self.depth == IPL_DEPTH_32F:
421 elif self.depth == IPL_DEPTH_64F:
425 raise TypeError("unknown resp. unhandled OpenCV image/matrix format")
427 if self.nChannels == 1:
428 # monochrome image, matrix with a single channel
429 return {'shape': (self.height, self.width),
433 'data': (int (self.data.ptr), False),
434 'strides': (int (self.widthStep), int (bytes_per_pixel))}
436 # color image, image with alpha, matrix with multiple channels
437 return {'shape': (self.height, self.width, self.nChannels),
441 'data': (int (self.data.ptr), False),
442 'strides': (int (self.widthStep), int (self.nChannels * bytes_per_pixel), int (bytes_per_pixel))}
444 __array_interface__ = property (__get_array_interface__, doc = "numpy array interface description")
450 // slice access and assignment for IplImage
461 void __setitem__(PyObject * object, double val){
463 CvRect subrect = PySlice_to_CvRect( self, object );
464 cvGetSubRect(self, &tmp, subrect);
465 cvSet(&tmp, cvScalarAll(val));
467 void __setitem__(PyObject * object, CvPoint val){
469 CvRect subrect = PySlice_to_CvRect( self, object );
470 cvGetSubRect(self, &tmp, subrect);
471 cvSet(&tmp, cvScalar(val.x, val.y));
473 void __setitem__(PyObject * object, CvPoint2D32f val){
475 CvRect subrect = PySlice_to_CvRect( self, object );
476 cvGetSubRect(self, &tmp, subrect);
477 cvSet(&tmp, cvScalar(val.x, val.y));
479 void __setitem__(PyObject * object, CvScalar val){
481 CvRect subrect = PySlice_to_CvRect( self, object );
482 cvGetSubRect(self, &tmp, subrect);
486 // array slice assignment
487 void __setitem__(PyObject * object, CvArr * arr){
489 CvRect subrect = PySlice_to_CvRect( self, object );
490 cvGetSubRect(self, &tmp, subrect);
491 cvConvert(arr, &tmp);
495 PyObject * __getitem__(PyObject * object){
498 CvRect subrect = PySlice_to_CvRect( self, object );
500 // return scalar if single element
501 if(subrect.width==1 && subrect.height==1){
503 int type = cvGetElemType( self );
504 if(CV_MAT_CN(type) > 1){
506 *s = cvGet2D( self, subrect.y, subrect.x );
507 return SWIG_NewPointerObj( s, $descriptor(CvScalar *), 1 );
509 switch(CV_MAT_DEPTH(type)){
511 return PyLong_FromUnsignedLong( CV_IMAGE_ELEM(self, uchar, subrect.y, subrect.x ) );
513 return PyLong_FromLong( CV_IMAGE_ELEM(self, char, subrect.y, subrect.x ) );
515 return PyLong_FromUnsignedLong( CV_IMAGE_ELEM(self, ushort, subrect.y, subrect.x ) );
517 return PyLong_FromLong( CV_IMAGE_ELEM(self, short, subrect.y, subrect.x ) );
519 return PyLong_FromLong( CV_IMAGE_ELEM(self, int, subrect.y, subrect.x ) );
521 return PyFloat_FromDouble( CV_IMAGE_ELEM(self, float, subrect.y, subrect.x) );
523 return PyFloat_FromDouble( CV_IMAGE_ELEM(self, double, subrect.y, subrect.x) );
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 );