Boost Python wrapper for a c++ class that uses Opencv 2.3

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Boost Python wrapper for a c++ class that uses Opencv 2.3

Kevin Hughes

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.



_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|

Re: Boost Python wrapper for a c++ class that uses Opencv 2.3

Jim Bosch-2
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
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|

Re: Boost Python wrapper for a c++ class that uses Opencv 2.3

Kevin Hughes
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 <[hidden email]> 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
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig


_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|

Re: Boost Python wrapper for a c++ class that uses Opencv 2.3

Jim Bosch-2
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
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|

Re: Boost Python wrapper for a c++ class that uses Opencv 2.3

Kevin Hughes
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 <[hidden email]> 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
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig


_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|

Re: Boost Python wrapper for a c++ class that uses Opencv 2.3

Kevin Hughes
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 <[hidden email]> 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 <[hidden email]> 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
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig



_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|

Re: Boost Python wrapper for a c++ class that uses Opencv 2.3

Jim Bosch-2
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
_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig