2013-02-11 4 views
3

내가 boost::python 내 C++ OpenCV의 코드를 포장하고, 그것을 수행하는 방법을 배우고 싶다, 나는 boost::numpy::ndarray로 날을 제공하기 위해 Boost.Numpy 프로젝트를 사용하는Boost :: Python으로 C++ OpenCV 코드를 어떻게 감쌀까요?

  • 에 장난감 예를 시도했다.

  • 랩핑 될 C++ 함수 인 square()boost::numpy::ndarray을 취하고 그 안에있는 각 요소를 제곱하여 수정합니다.

  • 내 보낸 파이썬 모듈 이름은 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); 
} 

그리고 여기 메이크입니다 : 내가 maketest.so가 생성됩니다 입력 할 수 있습니다

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 

이 구성표. 하지만 가져 오기를 시도 할 때

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 ++ 등을 사용하지 않고 이미 통합 한 코드가 있습니까?.

+0

나는 부스트없이 시도했는데 비슷한 오류가 발생했습니다. 부스트는 훌륭하지만 최신 OpneCV 버전은 매우 훌륭한 파이썬 바인딩을 제공합니다. 그들은 Python/C API를 사용하여 얻을 수있는 최상의 성능을 제공합니다. 왜 부스트를 사용하고 싶습니까? – Froyo

+0

필자는 픽셀 단위로 많은 수의 반복을 필요로하는 씬닝 알고리즘을 구현했습니다. 파이썬의 루프는 n 개의 이중 루프를 작성하는 것에 대해 걱정할 필요가없는 C++ 루프와 비교할 때 매우 느립니다. 내가 체크했을 때, 파이썬 버전은 numpy 벡터 연산을 사용하여 벡터화 된 연산이 있더라도 C++ 버전보다 훨씬 느리다. –

+0

예. 사실. 파이썬에서 반복한다면, 많은 시간이 걸릴 것입니다. – Froyo

답변

2

좋아요. 그것은 간단한 문제였습니다. 그러나 졸린 뇌와 서빙 bjam은 그것을 무시하게 만들었습니다. Makefile에서는 Boost.Numpy libs를 내 lib에 링크하는 -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 
+0

+1 - 반가워요. 잘 작동하면 자신의 답변을 수락하고이 세션을 '대답 함'으로 표시 할 수 있습니다. –

+0

그럴 것입니다. 나는 내 자신의 대답을 받아들이 기 전에 하루를 기다려야한다. –

+0

OK.Fine. 방금 언급 했어. 어쨌든 좋은 작품 !!! –

관련 문제