понедельник, 28 февраля 2011 г.

cv.CamShift

У меня работает OpenCV 2.2, а не какая-нибудь OpenCV 2.1! Но имеющийся в комплекте пример "camshift.py" не работает. Не работает и любой вызов функции cv.CamShift. Возникает ошибка внутри библиотеки OpenCV из-за каких-то проблем в параметрах. Пришлось делать этот вызов самостоятельно.


Вот выкладываю, чтоб не потерялось.


#include "Python.h"
#include "cv.h"
#define MODULE_NAME "pycamshift"
#define ERROR_NAME "PyCamShiftError"
#define INIT_FUNC_NAME initpycamshift

static PyObject *my_error;

struct Py_IplImage
{
    PyObject_HEAD
    IplImage *a;
    PyObject *data;
    size_t offset;
};

static PyObject* camshift(PyObject *self, PyObject *args)
{
    PyObject* probImageObj;
    PyObject* py_rect;
    PyObject* py_crit;
    int type;
    int max_iter;
    double epsilon;
    if(!PyArg_ParseTuple(
        args,
        "OOO",
        &probImageObj,
        &py_rect,
        &py_crit))
    {
        PyErr_SetString(my_error, "wrong parameters list");
        return NULL;
    }
    CvRect rect;
    Py_ssize_t N = PySequence_Size(py_rect);
    if(N != 4)
    {
        PyErr_SetString(
            my_error,
            "second parameter must be 4-tuple of integers");
            return NULL;
    }
    rect.x = PyInt_AsLong(PySequence_GetItem(py_rect, 0));
    rect.y = PyInt_AsLong(PySequence_GetItem(py_rect, 1));
    rect.width = PyInt_AsLong(PySequence_GetItem(py_rect, 2));
    rect.height = PyInt_AsLong(PySequence_GetItem(py_rect, 3));

    CvTermCriteria crit;
    N = PySequence_Size(py_crit);
    if(N != 3)
    {
        PyErr_SetString(
            my_error,
            "the third parameter must be "
                "3-tuple of two integers and double");
            return NULL;
    }
    crit.type = PyInt_AsLong(PySequence_GetItem(py_crit, 0));
    crit.max_iter = PyInt_AsLong(PySequence_GetItem(py_crit, 1));
    crit.epsilon = PyInt_AsLong(PySequence_GetItem(py_crit, 2));

    Py_IplImage *image = reinterpret_cast(probImageObj);
    CvConnectedComp comp;
    CvBox2D box;
    cvCamShift(image->a, rect, crit, &comp, &box);
    return Py_BuildValue(
        "(d(dddd)(iiii))((dd)(dd)d)", 
        comp.area,
        comp.value.val[0],
        comp.value.val[1],
        comp.value.val[2],
        comp.value.val[3],
        comp.rect.x,
        comp.rect.y,
        comp.rect.width,
        comp.rect.height,
        box.center.x, 
        box.center.y, 
        box.size.width, 
        box.size.height, 
        box.angle);
}

static PyMethodDef methods[] = 
{
    {"camshift", camshift, METH_VARARGS, "cvCamShift binding"},
    {NULL, NULL, 0, NULL} /* Sentinel */
};

PyMODINIT_FUNC INIT_FUNC_NAME(void)
{
    PyObject *m = Py_InitModule(MODULE_NAME, methods);
    if(m == NULL)
        return;
    my_error = PyErr_NewException(
        MODULE_NAME"."ERROR_NAME,
        NULL,
        NULL);
    Py_INCREF(my_error);
    PyModule_AddObject(m, ERROR_NAME, my_error);
}

Комментариев нет:

Отправить комментарий