使用BOOST.python从C ++将结构返回到Python [英] Return a structure to Python from C++ using BOOST.python

查看:757
本文介绍了使用BOOST.python从C ++将结构返回到Python的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个C ++方法,从中我需要返回一个结构到Python。
我已经能够使用BOOST按照 mat 从Python发送到C ++。 com / questions / 19136944 / call-c-opencv-functions-from-python-send-a-cv-mat-to-c-dll-which-is-usi> link



现在我需要走另一条路;从C ++返回到Python,然后在Python中访问该结构。可以吗?



任何样品或参考链接都是好的。

解决方案

您可以使用另一个函数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);
}

然后Boost Python包装器将如下所示:

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

return boostPyObjFrame;
}

请看这个链接: https://wiki.python.org/moin/boost.python/handle ,以确保您使用适当的boost :: python :: handle<>函数。



如果你需要不需要返回一个cv :: Mat但是你可以考虑不同的数据使用boost :: python :: list或boost :: python :: dict。例如,如果你想返回一个2D点的向量到Python,你可以这样做:

  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 [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
}



最后Boost Python包装器:

  BOOST_PYTHON_MODULE(myWrapper)
{
//只有在返回array(cv :: Mat)时才需要
import_array();
boost :: python :: converter :: registry :: insert(& extract_pyarray,type_id< PyArrayObject>());

def toPython(toPython,& toPython);
}



我没有测试这个特定的解决方案,但它应该原则上工作。 / p>

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.

解决方案

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.

这篇关于使用BOOST.python从C ++将结构返回到Python的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆