Chinmay Shah
Chinmay Shah

Reputation: 247

How OpenCV determines python bindings for functions with different arguments?

In OpenCV Scene Text Detection, we have two C++ functions, with different arguments

void cv::text::detectRegions    (   InputArray  image,
const Ptr< ERFilter > &     er_filter1,
const Ptr< ERFilter > &     er_filter2,
std::vector< std::vector< Point > > &   regions 
)   

void cv::text::detectRegions    (   InputArray  image,
const Ptr< ERFilter > &     er_filter1,
const Ptr< ERFilter > &     er_filter2,
std::vector< Rect > &   groups_rects,
int     method = ERGROUPING_ORIENTATION_HORIZ,
const String &  filename = String(),
float   minProbability = (float) 0.5 
)   

But it's corresponding python function is:

regions= cv.text.detectRegions(image, er_filter1, er_filter2)

How does this python binding decide which C++ function to execute?

Upvotes: 0

Views: 439

Answers (2)

zindarod
zindarod

Reputation: 6468

The following is the Python code that OpenCV created on my machine for detectRegions function. The Python function signature is: cv2.text.detectRegions(image, er_filter1, er_filter2[, method[, filename[, minProbability]]]) -> groups_rects.

If you look at the code closely, you'll see that two different versions of cv::text::detectRegions is being called based on the number and type of arguments you provide.

static PyObject* pyopencv_cv_text_detectRegions(PyObject* , PyObject* args, PyObject* kw)
{
    using namespace cv::text;

    {
    PyObject* pyobj_image = NULL;
    Mat image;
    PyObject* pyobj_er_filter1 = NULL;
    Ptr<ERFilter> er_filter1;
    PyObject* pyobj_er_filter2 = NULL;
    Ptr<ERFilter> er_filter2;
    vector_vector_Point regions;

    const char* keywords[] = { "image", "er_filter1", "er_filter2", NULL };
    if( PyArg_ParseTupleAndKeywords(args, kw, "OOO:detectRegions", (char**)keywords, &pyobj_image, &pyobj_er_filter1, &pyobj_er_filter2) &&
        pyopencv_to(pyobj_image, image, ArgInfo("image", 0)) &&
        pyopencv_to(pyobj_er_filter1, er_filter1, ArgInfo("er_filter1", 0)) &&
        pyopencv_to(pyobj_er_filter2, er_filter2, ArgInfo("er_filter2", 0)) )
    {
        ERRWRAP2(cv::text::detectRegions(image, er_filter1, er_filter2, regions));
        return pyopencv_from(regions);
    }
    }
    PyErr_Clear();

    {
    PyObject* pyobj_image = NULL;
    UMat image;
    PyObject* pyobj_er_filter1 = NULL;
    Ptr<ERFilter> er_filter1;
    PyObject* pyobj_er_filter2 = NULL;
    Ptr<ERFilter> er_filter2;
    vector_vector_Point regions;

    const char* keywords[] = { "image", "er_filter1", "er_filter2", NULL };
    if( PyArg_ParseTupleAndKeywords(args, kw, "OOO:detectRegions", (char**)keywords, &pyobj_image, &pyobj_er_filter1, &pyobj_er_filter2) &&
        pyopencv_to(pyobj_image, image, ArgInfo("image", 0)) &&
        pyopencv_to(pyobj_er_filter1, er_filter1, ArgInfo("er_filter1", 0)) &&
        pyopencv_to(pyobj_er_filter2, er_filter2, ArgInfo("er_filter2", 0)) )
    {
        ERRWRAP2(cv::text::detectRegions(image, er_filter1, er_filter2, regions));
        return pyopencv_from(regions);
    }
    }
    PyErr_Clear();

    {
    PyObject* pyobj_image = NULL;
    Mat image;
    PyObject* pyobj_er_filter1 = NULL;
    Ptr<ERFilter> er_filter1;
    PyObject* pyobj_er_filter2 = NULL;
    Ptr<ERFilter> er_filter2;
    vector_Rect groups_rects;
    int method=ERGROUPING_ORIENTATION_HORIZ;
    PyObject* pyobj_filename = NULL;
    String filename;
    float minProbability=(float)0.5;

    const char* keywords[] = { "image", "er_filter1", "er_filter2", "method", "filename", "minProbability", NULL };
    if( PyArg_ParseTupleAndKeywords(args, kw, "OOO|iOf:detectRegions", (char**)keywords, &pyobj_image, &pyobj_er_filter1, &pyobj_er_filter2, &method, &pyobj_filename, &minProbability) &&
        pyopencv_to(pyobj_image, image, ArgInfo("image", 0)) &&
        pyopencv_to(pyobj_er_filter1, er_filter1, ArgInfo("er_filter1", 0)) &&
        pyopencv_to(pyobj_er_filter2, er_filter2, ArgInfo("er_filter2", 0)) &&
        pyopencv_to(pyobj_filename, filename, ArgInfo("filename", 0)) )
    {
        ERRWRAP2(cv::text::detectRegions(image, er_filter1, er_filter2, groups_rects, method, filename, minProbability));
        return pyopencv_from(groups_rects);
    }
    }
    PyErr_Clear();

    {
    PyObject* pyobj_image = NULL;
    UMat image;
    PyObject* pyobj_er_filter1 = NULL;
    Ptr<ERFilter> er_filter1;
    PyObject* pyobj_er_filter2 = NULL;
    Ptr<ERFilter> er_filter2;
    vector_Rect groups_rects;
    int method=ERGROUPING_ORIENTATION_HORIZ;
    PyObject* pyobj_filename = NULL;
    String filename;
    float minProbability=(float)0.5;

    const char* keywords[] = { "image", "er_filter1", "er_filter2", "method", "filename", "minProbability", NULL };
    if( PyArg_ParseTupleAndKeywords(args, kw, "OOO|iOf:detectRegions", (char**)keywords, &pyobj_image, &pyobj_er_filter1, &pyobj_er_filter2, &method, &pyobj_filename, &minProbability) &&
        pyopencv_to(pyobj_image, image, ArgInfo("image", 0)) &&
        pyopencv_to(pyobj_er_filter1, er_filter1, ArgInfo("er_filter1", 0)) &&
        pyopencv_to(pyobj_er_filter2, er_filter2, ArgInfo("er_filter2", 0)) &&
        pyopencv_to(pyobj_filename, filename, ArgInfo("filename", 0)) )
    {
        ERRWRAP2(cv::text::detectRegions(image, er_filter1, er_filter2, groups_rects, method, filename, minProbability));
        return pyopencv_from(groups_rects);
    }
    }

    return NULL;
}

Upvotes: 0

Osama AlKoky
Osama AlKoky

Reputation: 214

The binding happens manually so you need to check the code for python binding in opencv to know which function is used. https://docs.opencv.org/3.4/da/d49/tutorial_py_bindings_basics.html

Upvotes: 1

Related Questions