为我的算法创建一个使用Opencv 2.3的Python封装

5 投票
1 回答
1317 浏览
提问于 2025-04-17 02:27

我想把一个用C++写的类包装起来,这个类实现了我用OpenCV 2.3写的算法。我知道OpenCV本身有Python的包装,但我需要的是把我自己的代码包装起来,这样我就可以在Python中调用它。这样做是有道理的,因为我算法的底层是快速编译的C++代码,我可以自由地从Python调用它,并围绕它构建一个系统。

我的类其实很简单,主要有4个方法:

  void train( std::vector<cv::Mat> );
  void save();
  void load();
  bool detect( cv::Mat );

这基本上就是我需要包装的大部分内容。问题是我不知道该怎么做。我查过ctypes、swig、boost python和pyplusplus,但到现在为止都没有成功。

我一直在遇到如何包装OpenCV对象cv::Mat的问题。从Python中我会使用numpy数组,所以我知道我需要将numpy数组转换为cv::Mat的代码,并且我还需要注册这个转换。

我觉得应该有人在某个时候尝试过类似的事情,如果你能帮我一下,我会非常感激。


再重申一下目标:把我使用OpenCV的C++类包装成一个Python库,这样我就可以在Python中使用我的算法。

我觉得我对转换的部分有些了解了(在OpenCV源代码的帮助下),但在Python中还是无法工作。

好吧,我一直在使用上面帖子中链接的代码(从numpy到cv::Mat的转换),但仍然遇到问题。我打算把我的代码发出来,希望比我更懂的人能帮我。

例如,这里有一个简单的类:

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);
  }

这是我尝试使用boost::python和上面链接中的一些代码来包装这个类的地方:

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

numpy_to_mat函数来自pano_cv库,但通过玩弄官方的OpenCV源代码,我知道这个函数在某种程度上也是存在的。完整的文件中有我上面写的函数。这个代码用bjam编译得很好,但当我在Python中导入时却崩溃了。错误信息是:libFoo.so: undefined symbol: _ZN2cv3Mat10deallocateEv。我尝试了很多不同的方法,但就是无法让它工作。

非常感谢任何帮助。

1 个回答

1

我在谷歌上找到了一些代码,这段代码可以把numpy数组转换成C++中的cv::mat,使用了boost::python库:

链接

撰写回答