【问题标题】:How do you wrap C++ OpenCV code with Boost::Python?如何用 Boost::Python 封装 C++ OpenCV 代码?
【发布时间】:2013-01-26 07:39:43
【问题描述】:

我想用boost::python 包装我的 C++ OpenCV 代码,为了学习如何做,我尝试了一个玩具示例,其中

  • 我使用Boost.Numpy 项目为我提供boost::numpy::ndarray

  • 要包装的 C++ 函数 square() 采用 boost::numpy::ndarray 并通过对其中的每个元素进行平方来对其进行修改。

  • 导出的 Python 模块名称为 test

  • square() C++ 函数在导出的模块中导出为square 名称。

  • 使用 bjam,因为 IMO 它太复杂了,无论如何都不适合我。我正在使用旧的make

现在,代码如下:

// test.cpp
#include <boost/python.hpp>
#include <boost/numpy.hpp>
#include <boost/scoped_array.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>

namespace py = boost::python;
namespace np = boost::numpy;

void square(np::ndarray& array)
{
    if (array.get_dtype() != np::dtype::get_builtin<int>())
    {
        PyErr_SetString(PyExc_TypeError, "Incorrect array data type.");
        py::throw_error_already_set();
    }
    size_t rows = array.shape(0), cols = array.shape(1);
    size_t stride_row = array.strides(0) / sizeof(int), 
           stride_col = array.strides(1) / sizeof(int);
    cv::Mat mat(rows, cols, CV_32S);
    int *row_iter = reinterpret_cast<int*>(array.get_data());
    for (int i = 0; i < rows; i++, row_iter += stride_row)
    {
        int *col_iter = row_iter;
        int *mat_row = (int*)mat.ptr(i);
        for (int j = 0; j < cols; j++, col_iter += stride_col)
        {
            *(mat_row + j) = (*col_iter) * (*col_iter); 
        }
    }

    for (int i = 0; i < rows; i++, row_iter += stride_row)
    {
        int *col_iter = row_iter;
        int *mat_row = (int*)mat.ptr(i);
        for (int j = 0; j < cols; j++, col_iter += stride_col)
        {
            *col_iter = *(mat_row + j);
        }
    }
}


BOOST_PYTHON_MODULE(test)
{
   using namespace boost::python;
   def("square", square);
}

这是 Makefile:

PYTHON_VERSION = 2.7
PYTHON_INCLUDE = /usr/include/python$(PYTHON_VERSION)

BOOST_INC = /usr/local/include
BOOST_LIB = /usr/local/lib
OPENCV_LIB = $$(pkg-config --libs opencv)
OPENCV_INC = $$(pkg-config --cflags opencv)

TARGET = test

$(TARGET).so: $(TARGET).o
        g++ -shared -Wl,--export-dynamic \
        $(TARGET).o -L$(BOOST_LIB) -lboost_python \
        $(OPENCV_LIB) \
        -L/usr/lib/python$(PYTHON_VERSION)/config -lpython$(PYTHON_VERSION) \
        -o $(TARGET).so

$(TARGET).o: $(TARGET).cpp
        g++ -I$(PYTHON_INCLUDE) $(OPENCV_INC) -I$(BOOST_INC) -fPIC -c $(TARGET).cpp

使用此方案,我可以键入 make 并创建 test.so。但是当我尝试导入它时,

In [1]: import test
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-1-73ae3ffe1045> in <module>()
----> 1 import test

ImportError: ./test.so: undefined symbol:        _ZN5boost6python9converter21object_manager_traitsINS_5numpy7ndarrayEE10get_pytypeEv

In [2]: 

这是一个链接器错误,我似乎无法修复。任何人都可以帮我解决发生了什么吗? 您是否有(链接到)已经集成 OpenCV、numpy 和 Boost.Python 的代码,但没有 Py++ 之类的东西?

【问题讨论】:

  • 我在没有 Boost 的情况下尝试过,得到了类似的错误。 Boost 很好,但最新的 OpneCV 版本带有非常好的 Python 绑定。他们正在使用 Python/C API 来提供您可以获得的最佳性能。为什么要使用 boost?
  • 我已经实现了一个细化算法,它需要大量的迭代,逐个像素。与我不必担心编写 n 个双循环的 C++ 循环相比,Python 中的循环非常慢。当我检查时,Python 版本比 C++ 版本慢很多,即使某些操作是使用 numpy 向量操作向量化的。
  • 是的。诚然。如果你打算用 Python 进行迭代,那将需要很多时间。

标签: c++ python opencv boost makefile


【解决方案1】:

好的,我解决了这个问题。这是一个简单的问题,但昏昏欲睡的大脑和bjam 的份量让我忽略了它。在Makefile 中,我忘记了将 Boost.Numpy 库链接到我的库的-lboost_numpy。所以,修改后的Makefile 看起来像这样:

PYTHON_VERSION = 2.7
PYTHON_INCLUDE = /usr/include/python$(PYTHON_VERSION)

BOOST_INC = /usr/local/include
BOOST_LIB = /usr/local/lib
OPENCV_LIB = $$(pkg-config --libs opencv)
OPENCV_INC = $$(pkg-config --cflags opencv)

TARGET = test

$(TARGET).so: $(TARGET).o
        g++ -shared -Wl,--export-dynamic \
        $(TARGET).o -L$(BOOST_LIB) -lboost_python -lboost_numpy \
        $(OPENCV_LIB) \
        -L/usr/lib/python$(PYTHON_VERSION)/config -lpython$(PYTHON_VERSION) \
        -o $(TARGET).so

$(TARGET).o: $(TARGET).cpp
        g++ -I$(PYTHON_INCLUDE) $(OPENCV_INC) -I$(BOOST_INC) -fPIC -c $(TARGET).cpp

【讨论】:

  • +1 - 很高兴看到你解决了它。如果它适合您,您可以接受自己的答案并将此会话标记为answered
  • 我会的。我需要等待一天才能接受我自己的答案:)
猜你喜欢
  • 1970-01-01
  • 2012-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-04
  • 2016-07-23
  • 2015-11-19
相关资源
最近更新 更多