cv2.cpp 35.8 KB
Newer Older
1 2 3 4 5
#if defined(_MSC_VER) && (_MSC_VER >= 1800)
// eliminating duplicated round() declaration
#define HAVE_ROUND
#endif

6 7 8
#include <Python.h>

#define MODULESTR "cv2"
9
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
A
Andrey Kamaev 已提交
10
#include <numpy/ndarrayobject.h>
11

12
#include "pyopencv_generated_include.h"
13
#include "opencv2/core/types_c.h"
14

15 16
#include "opencv2/opencv_modules.hpp"

17 18
#include "pycompat.hpp"

19

20 21 22 23 24
static PyObject* opencv_error = 0;

static int failmsg(const char *fmt, ...)
{
    char str[1000];
25

26 27 28 29
    va_list ap;
    va_start(ap, fmt);
    vsnprintf(str, sizeof(str), fmt, ap);
    va_end(ap);
30

31 32 33 34
    PyErr_SetString(PyExc_TypeError, str);
    return 0;
}

35 36 37 38 39 40
struct ArgInfo
{
    const char * name;
    bool outputarg;
    // more fields may be added if necessary

41
    ArgInfo(const char * name_, bool outputarg_)
42 43 44 45 46 47 48
        : name(name_)
        , outputarg(outputarg_) {}

    // to match with older pyopencv_to function signature
    operator const char *() const { return name; }
};

49 50 51 52
class PyAllowThreads
{
public:
    PyAllowThreads() : _state(PyEval_SaveThread()) {}
53
    ~PyAllowThreads()
54 55 56 57 58 59 60
    {
        PyEval_RestoreThread(_state);
    }
private:
    PyThreadState* _state;
};

A
Alexander Mordvintsev 已提交
61 62 63 64
class PyEnsureGIL
{
public:
    PyEnsureGIL() : _state(PyGILState_Ensure()) {}
65
    ~PyEnsureGIL()
A
Alexander Mordvintsev 已提交
66 67 68 69 70 71 72
    {
        PyGILState_Release(_state);
    }
private:
    PyGILState_STATE _state;
};

73 74 75
#define ERRWRAP2(expr) \
try \
{ \
76
    PyAllowThreads allowThreads; \
77 78 79 80 81 82 83 84
    expr; \
} \
catch (const cv::Exception &e) \
{ \
    PyErr_SetString(opencv_error, e.what()); \
    return 0; \
}

V
Vadim Pisarevsky 已提交
85 86
using namespace cv;

87
typedef std::vector<uchar> vector_uchar;
A
abidrahmank 已提交
88
typedef std::vector<char> vector_char;
89 90 91 92 93 94 95 96 97 98 99 100 101 102
typedef std::vector<int> vector_int;
typedef std::vector<float> vector_float;
typedef std::vector<double> vector_double;
typedef std::vector<Point> vector_Point;
typedef std::vector<Point2f> vector_Point2f;
typedef std::vector<Vec2f> vector_Vec2f;
typedef std::vector<Vec3f> vector_Vec3f;
typedef std::vector<Vec4f> vector_Vec4f;
typedef std::vector<Vec6f> vector_Vec6f;
typedef std::vector<Vec4i> vector_Vec4i;
typedef std::vector<Rect> vector_Rect;
typedef std::vector<KeyPoint> vector_KeyPoint;
typedef std::vector<Mat> vector_Mat;
typedef std::vector<DMatch> vector_DMatch;
103
typedef std::vector<String> vector_String;
104
typedef std::vector<Scalar> vector_Scalar;
A
abidrahmank 已提交
105 106

typedef std::vector<std::vector<char> > vector_vector_char;
107 108 109 110
typedef std::vector<std::vector<Point> > vector_vector_Point;
typedef std::vector<std::vector<Point2f> > vector_vector_Point2f;
typedef std::vector<std::vector<Point3f> > vector_vector_Point3f;
typedef std::vector<std::vector<DMatch> > vector_vector_DMatch;
111

112
#ifdef HAVE_OPENCV_FEATURES2D
113
typedef SimpleBlobDetector::Params SimpleBlobDetector_Params;
114
#endif
115

116
#ifdef HAVE_OPENCV_FLANN
117 118
typedef cvflann::flann_distance_t cvflann_flann_distance_t;
typedef cvflann::flann_algorithm_t cvflann_flann_algorithm_t;
119
#endif
120

121
#ifdef HAVE_OPENCV_STITCHING
122
typedef Stitcher::Status Status;
123
#endif
124

V
Vadim Pisarevsky 已提交
125 126 127 128 129 130 131 132 133 134 135 136 137
static PyObject* failmsgp(const char *fmt, ...)
{
  char str[1000];

  va_list ap;
  va_start(ap, fmt);
  vsnprintf(str, sizeof(str), fmt, ap);
  va_end(ap);

  PyErr_SetString(PyExc_TypeError, str);
  return 0;
}

138 139 140
class NumpyAllocator : public MatAllocator
{
public:
141
    NumpyAllocator() { stdAllocator = Mat::getStdAllocator(); }
142
    ~NumpyAllocator() {}
143

144 145 146 147 148 149 150 151 152 153 154 155 156
    UMatData* allocate(PyObject* o, int dims, const int* sizes, int type, size_t* step) const
    {
        UMatData* u = new UMatData(this);
        u->data = u->origdata = (uchar*)PyArray_DATA((PyArrayObject*) o);
        npy_intp* _strides = PyArray_STRIDES((PyArrayObject*) o);
        for( int i = 0; i < dims - 1; i++ )
            step[i] = (size_t)_strides[i];
        step[dims-1] = CV_ELEM_SIZE(type);
        u->size = sizes[0]*step[0];
        u->userdata = o;
        return u;
    }

157
    UMatData* allocate(int dims0, const int* sizes, int type, void* data, size_t* step, int flags, UMatUsageFlags usageFlags) const
158
    {
159 160 161 162
        if( data != 0 )
        {
            CV_Error(Error::StsAssert, "The data should normally be NULL!");
            // probably this is safe to do in such extreme case
163
            return stdAllocator->allocate(dims0, sizes, type, data, step, flags, usageFlags);
164
        }
A
Alexander Mordvintsev 已提交
165 166
        PyEnsureGIL gil;

167 168 169 170
        int depth = CV_MAT_DEPTH(type);
        int cn = CV_MAT_CN(type);
        const int f = (int)(sizeof(size_t)/8);
        int typenum = depth == CV_8U ? NPY_UBYTE : depth == CV_8S ? NPY_BYTE :
171 172 173 174
        depth == CV_16U ? NPY_USHORT : depth == CV_16S ? NPY_SHORT :
        depth == CV_32S ? NPY_INT : depth == CV_32F ? NPY_FLOAT :
        depth == CV_64F ? NPY_DOUBLE : f*NPY_ULONGLONG + (f^1)*NPY_UINT;
        int i, dims = dims0;
A
Andrey Kamaev 已提交
175
        cv::AutoBuffer<npy_intp> _sizes(dims + 1);
176 177 178
        for( i = 0; i < dims; i++ )
            _sizes[i] = sizes[i];
        if( cn > 1 )
A
Andrey Kamaev 已提交
179
            _sizes[dims++] = cn;
180 181
        PyObject* o = PyArray_SimpleNew(dims, _sizes, typenum);
        if(!o)
A
Andrey Kamaev 已提交
182
            CV_Error_(Error::StsError, ("The numpy array of typenum=%d, ndims=%d can not be created", typenum, dims));
183
        return allocate(o, dims0, sizes, type, step);
184
    }
185

186
    bool allocate(UMatData* u, int accessFlags, UMatUsageFlags usageFlags) const
187
    {
188
        return stdAllocator->allocate(u, accessFlags, usageFlags);
189 190 191 192
    }

    void deallocate(UMatData* u) const
    {
193 194 195 196 197 198
        if(!u)
            return;
        PyEnsureGIL gil;
        CV_Assert(u->urefcount >= 0);
        CV_Assert(u->refcount >= 0);
        if(u->refcount == 0)
199 200
        {
            PyObject* o = (PyObject*)u->userdata;
201
            Py_XDECREF(o);
202 203
            delete u;
        }
204
    }
205 206

    const MatAllocator* stdAllocator;
207 208 209
};

NumpyAllocator g_numpyAllocator;
210

211 212 213 214 215 216 217

template<typename T> static
bool pyopencv_to(PyObject* obj, T& p, const char* name = "<unknown>");

template<typename T> static
PyObject* pyopencv_from(const T& src);

218 219
enum { ARG_NONE = 0, ARG_MAT = 1, ARG_SCALAR = 2 };

220
// special case, when the convertor needs full ArgInfo structure
221
static bool pyopencv_to(PyObject* o, Mat& m, const ArgInfo info)
222
{
223
    bool allowND = true;
V
Vadim Pisarevsky 已提交
224 225 226 227 228 229
    if(!o || o == Py_None)
    {
        if( !m.data )
            m.allocator = &g_numpyAllocator;
        return true;
    }
230

231 232
    if( PyInt_Check(o) )
    {
233
        double v[] = {static_cast<double>(PyInt_AsLong((PyObject*)o)), 0., 0., 0.};
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
        m = Mat(4, 1, CV_64F, v).clone();
        return true;
    }
    if( PyFloat_Check(o) )
    {
        double v[] = {PyFloat_AsDouble((PyObject*)o), 0., 0., 0.};
        m = Mat(4, 1, CV_64F, v).clone();
        return true;
    }
    if( PyTuple_Check(o) )
    {
        int i, sz = (int)PyTuple_Size((PyObject*)o);
        m = Mat(sz, 1, CV_64F);
        for( i = 0; i < sz; i++ )
        {
            PyObject* oi = PyTuple_GET_ITEM(o, i);
            if( PyInt_Check(oi) )
                m.at<double>(i) = (double)PyInt_AsLong(oi);
            else if( PyFloat_Check(oi) )
                m.at<double>(i) = (double)PyFloat_AsDouble(oi);
            else
            {
                failmsg("%s is not a numerical tuple", info.name);
                m.release();
                return false;
            }
        }
        return true;
    }

V
Vadim Pisarevsky 已提交
264 265
    if( !PyArray_Check(o) )
    {
266
        failmsg("%s is not a numpy array, neither a scalar", info.name);
V
Vadim Pisarevsky 已提交
267
        return false;
268
    }
269

270 271
    PyArrayObject* oarr = (PyArrayObject*) o;

272
    bool needcopy = false, needcast = false;
273
    int typenum = PyArray_TYPE(oarr), new_typenum = typenum;
274 275 276 277
    int type = typenum == NPY_UBYTE ? CV_8U :
               typenum == NPY_BYTE ? CV_8S :
               typenum == NPY_USHORT ? CV_16U :
               typenum == NPY_SHORT ? CV_16S :
278
               typenum == NPY_INT ? CV_32S :
279
               typenum == NPY_INT32 ? CV_32S :
280 281
               typenum == NPY_FLOAT ? CV_32F :
               typenum == NPY_DOUBLE ? CV_64F : -1;
282

283 284
    if( type < 0 )
    {
B
boatx 已提交
285
        if( typenum == NPY_INT64 || typenum == NPY_UINT64 || typenum == NPY_LONG )
286 287
        {
            needcopy = needcast = true;
288
            new_typenum = NPY_INT;
289 290 291 292 293 294 295
            type = CV_32S;
        }
        else
        {
            failmsg("%s data type = %d is not supported", info.name, typenum);
            return false;
        }
296
    }
297

A
Andrey Kamaev 已提交
298 299 300 301
#ifndef CV_MAX_DIM
    const int CV_MAX_DIM = 32;
#endif

302
    int ndims = PyArray_NDIM(oarr);
303 304
    if(ndims >= CV_MAX_DIM)
    {
305
        failmsg("%s dimensionality (=%d) is too high", info.name, ndims);
V
Vadim Pisarevsky 已提交
306
        return false;
307
    }
308

309
    int size[CV_MAX_DIM+1];
A
Andrey Kamaev 已提交
310 311
    size_t step[CV_MAX_DIM+1];
    size_t elemsize = CV_ELEM_SIZE1(type);
312 313
    const npy_intp* _sizes = PyArray_DIMS(oarr);
    const npy_intp* _strides = PyArray_STRIDES(oarr);
314 315
    bool ismultichannel = ndims == 3 && _sizes[2] <= CV_CN_MAX;

316 317 318 319 320 321
    for( int i = ndims-1; i >= 0 && !needcopy; i-- )
    {
        // these checks handle cases of
        //  a) multi-dimensional (ndims > 2) arrays, as well as simpler 1- and 2-dimensional cases
        //  b) transposed arrays, where _strides[] elements go in non-descending order
        //  c) flipped arrays, where some of _strides[] elements are negative
322 323 324
        // the _sizes[i] > 1 is needed to avoid spurious copies when NPY_RELAXED_STRIDES is set
        if( (i == ndims-1 && _sizes[i] > 1 && (size_t)_strides[i] != elemsize) ||
            (i < ndims-1 && _sizes[i] > 1 && _strides[i] < _strides[i+1]) )
325 326
            needcopy = true;
    }
327

328 329 330
    if( ismultichannel && _strides[1] != (npy_intp)elemsize*_sizes[2] )
        needcopy = true;

331 332 333 334
    if (needcopy)
    {
        if (info.outputarg)
        {
335
            failmsg("Layout of the output array %s is incompatible with cv::Mat (step[ndims-1] != elemsize or step[1] != elemsize*nchannels)", info.name);
336 337
            return false;
        }
338 339 340 341 342 343 344 345 346 347 348

        if( needcast ) {
            o = PyArray_Cast(oarr, new_typenum);
            oarr = (PyArrayObject*) o;
        }
        else {
            oarr = PyArray_GETCONTIGUOUS(oarr);
            o = (PyObject*) oarr;
        }

        _strides = PyArray_STRIDES(oarr);
349
    }
350

351 352 353
    // Normalize strides in case NPY_RELAXED_STRIDES is set
    size_t default_step = elemsize;
    for ( int i = ndims - 1; i >= 0; --i )
354 355
    {
        size[i] = (int)_sizes[i];
356 357 358 359 360 361 362 363 364 365
        if ( size[i] > 1 )
        {
            step[i] = (size_t)_strides[i];
            default_step = step[i] * size[i];
        }
        else
        {
            step[i] = default_step;
            default_step *= size[i];
        }
366
    }
367

368 369
    // handle degenerate case
    if( ndims == 0) {
370 371 372 373
        size[ndims] = 1;
        step[ndims] = elemsize;
        ndims++;
    }
374

375
    if( ismultichannel )
V
Vadim Pisarevsky 已提交
376 377 378 379
    {
        ndims--;
        type |= CV_MAKETYPE(0, size[2]);
    }
380

V
Vadim Pisarevsky 已提交
381
    if( ndims > 2 && !allowND )
382
    {
383
        failmsg("%s has more than 2 dimensions", info.name);
V
Vadim Pisarevsky 已提交
384
        return false;
385
    }
386

387
    m = Mat(ndims, size, type, PyArray_DATA(oarr), step);
388
    m.u = g_numpyAllocator.allocate(o, ndims, size, type, step);
A
Alexander Alekhin 已提交
389
    m.addref();
390

391
    if( !needcopy )
392
    {
393 394
        Py_INCREF(o);
    }
395
    m.allocator = &g_numpyAllocator;
396

V
Vadim Pisarevsky 已提交
397
    return true;
398 399
}

400 401 402 403 404 405
template<>
bool pyopencv_to(PyObject* o, Mat& m, const char* name)
{
    return pyopencv_to(o, m, ArgInfo(name, 0));
}

406 407
template<>
PyObject* pyopencv_from(const Mat& m)
408
{
409
    if( !m.data )
410
        Py_RETURN_NONE;
V
Vadim Pisarevsky 已提交
411
    Mat temp, *p = (Mat*)&m;
412
    if(!p->u || p->allocator != &g_numpyAllocator)
V
Vadim Pisarevsky 已提交
413
    {
V
Vadim Pisarevsky 已提交
414
        temp.allocator = &g_numpyAllocator;
415
        ERRWRAP2(m.copyTo(temp));
V
Vadim Pisarevsky 已提交
416 417
        p = &temp;
    }
418 419 420
    PyObject* o = (PyObject*)p->u->userdata;
    Py_INCREF(o);
    return o;
421 422
}

423 424
template<>
bool pyopencv_to(PyObject *o, Scalar& s, const char *name)
425
{
V
Vadim Pisarevsky 已提交
426 427
    if(!o || o == Py_None)
        return true;
428 429 430
    if (PySequence_Check(o)) {
        PyObject *fi = PySequence_Fast(o, name);
        if (fi == NULL)
V
Vadim Pisarevsky 已提交
431
            return false;
432 433 434
        if (4 < PySequence_Fast_GET_SIZE(fi))
        {
            failmsg("Scalar value for argument '%s' is longer than 4", name);
V
Vadim Pisarevsky 已提交
435
            return false;
436 437 438 439
        }
        for (Py_ssize_t i = 0; i < PySequence_Fast_GET_SIZE(fi); i++) {
            PyObject *item = PySequence_Fast_GET_ITEM(fi, i);
            if (PyFloat_Check(item) || PyInt_Check(item)) {
440
                s[(int)i] = PyFloat_AsDouble(item);
441 442
            } else {
                failmsg("Scalar value for argument '%s' is not numeric", name);
V
Vadim Pisarevsky 已提交
443
                return false;
444 445 446 447 448 449 450 451
            }
        }
        Py_DECREF(fi);
    } else {
        if (PyFloat_Check(o) || PyInt_Check(o)) {
            s[0] = PyFloat_AsDouble(o);
        } else {
            failmsg("Scalar value for argument '%s' is not numeric", name);
V
Vadim Pisarevsky 已提交
452
            return false;
453 454
        }
    }
V
Vadim Pisarevsky 已提交
455
    return true;
456 457
}

458 459
template<>
PyObject* pyopencv_from(const Scalar& src)
V
Vadim Pisarevsky 已提交
460 461 462
{
    return Py_BuildValue("(dddd)", src[0], src[1], src[2], src[3]);
}
463

464 465
template<>
PyObject* pyopencv_from(const bool& value)
466
{
V
Vadim Pisarevsky 已提交
467 468 469
    return PyBool_FromLong(value);
}

470
#ifdef HAVE_OPENCV_STITCHING
471 472 473 474 475
template<>
PyObject* pyopencv_from(const Status& value)
{
    return PyInt_FromLong(value);
}
476
#endif
477

478 479
template<>
bool pyopencv_to(PyObject* obj, bool& value, const char* name)
V
Vadim Pisarevsky 已提交
480
{
A
Andrey Kamaev 已提交
481
    (void)name;
V
Vadim Pisarevsky 已提交
482 483 484 485 486 487 488 489 490
    if(!obj || obj == Py_None)
        return true;
    int _val = PyObject_IsTrue(obj);
    if(_val < 0)
        return false;
    value = _val > 0;
    return true;
}

491 492
template<>
PyObject* pyopencv_from(const size_t& value)
V
Vadim Pisarevsky 已提交
493
{
494
    return PyLong_FromSize_t(value);
V
Vadim Pisarevsky 已提交
495
}
496

497 498
template<>
bool pyopencv_to(PyObject* obj, size_t& value, const char* name)
499
{
A
Andrey Kamaev 已提交
500
    (void)name;
501 502 503
    if(!obj || obj == Py_None)
        return true;
    value = (int)PyLong_AsUnsignedLong(obj);
504
    return value != (size_t)-1 || !PyErr_Occurred();
505 506
}

507 508
template<>
PyObject* pyopencv_from(const int& value)
V
Vadim Pisarevsky 已提交
509 510
{
    return PyInt_FromLong(value);
511 512
}

513
#ifdef HAVE_OPENCV_FLANN
514 515
template<>
PyObject* pyopencv_from(const cvflann_flann_algorithm_t& value)
A
Andrey Kamaev 已提交
516 517 518 519
{
    return PyInt_FromLong(int(value));
}

520 521
template<>
PyObject* pyopencv_from(const cvflann_flann_distance_t& value)
A
Andrey Kamaev 已提交
522 523 524
{
    return PyInt_FromLong(int(value));
}
525
#endif
A
Andrey Kamaev 已提交
526

527 528
template<>
bool pyopencv_to(PyObject* obj, int& value, const char* name)
529
{
A
Andrey Kamaev 已提交
530
    (void)name;
531 532
    if(!obj || obj == Py_None)
        return true;
533 534 535 536 537 538
    if(PyInt_Check(obj))
        value = (int)PyInt_AsLong(obj);
    else if(PyLong_Check(obj))
        value = (int)PyLong_AsLong(obj);
    else
        return false;
539 540 541
    return value != -1 || !PyErr_Occurred();
}

542 543
template<>
PyObject* pyopencv_from(const uchar& value)
544 545 546 547
{
    return PyInt_FromLong(value);
}

548 549
template<>
bool pyopencv_to(PyObject* obj, uchar& value, const char* name)
550
{
A
Andrey Kamaev 已提交
551
    (void)name;
V
Vadim Pisarevsky 已提交
552 553
    if(!obj || obj == Py_None)
        return true;
554 555 556
    int ivalue = (int)PyInt_AsLong(obj);
    value = cv::saturate_cast<uchar>(ivalue);
    return ivalue != -1 || !PyErr_Occurred();
V
Vadim Pisarevsky 已提交
557 558
}

559 560
template<>
PyObject* pyopencv_from(const double& value)
V
Vadim Pisarevsky 已提交
561 562 563 564
{
    return PyFloat_FromDouble(value);
}

565 566
template<>
bool pyopencv_to(PyObject* obj, double& value, const char* name)
V
Vadim Pisarevsky 已提交
567
{
A
Andrey Kamaev 已提交
568
    (void)name;
V
Vadim Pisarevsky 已提交
569 570
    if(!obj || obj == Py_None)
        return true;
571
    if(!!PyInt_CheckExact(obj))
V
Vadim Pisarevsky 已提交
572
        value = (double)PyInt_AS_LONG(obj);
573
    else
V
Vadim Pisarevsky 已提交
574 575
        value = PyFloat_AsDouble(obj);
    return !PyErr_Occurred();
576 577
}

578 579
template<>
PyObject* pyopencv_from(const float& value)
580
{
V
Vadim Pisarevsky 已提交
581
    return PyFloat_FromDouble(value);
582
}
V
Vadim Pisarevsky 已提交
583

584 585
template<>
bool pyopencv_to(PyObject* obj, float& value, const char* name)
586
{
A
Andrey Kamaev 已提交
587
    (void)name;
V
Vadim Pisarevsky 已提交
588 589
    if(!obj || obj == Py_None)
        return true;
590
    if(!!PyInt_CheckExact(obj))
V
Vadim Pisarevsky 已提交
591 592 593 594
        value = (float)PyInt_AS_LONG(obj);
    else
        value = (float)PyFloat_AsDouble(obj);
    return !PyErr_Occurred();
595 596
}

597 598
template<>
PyObject* pyopencv_from(const int64& value)
599
{
600
    return PyLong_FromLongLong(value);
601 602
}

603 604
template<>
PyObject* pyopencv_from(const String& value)
V
Vadim Pisarevsky 已提交
605 606 607
{
    return PyString_FromString(value.empty() ? "" : value.c_str());
}
608

609 610
template<>
bool pyopencv_to(PyObject* obj, String& value, const char* name)
611
{
A
Andrey Kamaev 已提交
612
    (void)name;
V
Vadim Pisarevsky 已提交
613 614 615 616 617
    if(!obj || obj == Py_None)
        return true;
    char* str = PyString_AsString(obj);
    if(!str)
        return false;
618
    value = String(str);
V
Vadim Pisarevsky 已提交
619 620 621
    return true;
}

622 623
template<>
bool pyopencv_to(PyObject* obj, Size& sz, const char* name)
V
Vadim Pisarevsky 已提交
624
{
A
Andrey Kamaev 已提交
625
    (void)name;
V
Vadim Pisarevsky 已提交
626 627
    if(!obj || obj == Py_None)
        return true;
A
Alexander Mordvintsev 已提交
628
    return PyArg_ParseTuple(obj, "ii", &sz.width, &sz.height) > 0;
V
Vadim Pisarevsky 已提交
629 630
}

631 632
template<>
PyObject* pyopencv_from(const Size& sz)
V
Vadim Pisarevsky 已提交
633 634 635 636
{
    return Py_BuildValue("(ii)", sz.width, sz.height);
}

637 638
template<>
bool pyopencv_to(PyObject* obj, Rect& r, const char* name)
V
Vadim Pisarevsky 已提交
639
{
A
Andrey Kamaev 已提交
640
    (void)name;
V
Vadim Pisarevsky 已提交
641 642
    if(!obj || obj == Py_None)
        return true;
A
Alexander Mordvintsev 已提交
643
    return PyArg_ParseTuple(obj, "iiii", &r.x, &r.y, &r.width, &r.height) > 0;
V
Vadim Pisarevsky 已提交
644 645
}

646 647
template<>
PyObject* pyopencv_from(const Rect& r)
V
Vadim Pisarevsky 已提交
648 649 650 651
{
    return Py_BuildValue("(iiii)", r.x, r.y, r.width, r.height);
}

652 653
template<>
bool pyopencv_to(PyObject* obj, Range& r, const char* name)
V
Vadim Pisarevsky 已提交
654
{
A
Andrey Kamaev 已提交
655
    (void)name;
V
Vadim Pisarevsky 已提交
656 657 658
    if(!obj || obj == Py_None)
        return true;
    if(PyObject_Size(obj) == 0)
659
    {
V
Vadim Pisarevsky 已提交
660 661
        r = Range::all();
        return true;
662
    }
A
Alexander Mordvintsev 已提交
663
    return PyArg_ParseTuple(obj, "ii", &r.start, &r.end) > 0;
V
Vadim Pisarevsky 已提交
664 665
}

666 667
template<>
PyObject* pyopencv_from(const Range& r)
V
Vadim Pisarevsky 已提交
668 669 670 671
{
    return Py_BuildValue("(ii)", r.start, r.end);
}

672 673
template<>
bool pyopencv_to(PyObject* obj, Point& p, const char* name)
V
Vadim Pisarevsky 已提交
674
{
A
Andrey Kamaev 已提交
675
    (void)name;
V
Vadim Pisarevsky 已提交
676 677
    if(!obj || obj == Py_None)
        return true;
678
    if(!!PyComplex_CheckExact(obj))
V
Vadim Pisarevsky 已提交
679 680 681 682 683 684
    {
        Py_complex c = PyComplex_AsCComplex(obj);
        p.x = saturate_cast<int>(c.real);
        p.y = saturate_cast<int>(c.imag);
        return true;
    }
A
Alexander Mordvintsev 已提交
685
    return PyArg_ParseTuple(obj, "ii", &p.x, &p.y) > 0;
V
Vadim Pisarevsky 已提交
686 687
}

688 689
template<>
bool pyopencv_to(PyObject* obj, Point2f& p, const char* name)
V
Vadim Pisarevsky 已提交
690
{
A
Andrey Kamaev 已提交
691
    (void)name;
V
Vadim Pisarevsky 已提交
692 693
    if(!obj || obj == Py_None)
        return true;
694
    if(!!PyComplex_CheckExact(obj))
695
    {
V
Vadim Pisarevsky 已提交
696 697 698 699 700
        Py_complex c = PyComplex_AsCComplex(obj);
        p.x = saturate_cast<float>(c.real);
        p.y = saturate_cast<float>(c.imag);
        return true;
    }
A
Alexander Mordvintsev 已提交
701
    return PyArg_ParseTuple(obj, "ff", &p.x, &p.y) > 0;
V
Vadim Pisarevsky 已提交
702 703
}

704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720
template<>
bool pyopencv_to(PyObject* obj, Point2d& p, const char* name)
{
    (void)name;
    if(!obj || obj == Py_None)
        return true;
    if(!!PyComplex_CheckExact(obj))
    {
        Py_complex c = PyComplex_AsCComplex(obj);
        p.x = saturate_cast<double>(c.real);
        p.y = saturate_cast<double>(c.imag);
        return true;
    }
    return PyArg_ParseTuple(obj, "dd", &p.x, &p.y) > 0;
}


721 722
template<>
PyObject* pyopencv_from(const Point& p)
V
Vadim Pisarevsky 已提交
723 724 725 726
{
    return Py_BuildValue("(ii)", p.x, p.y);
}

727 728
template<>
PyObject* pyopencv_from(const Point2f& p)
V
Vadim Pisarevsky 已提交
729 730 731 732
{
    return Py_BuildValue("(dd)", p.x, p.y);
}

733 734
template<>
bool pyopencv_to(PyObject* obj, Vec3d& v, const char* name)
V
Vadim Pisarevsky 已提交
735
{
A
Andrey Kamaev 已提交
736
    (void)name;
V
Vadim Pisarevsky 已提交
737 738
    if(!obj)
        return true;
A
Alexander Mordvintsev 已提交
739
    return PyArg_ParseTuple(obj, "ddd", &v[0], &v[1], &v[2]) > 0;
V
Vadim Pisarevsky 已提交
740 741
}

742 743
template<>
PyObject* pyopencv_from(const Vec3d& v)
V
Vadim Pisarevsky 已提交
744 745 746 747
{
    return Py_BuildValue("(ddd)", v[0], v[1], v[2]);
}

748 749
template<>
PyObject* pyopencv_from(const Vec2d& v)
A
Andrey Kamaev 已提交
750 751 752 753
{
    return Py_BuildValue("(dd)", v[0], v[1]);
}

754 755
template<>
PyObject* pyopencv_from(const Point2d& p)
V
Vadim Pisarevsky 已提交
756 757 758 759 760 761
{
    return Py_BuildValue("(dd)", p.x, p.y);
}

template<typename _Tp> struct pyopencvVecConverter
{
762
    static bool to(PyObject* obj, std::vector<_Tp>& value, const ArgInfo info)
V
Vadim Pisarevsky 已提交
763 764
    {
        typedef typename DataType<_Tp>::channel_type _Cp;
V
Vadim Pisarevsky 已提交
765
        if(!obj || obj == Py_None)
V
Vadim Pisarevsky 已提交
766 767 768 769
            return true;
        if (PyArray_Check(obj))
        {
            Mat m;
770
            pyopencv_to(obj, m, info);
V
Vadim Pisarevsky 已提交
771 772 773 774
            m.copyTo(value);
        }
        if (!PySequence_Check(obj))
            return false;
775
        PyObject *seq = PySequence_Fast(obj, info.name);
V
Vadim Pisarevsky 已提交
776 777 778 779
        if (seq == NULL)
            return false;
        int i, j, n = (int)PySequence_Fast_GET_SIZE(seq);
        value.resize(n);
780

V
Vadim Pisarevsky 已提交
781 782 783
        int type = DataType<_Tp>::type;
        int depth = CV_MAT_DEPTH(type), channels = CV_MAT_CN(type);
        PyObject** items = PySequence_Fast_ITEMS(seq);
784

V
Vadim Pisarevsky 已提交
785 786 787 788 789 790
        for( i = 0; i < n; i++ )
        {
            PyObject* item = items[i];
            PyObject* seq_i = 0;
            PyObject** items_i = &item;
            _Cp* data = (_Cp*)&value[i];
791

V
Vadim Pisarevsky 已提交
792 793 794 795 796 797 798 799 800
            if( channels == 2 && PyComplex_CheckExact(item) )
            {
                Py_complex c = PyComplex_AsCComplex(obj);
                data[0] = saturate_cast<_Cp>(c.real);
                data[1] = saturate_cast<_Cp>(c.imag);
                continue;
            }
            if( channels > 1 )
            {
V
Vadim Pisarevsky 已提交
801
                if( PyArray_Check(item))
V
Vadim Pisarevsky 已提交
802 803
                {
                    Mat src;
804
                    pyopencv_to(item, src, info);
V
Vadim Pisarevsky 已提交
805 806 807 808 809 810 811 812 813 814
                    if( src.dims != 2 || src.channels() != 1 ||
                       ((src.cols != 1 || src.rows != channels) &&
                        (src.cols != channels || src.rows != 1)))
                        break;
                    Mat dst(src.rows, src.cols, depth, data);
                    src.convertTo(dst, type);
                    if( dst.data != (uchar*)data )
                        break;
                    continue;
                }
815

816
                seq_i = PySequence_Fast(item, info.name);
V
Vadim Pisarevsky 已提交
817 818 819 820 821 822 823
                if( !seq_i || (int)PySequence_Fast_GET_SIZE(seq_i) != channels )
                {
                    Py_XDECREF(seq_i);
                    break;
                }
                items_i = PySequence_Fast_ITEMS(seq_i);
            }
824

V
Vadim Pisarevsky 已提交
825 826 827 828 829
            for( j = 0; j < channels; j++ )
            {
                PyObject* item_ij = items_i[j];
                if( PyInt_Check(item_ij))
                {
830 831 832 833 834 835 836 837
                    int v = (int)PyInt_AsLong(item_ij);
                    if( v == -1 && PyErr_Occurred() )
                        break;
                    data[j] = saturate_cast<_Cp>(v);
                }
                else if( PyLong_Check(item_ij))
                {
                    int v = (int)PyLong_AsLong(item_ij);
V
Vadim Pisarevsky 已提交
838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857
                    if( v == -1 && PyErr_Occurred() )
                        break;
                    data[j] = saturate_cast<_Cp>(v);
                }
                else if( PyFloat_Check(item_ij))
                {
                    double v = PyFloat_AsDouble(item_ij);
                    if( PyErr_Occurred() )
                        break;
                    data[j] = saturate_cast<_Cp>(v);
                }
                else
                    break;
            }
            Py_XDECREF(seq_i);
            if( j < channels )
                break;
        }
        Py_DECREF(seq);
        return i == n;
858
    }
859

860
    static PyObject* from(const std::vector<_Tp>& value)
V
Vadim Pisarevsky 已提交
861 862 863 864 865 866 867 868
    {
        if(value.empty())
            return PyTuple_New(0);
        Mat src((int)value.size(), DataType<_Tp>::channels, DataType<_Tp>::depth, (uchar*)&value[0]);
        return pyopencv_from(src);
    }
};

A
abidrahmank 已提交
869
template<typename _Tp>
870
bool pyopencv_to(PyObject* obj, std::vector<_Tp>& value, const ArgInfo info)
V
Vadim Pisarevsky 已提交
871
{
872
    return pyopencvVecConverter<_Tp>::to(obj, value, info);
V
Vadim Pisarevsky 已提交
873 874
}

875 876
template<typename _Tp>
PyObject* pyopencv_from(const std::vector<_Tp>& value)
V
Vadim Pisarevsky 已提交
877 878 879 880
{
    return pyopencvVecConverter<_Tp>::from(value);
}

881
template<typename _Tp> static inline bool pyopencv_to_generic_vec(PyObject* obj, std::vector<_Tp>& value, const ArgInfo info)
V
Vadim Pisarevsky 已提交
882
{
V
Vadim Pisarevsky 已提交
883 884
    if(!obj || obj == Py_None)
       return true;
V
Vadim Pisarevsky 已提交
885 886
    if (!PySequence_Check(obj))
        return false;
887
    PyObject *seq = PySequence_Fast(obj, info.name);
V
Vadim Pisarevsky 已提交
888 889 890 891
    if (seq == NULL)
        return false;
    int i, n = (int)PySequence_Fast_GET_SIZE(seq);
    value.resize(n);
892

V
Vadim Pisarevsky 已提交
893
    PyObject** items = PySequence_Fast_ITEMS(seq);
894

V
Vadim Pisarevsky 已提交
895 896 897
    for( i = 0; i < n; i++ )
    {
        PyObject* item = items[i];
898
        if(!pyopencv_to(item, value[i], info))
V
Vadim Pisarevsky 已提交
899 900 901 902 903 904
            break;
    }
    Py_DECREF(seq);
    return i == n;
}

905
template<typename _Tp> static inline PyObject* pyopencv_from_generic_vec(const std::vector<_Tp>& value)
V
Vadim Pisarevsky 已提交
906 907
{
    int i, n = (int)value.size();
V
Vadim Pisarevsky 已提交
908
    PyObject* seq = PyList_New(n);
V
Vadim Pisarevsky 已提交
909
    for( i = 0; i < n; i++ )
910
    {
V
Vadim Pisarevsky 已提交
911 912 913
        PyObject* item = pyopencv_from(value[i]);
        if(!item)
            break;
V
Vadim Pisarevsky 已提交
914
        PyList_SET_ITEM(seq, i, item);
V
Vadim Pisarevsky 已提交
915 916
    }
    if( i < n )
917
    {
V
Vadim Pisarevsky 已提交
918
        Py_DECREF(seq);
919 920
        return 0;
    }
V
Vadim Pisarevsky 已提交
921 922 923 924
    return seq;
}


925
template<typename _Tp> struct pyopencvVecConverter<std::vector<_Tp> >
V
Vadim Pisarevsky 已提交
926
{
A
abidrahmank 已提交
927
    static bool to(PyObject* obj, std::vector<std::vector<_Tp> >& value, const ArgInfo info)
V
Vadim Pisarevsky 已提交
928
    {
A
abidrahmank 已提交
929
        return pyopencv_to_generic_vec(obj, value, info);
V
Vadim Pisarevsky 已提交
930
    }
931

932
    static PyObject* from(const std::vector<std::vector<_Tp> >& value)
V
Vadim Pisarevsky 已提交
933 934 935 936 937 938 939
    {
        return pyopencv_from_generic_vec(value);
    }
};

template<> struct pyopencvVecConverter<Mat>
{
940
    static bool to(PyObject* obj, std::vector<Mat>& value, const ArgInfo info)
V
Vadim Pisarevsky 已提交
941
    {
942
        return pyopencv_to_generic_vec(obj, value, info);
V
Vadim Pisarevsky 已提交
943
    }
944

945
    static PyObject* from(const std::vector<Mat>& value)
V
Vadim Pisarevsky 已提交
946 947 948 949
    {
        return pyopencv_from_generic_vec(value);
    }
};
950

V
Vadim Pisarevsky 已提交
951
template<> struct pyopencvVecConverter<KeyPoint>
952
{
953
    static bool to(PyObject* obj, std::vector<KeyPoint>& value, const ArgInfo info)
V
Vadim Pisarevsky 已提交
954
    {
955
        return pyopencv_to_generic_vec(obj, value, info);
V
Vadim Pisarevsky 已提交
956
    }
957

958
    static PyObject* from(const std::vector<KeyPoint>& value)
V
Vadim Pisarevsky 已提交
959 960 961 962 963
    {
        return pyopencv_from_generic_vec(value);
    }
};

964 965
template<> struct pyopencvVecConverter<DMatch>
{
966
    static bool to(PyObject* obj, std::vector<DMatch>& value, const ArgInfo info)
967
    {
968
        return pyopencv_to_generic_vec(obj, value, info);
969
    }
970

971
    static PyObject* from(const std::vector<DMatch>& value)
972 973 974 975 976
    {
        return pyopencv_from_generic_vec(value);
    }
};

977
template<> struct pyopencvVecConverter<String>
V
Vadim Pisarevsky 已提交
978
{
979
    static bool to(PyObject* obj, std::vector<String>& value, const ArgInfo info)
V
Vadim Pisarevsky 已提交
980
    {
981
        return pyopencv_to_generic_vec(obj, value, info);
V
Vadim Pisarevsky 已提交
982
    }
983

984
    static PyObject* from(const std::vector<String>& value)
V
Vadim Pisarevsky 已提交
985 986 987 988 989
    {
        return pyopencv_from_generic_vec(value);
    }
};

990 991
template<>
bool pyopencv_to(PyObject *obj, TermCriteria& dst, const char *name)
992
{
A
Andrey Kamaev 已提交
993
    (void)name;
V
Vadim Pisarevsky 已提交
994 995 996
    if(!obj)
        return true;
    return PyArg_ParseTuple(obj, "iid", &dst.type, &dst.maxCount, &dst.epsilon) > 0;
997 998
}

999 1000
template<>
PyObject* pyopencv_from(const TermCriteria& src)
1001
{
V
Vadim Pisarevsky 已提交
1002
    return Py_BuildValue("(iid)", src.type, src.maxCount, src.epsilon);
1003 1004
}

1005 1006
template<>
bool pyopencv_to(PyObject *obj, RotatedRect& dst, const char *name)
1007
{
A
Andrey Kamaev 已提交
1008
    (void)name;
V
Vadim Pisarevsky 已提交
1009 1010 1011
    if(!obj)
        return true;
    return PyArg_ParseTuple(obj, "(ff)(ff)f", &dst.center.x, &dst.center.y, &dst.size.width, &dst.size.height, &dst.angle) > 0;
1012 1013
}

1014 1015
template<>
PyObject* pyopencv_from(const RotatedRect& src)
1016
{
V
Vadim Pisarevsky 已提交
1017
    return Py_BuildValue("((ff)(ff)f)", src.center.x, src.center.y, src.size.width, src.size.height, src.angle);
1018 1019
}

1020 1021
template<>
PyObject* pyopencv_from(const Moments& m)
1022
{
V
Vadim Pisarevsky 已提交
1023 1024 1025 1026 1027 1028 1029
    return Py_BuildValue("{s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d,s:d}",
                         "m00", m.m00, "m10", m.m10, "m01", m.m01,
                         "m20", m.m20, "m11", m.m11, "m02", m.m02,
                         "m30", m.m30, "m21", m.m21, "m12", m.m12, "m03", m.m03,
                         "mu20", m.mu20, "mu11", m.mu11, "mu02", m.mu02,
                         "mu30", m.mu30, "mu21", m.mu21, "mu12", m.mu12, "mu03", m.mu03,
                         "nu20", m.nu20, "nu11", m.nu11, "nu02", m.nu02,
1030
                         "nu30", m.nu30, "nu21", m.nu21, "nu12", m.nu12, "nu03", m.nu03);
1031 1032
}

1033
#ifdef HAVE_OPENCV_FLANN
1034 1035
template<>
bool pyopencv_to(PyObject *o, cv::flann::IndexParams& p, const char *name)
1036
{
A
Andrey Kamaev 已提交
1037
    (void)name;
1038 1039 1040 1041 1042 1043 1044 1045 1046
    bool ok = true;
    PyObject* key = NULL;
    PyObject* item = NULL;
    Py_ssize_t pos = 0;

    if(PyDict_Check(o)) {
        while(PyDict_Next(o, &pos, &key, &item)) {
            if( !PyString_Check(key) ) {
                ok = false;
1047
                break;
1048 1049
            }

1050
            String k = PyString_AsString(key);
1051
            if( PyString_Check(item) )
1052 1053 1054 1055
            {
                const char* value = PyString_AsString(item);
                p.setString(k, value);
            }
1056
            else if( !!PyBool_Check(item) )
1057
                p.setBool(k, item == Py_True);
1058
            else if( PyInt_Check(item) )
1059 1060 1061 1062 1063 1064 1065
            {
                int value = (int)PyInt_AsLong(item);
                if( strcmp(k.c_str(), "algorithm") == 0 )
                    p.setAlgorithm(value);
                else
                    p.setInt(k, value);
            }
1066
            else if( PyFloat_Check(item) )
1067 1068 1069 1070
            {
                double value = PyFloat_AsDouble(item);
                p.setDouble(k, value);
            }
1071
            else
1072 1073
            {
                ok = false;
1074
                break;
1075
            }
1076 1077
        }
    }
1078

1079
    return ok && !PyErr_Occurred();
1080 1081
}

1082 1083 1084 1085 1086
template<>
bool pyopencv_to(PyObject* obj, cv::flann::SearchParams & value, const char * name)
{
    return pyopencv_to<cv::flann::IndexParams>(obj, value, name);
}
1087
#endif
1088

1089 1090
template <typename T>
bool pyopencv_to(PyObject *o, Ptr<T>& p, const char *name)
1091
{
1092
    p = makePtr<T>();
1093 1094 1095
    return pyopencv_to(o, *p, name);
}

1096
#ifdef HAVE_OPENCV_FLANN
1097 1098
template<>
bool pyopencv_to(PyObject *o, cvflann::flann_distance_t& dist, const char *name)
1099
{
1100
    int d = (int)dist;
1101
    bool ok = pyopencv_to(o, d, name);
1102
    dist = (cvflann::flann_distance_t)d;
1103 1104
    return ok;
}
1105
#endif
1106

A
Andrey Kamaev 已提交
1107 1108 1109 1110

////////////////////////////////////////////////////////////////////////////////////////////////////
// TODO: REMOVE used only by ml wrapper

1111 1112
template<>
bool pyopencv_to(PyObject *obj, CvTermCriteria& dst, const char *name)
A
Andrey Kamaev 已提交
1113 1114 1115 1116 1117 1118 1119
{
    (void)name;
    if(!obj)
        return true;
    return PyArg_ParseTuple(obj, "iid", &dst.type, &dst.max_iter, &dst.epsilon) > 0;
}

1120 1121
template<>
bool pyopencv_to(PyObject* obj, CvSlice& r, const char* name)
A
Andrey Kamaev 已提交
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133
{
    (void)name;
    if(!obj || obj == Py_None)
        return true;
    if(PyObject_Size(obj) == 0)
    {
        r = CV_WHOLE_SEQ;
        return true;
    }
    return PyArg_ParseTuple(obj, "ii", &r.start_index, &r.end_index) > 0;
}

1134 1135 1136 1137 1138 1139
////////////////////////////////////////////////////////////////////////////////////////////////////

static void OnMouse(int event, int x, int y, int flags, void* param)
{
    PyGILState_STATE gstate;
    gstate = PyGILState_Ensure();
1140

1141 1142
    PyObject *o = (PyObject*)param;
    PyObject *args = Py_BuildValue("iiiiO", event, x, y, flags, PyTuple_GetItem(o, 1));
1143

1144 1145 1146 1147 1148 1149 1150 1151 1152
    PyObject *r = PyObject_Call(PyTuple_GetItem(o, 0), args, NULL);
    if (r == NULL)
        PyErr_Print();
    else
        Py_DECREF(r);
    Py_DECREF(args);
    PyGILState_Release(gstate);
}

1153
#ifdef HAVE_OPENCV_HIGHGUI
A
Andrey Kamaev 已提交
1154
static PyObject *pycvSetMouseCallback(PyObject*, PyObject *args, PyObject *kw)
1155 1156 1157 1158 1159
{
    const char *keywords[] = { "window_name", "on_mouse", "param", NULL };
    char* name;
    PyObject *on_mouse;
    PyObject *param = NULL;
1160

1161 1162 1163 1164 1165 1166 1167 1168 1169
    if (!PyArg_ParseTupleAndKeywords(args, kw, "sO|O", (char**)keywords, &name, &on_mouse, &param))
        return NULL;
    if (!PyCallable_Check(on_mouse)) {
        PyErr_SetString(PyExc_TypeError, "on_mouse must be callable");
        return NULL;
    }
    if (param == NULL) {
        param = Py_None;
    }
A
Andrey Kamaev 已提交
1170
    ERRWRAP2(setMouseCallback(name, OnMouse, Py_BuildValue("OO", on_mouse, param)));
1171 1172
    Py_RETURN_NONE;
}
1173
#endif
1174

1175
static void OnChange(int pos, void *param)
1176 1177 1178
{
    PyGILState_STATE gstate;
    gstate = PyGILState_Ensure();
1179

1180 1181 1182 1183 1184 1185 1186 1187 1188
    PyObject *o = (PyObject*)param;
    PyObject *args = Py_BuildValue("(i)", pos);
    PyObject *r = PyObject_Call(PyTuple_GetItem(o, 0), args, NULL);
    if (r == NULL)
        PyErr_Print();
    Py_DECREF(args);
    PyGILState_Release(gstate);
}

1189
#ifdef HAVE_OPENCV_HIGHGUI
A
Andrey Kamaev 已提交
1190
static PyObject *pycvCreateTrackbar(PyObject*, PyObject *args)
1191 1192 1193 1194 1195 1196
{
    PyObject *on_change;
    char* trackbar_name;
    char* window_name;
    int *value = new int;
    int count;
1197

1198 1199 1200 1201 1202 1203
    if (!PyArg_ParseTuple(args, "ssiiO", &trackbar_name, &window_name, value, &count, &on_change))
        return NULL;
    if (!PyCallable_Check(on_change)) {
        PyErr_SetString(PyExc_TypeError, "on_change must be callable");
        return NULL;
    }
A
Andrey Kamaev 已提交
1204
    ERRWRAP2(createTrackbar(trackbar_name, window_name, value, count, OnChange, Py_BuildValue("OO", on_change, Py_None)));
1205 1206
    Py_RETURN_NONE;
}
1207
#endif
1208 1209 1210

///////////////////////////////////////////////////////////////////////////////////////

1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221
static int convert_to_char(PyObject *o, char *dst, const char *name = "no_name")
{
  if (PyString_Check(o) && PyString_Size(o) == 1) {
    *dst = PyString_AsString(o)[0];
    return 1;
  } else {
    (*dst) = 0;
    return failmsg("Expected single character string for argument '%s'", name);
  }
}

1222 1223 1224
#if PY_MAJOR_VERSION >= 3
#define MKTYPE2(NAME) pyopencv_##NAME##_specials(); if (!to_ok(&pyopencv_##NAME##_Type)) return NULL;
#else
1225
#define MKTYPE2(NAME) pyopencv_##NAME##_specials(); if (!to_ok(&pyopencv_##NAME##_Type)) return
1226
#endif
1227

A
Andrey Kamaev 已提交
1228 1229 1230 1231 1232
#ifdef __GNUC__
#  pragma GCC diagnostic ignored "-Wunused-parameter"
#  pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#endif

1233 1234 1235
#include "pyopencv_generated_types.h"
#include "pyopencv_generated_funcs.h"

A
Alexander Mordvintsev 已提交
1236
static PyMethodDef special_methods[] = {
1237
#ifdef HAVE_OPENCV_HIGHGUI
1238
  {"createTrackbar", pycvCreateTrackbar, METH_VARARGS, "createTrackbar(trackbarName, windowName, value, count, onChange) -> None"},
1239
  {"setMouseCallback", (PyCFunction)pycvSetMouseCallback, METH_VARARGS | METH_KEYWORDS, "setMouseCallback(windowName, onMouse [, param]) -> None"},
1240
#endif
1241 1242 1243 1244 1245 1246
  {NULL, NULL},
};

/************************************************************************/
/* Module init */

1247 1248 1249 1250 1251 1252 1253
struct ConstDef
{
    const char * name;
    long val;
};

static void init_submodule(PyObject * root, const char * name, PyMethodDef * methods, ConstDef * consts)
1254
{
1255
  // traverse and create nested submodules
1256
  std::string s = name;
1257 1258
  size_t i = s.find('.');
  while (i < s.length() && i != std::string::npos)
1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273
  {
    size_t j = s.find('.', i);
    if (j == std::string::npos)
        j = s.length();
    std::string short_name = s.substr(i, j-i);
    std::string full_name = s.substr(0, j);
    i = j+1;

    PyObject * d = PyModule_GetDict(root);
    PyObject * submod = PyDict_GetItemString(d, short_name.c_str());
    if (submod == NULL)
    {
        submod = PyImport_AddModule(full_name.c_str());
        PyDict_SetItemString(d, short_name.c_str(), submod);
    }
A
Adam Greig 已提交
1274 1275 1276

    if (short_name != "")
        root = submod;
1277 1278
  }

1279
  // populate module's dict
1280 1281 1282 1283 1284 1285 1286
  PyObject * d = PyModule_GetDict(root);
  for (PyMethodDef * m = methods; m->ml_name != NULL; ++m)
  {
    PyObject * method_obj = PyCFunction_NewEx(m, NULL, NULL);
    PyDict_SetItemString(d, m->ml_name, method_obj);
    Py_DECREF(method_obj);
  }
1287 1288 1289 1290 1291
  for (ConstDef * c = consts; c->name != NULL; ++c)
  {
    PyDict_SetItemString(d, c->name, PyInt_FromLong(c->val));
  }

1292 1293 1294 1295
}

#include "pyopencv_generated_ns_reg.h"

1296 1297 1298 1299 1300 1301 1302 1303
static int to_ok(PyTypeObject *to)
{
  to->tp_alloc = PyType_GenericAlloc;
  to->tp_new = PyType_GenericNew;
  to->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
  return (PyType_Ready(to) == 0);
}

1304 1305 1306 1307 1308 1309 1310 1311 1312 1313

#if PY_MAJOR_VERSION >= 3
extern "C" CV_EXPORTS PyObject* PyInit_cv2();
static struct PyModuleDef cv2_moduledef =
{
    PyModuleDef_HEAD_INIT,
    MODULESTR,
    "Python wrapper for OpenCV.",
    -1,     /* size of per-interpreter state of the module,
               or -1 if the module keeps state in global variables. */
A
Alexander Mordvintsev 已提交
1314
    special_methods
1315 1316 1317 1318
};

PyObject* PyInit_cv2()
#else
1319
extern "C" CV_EXPORTS void initcv2();
1320 1321

void initcv2()
1322
#endif
1323
{
A
Andrey Kamaev 已提交
1324
  import_array();
1325

1326 1327
#include "pyopencv_generated_type_reg.h"

1328 1329 1330
#if PY_MAJOR_VERSION >= 3
  PyObject* m = PyModule_Create(&cv2_moduledef);
#else
A
Alexander Mordvintsev 已提交
1331
  PyObject* m = Py_InitModule(MODULESTR, special_methods);
1332
#endif
1333 1334
  init_submodules(m); // from "pyopencv_generated_ns_reg.h"

1335 1336
  PyObject* d = PyModule_GetDict(m);

V
Vadim Pisarevsky 已提交
1337
  PyDict_SetItemString(d, "__version__", PyString_FromString(CV_VERSION));
1338 1339 1340

  opencv_error = PyErr_NewException((char*)MODULESTR".error", NULL, NULL);
  PyDict_SetItemString(d, "error", opencv_error);
1341

1342
#define PUBLISH(I) PyDict_SetItemString(d, #I, PyInt_FromLong(I))
A
Andrey Kamaev 已提交
1343
//#define PUBLISHU(I) PyDict_SetItemString(d, #I, PyLong_FromUnsignedLong(I))
1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380
#define PUBLISH2(I, value) PyDict_SetItemString(d, #I, PyLong_FromLong(value))

  PUBLISH(CV_8U);
  PUBLISH(CV_8UC1);
  PUBLISH(CV_8UC2);
  PUBLISH(CV_8UC3);
  PUBLISH(CV_8UC4);
  PUBLISH(CV_8S);
  PUBLISH(CV_8SC1);
  PUBLISH(CV_8SC2);
  PUBLISH(CV_8SC3);
  PUBLISH(CV_8SC4);
  PUBLISH(CV_16U);
  PUBLISH(CV_16UC1);
  PUBLISH(CV_16UC2);
  PUBLISH(CV_16UC3);
  PUBLISH(CV_16UC4);
  PUBLISH(CV_16S);
  PUBLISH(CV_16SC1);
  PUBLISH(CV_16SC2);
  PUBLISH(CV_16SC3);
  PUBLISH(CV_16SC4);
  PUBLISH(CV_32S);
  PUBLISH(CV_32SC1);
  PUBLISH(CV_32SC2);
  PUBLISH(CV_32SC3);
  PUBLISH(CV_32SC4);
  PUBLISH(CV_32F);
  PUBLISH(CV_32FC1);
  PUBLISH(CV_32FC2);
  PUBLISH(CV_32FC3);
  PUBLISH(CV_32FC4);
  PUBLISH(CV_64F);
  PUBLISH(CV_64FC1);
  PUBLISH(CV_64FC2);
  PUBLISH(CV_64FC3);
  PUBLISH(CV_64FC4);
1381

1382 1383 1384
#if PY_MAJOR_VERSION >= 3
    return m;
#endif
A
Andrey Kamaev 已提交
1385
}