Return a structure to Python from C++ using BOOST.python

情到浓时终转凉″ 提交于 2019-12-10 09:24:37

问题


I have written a C++ method from which I need to return a structure to Python. I'm already able to send an OpenCV mat from Python to C++ using BOOST following the method described in this link.

Now I need to go the other way; return from C++ to Python, and then access that structure in Python. Can it be done?

Any samples or reference links would be good. I have tried googling before posting this question and I couldn't get any samples or explanation links.


回答1:


You can use another function from modules/python/src2/cv2.cpp:

PyObject* pyopencv_from(const cv::Mat& m)
{
  if( !m.data )
      Py_RETURN_NONE;
  cv::Mat temp, *p = (cv::Mat*)&m;
  if(!p->refcount || p->allocator != &g_numpyAllocator)
  {
      temp.allocator = &g_numpyAllocator;
      m.copyTo(temp);
      p = &temp;
  }
  p->addref();
  return pyObjectFromRefcount(p->refcount);
}

Then the Boost Python wrapper will look like:

boost::python::object toPython( const cv::Mat &frame )
{
    PyObject* pyObjFrame = pyopencv_from( frame );
    boost::python::object boostPyObjFrame(boost::python::handle<>((PyObject*)pyObjFrame));

    return boostPyObjFrame;
}

Please have a look at this link: https://wiki.python.org/moin/boost.python/handle to make sure that you use the appropriate boost::python::handle<> function for your case.

If you need don't need to return a cv::Mat but different data you might consider to use boost::python::list or boost::python::dict. For example if you want to return a vectors of 2D points to Python you can do something like:

boost::python::dict toPython( std::vector<cv::Point> newPoints, std::vector<cv::Point> oldPoints )
{
    boost::python::dict pointsDict;
    boost::python::list oldPointsList;
    boost::python::list newPointsList;

    for( size_t ii = 0; ii < oldPoints.size( ); ++ii )
    {
        oldPointsList.append( boost::python::make_tuple( oldPoints[ii].x, oldPoints[ii].y ) );
    }

    for( size_t ii = 0; ii < newPoints.size( ); ++ii )
    {
        newPointsList.append( boost::python::make_tuple( newPoints[ii].x, newPoints[ii].y ) );
    }

    pointsDict["oldPoints"] = oldPointsList;
    pointsDict["newPoints"] = newPointsList;
    return pointsDict
}

Finally the Boost Python wrapper:

BOOST_PYTHON_MODULE( myWrapper )
{
    // necessary only if array (cv::Mat) is returned
    import_array();
    boost::python::converter::registry::insert( &extract_pyarray, type_id<PyArrayObject>());

    def toPython("toPython", &toPython);
}

I haven't tested this specific solution but it should work in principle.




回答2:


This might be a little too late, but take a look at https://github.com/spillai/numpy-opencv-converter



来源:https://stackoverflow.com/questions/19185574/return-a-structure-to-python-from-c-using-boost-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!