Boost Python wrapper for a c++ class that uses Opencv 2.3
I am trying to create a python library from a class which uses opencv 2.3. I want to be able to pass numpy array's into the class where they will be converted into cv::Mat's processed then converted back to numpy array's and returned. Here is a simple test class I am working on to get this working before wrapping my own class. Currently I am just trying to receive a numpy array concert to a cv::Mat, process it and then write it to file. After this is working I will work on returning the processed array to python. Here is the simple class: foo.h : #include <opencv2/core/core.hpp> class Foo { public: Foo(); ~Foo(); cv::Mat image; void bar( cv::Mat in ); }; foo.cpp : #include "foo.h" Foo::Foo(){} Foo::~Foo(){} void Foo::bar( cv::Mat in) { image = in; cv::Canny( image, image, 50, 100 ); cv::imwrite("image.png", image); } And here is where I have attempted to wrap this class using boost::python (I am using code from the opencv source for the the numpy to mat conversion) wrap_foo.cpp #include <boost/python.hpp> #include <numpy/arrayobject.h> #include <opencv2/core/core.hpp> #include "foo.h" using namespace cv; namespace bp = boost::python; //// Wrapper Functions void bar(Foo& f, bp::object np); //// Converter Functions cv::Mat convertNumpy2Mat(bp::object np); //// Wrapper Functions void bar(Foo& f, bp::object np) { Mat img = convertNumpy2Mat(np); f.bar(img); return; } //// Boost Python Class BOOST_PYTHON_MODULE(lib) { bp::class_<Foo>("Foo") .def("bar", bar) ; } //// Converters cv::Mat convertNumpy2Mat(bp::object np) { Mat m; numpy_to_mat(np.ptr(),m); return m; } The numpy_to_mat function is from the opencv source (modules/python/src2/cv2.cpp). The full file has the function below what I wrote above. This code compiles with bjam just fine but the when I import into python it crashes. The error is this: libFoo.so: undefined symbol: _ZN2cv3Mat10deallocateEv. I have tried a number of different things but I can't get this to work.
On 09/21/2011 09:31 AM, Kevin Hughes wrote:
I am trying to create a python library from a class which uses opencv 2.3. I want to be able to pass numpy array's into the class where they will be converted into cv::Mat's processed then converted back to numpy array's and returned.
Here is a simple test class I am working on to get this working before wrapping my own class. Currently I am just trying to receive a numpy array concert to a cv::Mat, process it and then write it to file. After this is working I will work on returning the processed array to python.
Without digging too deeply or getting into possibly better solutions, try adding: import_array(); inside your BOOST_PYTHON_MODULE block. Or maybe there's some opencv initialization function you need to call that will do that for you. The NumPy C-API (which I assume the numpy_to_mat function uses internally) needs to be initialized when your module is imported, or you'll get segfaults. The above call to import_array() is how you'd do it if you were using the NumPy C-API headers directly. In any case, you need to make sure it gets called somehow. HTH Jim Bosch
Thanks for the reply, I tried adding import_array(); to my BOOST_PYTHON_MODULE block but I still got an error when importing my library into python, the same same error I mentioned above. On Wed, Sep 21, 2011 at 9:43 AM, Jim Bosch <talljimbo@gmail.com> wrote:
On 09/21/2011 09:31 AM, Kevin Hughes wrote:
I am trying to create a python library from a class which uses opencv 2.3. I want to be able to pass numpy array's into the class where they will be converted into cv::Mat's processed then converted back to numpy array's and returned.
Here is a simple test class I am working on to get this working before wrapping my own class. Currently I am just trying to receive a numpy array concert to a cv::Mat, process it and then write it to file. After this is working I will work on returning the processed array to python.
Without digging too deeply or getting into possibly better solutions, try adding:
import_array();
inside your BOOST_PYTHON_MODULE block. Or maybe there's some opencv initialization function you need to call that will do that for you. The NumPy C-API (which I assume the numpy_to_mat function uses internally) needs to be initialized when your module is imported, or you'll get segfaults. The above call to import_array() is how you'd do it if you were using the NumPy C-API headers directly. In any case, you need to make sure it gets called somehow.
HTH
Jim Bosch ______________________________**_________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/**mailman/listinfo/cplusplus-sig<http://mail.python.org/mailman/listinfo/cplusplus-sig>
On 09/21/2011 10:25 AM, Kevin Hughes wrote:
Thanks for the reply, I tried adding import_array(); to my BOOST_PYTHON_MODULE block but I still got an error when importing my library into python, the same same error I mentioned above.
Does it actually crash Python, or just fail to import the module? It looks like a link error, and that usually just causes the module to fail to import. And that would suggest looking at your build system for whether you've linked properly against the opencv libs. Jim
Sorry it just fails to import, what should my JamRoot file look like to include my opencv libs? I am very new to boost python. On Wed, Sep 21, 2011 at 10:41 AM, Jim Bosch <talljimbo@gmail.com> wrote:
On 09/21/2011 10:25 AM, Kevin Hughes wrote:
Thanks for the reply, I tried adding import_array(); to my BOOST_PYTHON_MODULE block but I still got an error when importing my library into python, the same same error I mentioned above.
Does it actually crash Python, or just fail to import the module? It looks like a link error, and that usually just causes the module to fail to import. And that would suggest looking at your build system for whether you've linked properly against the opencv libs.
Jim
______________________________**_________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/**mailman/listinfo/cplusplus-sig<http://mail.python.org/mailman/listinfo/cplusplus-sig>
Here is the JamRoot file I have been using: using python ; # Specify that the boost-python library exists under the name # boost_python. That is, because the library was installed at the # standard search path as /usr/lib/libboost_python.so, bjam will find # it automatically. No need to specify the absolute path. # lib libboost_python : : <name>boost_python-mt ; lib libboost_python : : <name>boost_python ; lib libboost_date_time : : <name>boost_date_time ; # Set up the project-wide requirements that everything uses the # boost_python library. project : requirements <library>libboost_python ; # Declare the extension modules. You can specify multiple # source files after the colon separated by spaces. python-extension libFoo : wrap_foo.cpp ; On Wed, Sep 21, 2011 at 11:12 AM, Kevin Hughes <k.hughes@queensu.ca> wrote:
Sorry it just fails to import, what should my JamRoot file look like to include my opencv libs? I am very new to boost python.
On Wed, Sep 21, 2011 at 10:41 AM, Jim Bosch <talljimbo@gmail.com> wrote:
On 09/21/2011 10:25 AM, Kevin Hughes wrote:
Thanks for the reply, I tried adding import_array(); to my BOOST_PYTHON_MODULE block but I still got an error when importing my library into python, the same same error I mentioned above.
Does it actually crash Python, or just fail to import the module? It looks like a link error, and that usually just causes the module to fail to import. And that would suggest looking at your build system for whether you've linked properly against the opencv libs.
Jim
______________________________**_________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/**mailman/listinfo/cplusplus-sig<http://mail.python.org/mailman/listinfo/cplusplus-sig>
On 09/21/2011 11:13 AM, Kevin Hughes wrote:
Here is the JamRoot file I have been using:
using python ;
# Specify that the boost-python library exists under the name # boost_python. That is, because the library was installed at the # standard search path as /usr/lib/libboost_python.so, bjam will find # it automatically. No need to specify the absolute path. # lib libboost_python : : <name>boost_python-mt ; lib libboost_python : : <name>boost_python ; lib libboost_date_time : : <name>boost_date_time ;
# Set up the project-wide requirements that everything uses the # boost_python library. project : requirements <library>libboost_python ;
# Declare the extension modules. You can specify multiple # source files after the colon separated by spaces. python-extension libFoo : wrap_foo.cpp ;
As it turns out, I've never used bjam, except to build Boost itself. I suspect you need another "requirements" line with the opencv libraries, but I'm not sure of the syntax. Hopefully someone else can help you with that. There's no requirement that Boost.Python projects use bjam, however, and if you're already more comfortable with another build system you might find it easier to use that. Python's own distutils can work well for simple modules as well. Jim
participants (2)
-
Jim Bosch -
Kevin Hughes