问题
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