我想換我的C++ OpenCV的代碼boost::python
,並學習如何做到這一點,我想一個玩具示例,其中如何用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很好,但是最新的OpneCV版本帶有非常好的Python綁定。他們使用Python/C API來提供您可以獲得的最佳性能。你爲什麼要使用提升? – Froyo 2013-02-11 08:55:24
我已經實現了細化算法,它需要逐個像素進行大量迭代。與C++循環相比,Python中的循環非常慢,我不必擔心寫入n個雙循環。當我檢查時,即使某些操作使用numpy向量操作進行了矢量化,Python版本的速度比C++版本低很多。 – 2013-02-11 12:07:05
是的。誠然。如果你正在Python中使用它,它會花費很多時間。 – Froyo 2013-02-11 15:34:43