ubuntu下C++與Python混編,opencv中mat類轉換

C++ 與 Python 混編

由於趕項目進度,須要使用到深度學習的內容,不過現有的深度學習框架大多使用python代碼,對於不會改寫C++的朋友來講,須要耗費大量的時間去改寫,所以,使用python與C++混編能夠快速的查看效果,並做出選擇。python

在c++中使用混編python須要用到基礎頭文件Python.h,最好須要使用boost中的python,boost將底層python從新封裝,更好的使用c++調用python。c++

頭文件須要包括git

#include <Python.h>
#include <boost/python.hpp>

using namespace boost::python;

c++調用python須要先初始python的相關東西。根據python的版本分開github

#if (PY_VERSION_HEX >= 0x03000000)

    static void *init_ar() {
#else
        static void init_ar(){
#endif
        Py_Initialize();

        import_array();
        return NUMPY_IMPORT_ARRAY_RETVAL;
    }

在項目的開始須要調用inti_ar()。代碼片斷圖下:app

init_ar();
    char str[] = "Python";
    Py_SetProgramName(str);

而後判斷python是否已經初始化框架

if(!Py_IsInitialized())
        cout << "init faild/n" << endl;

以後能夠測試一下python是否可用直接在c++中寫python語句,以下:python2.7

PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('../python')");
    PyRun_SimpleString("import os");
    PyRun_SimpleString("print os.getcwd()");
    PyRun_SimpleString("print ('Hello Python!')\n");

以後須要調用python的文件:函數

PyObject *pModule,*pFunc,*pDict;
    PyObject *pArgs, *pValue;

    pModule = PyImport_ImportModule("add_module"); //    調用python文件
    if (pModule == NULL) {  
        cout<<"ERROR importing module"<<endl; 
        return false; 
    } 

    pDict = PyModule_GetDict(pModule);

    pFunc = PyDict_GetItemString(pDict, (char*)"add");  //獲得函數


    /* build args */

    PyObject *pArgs1 = Py_BuildValue("i", 5);
    PyObject *pArgs2 = Py_BuildValue("i", 3);


    if(pFunc != NULL) { 
        pValue = PyObject_CallFunction(pFunc, "OO",pArgs1,pArgs2 );   //傳入兩個值
    }else{
        cout<<"function error!"<<endl;
        
    }

其中add_module是python的文件名,add是python中的函數名。 這樣就能夠經過調用python的加法運算。學習

C++與Python傳輸Mat類

opencv中有C++和Python兩個接口,其中cv2.hpp中就有二者轉換的代碼,可是估計不少人不會使用,所以就有人提取出來,在github上搜pyboostcvconverter這個就能夠搜到https://github.com/Algomorph/pyboostcvconverter,我這裏就講一下如何使用。測試

原項目中cmakelist有點複雜,簡化一下:

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project("pbcvt")

#----------------------------CMAKE & GLOBAL PROPERTIES-------------------------#
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

###============= C++11 support====================================
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if (COMPILER_SUPPORTS_CXX11)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif (COMPILER_SUPPORTS_CXX0X)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else ()
    message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif ()


#=============== Find Packages 
find_package(OpenCV  REQUIRED)
include("DetectPython")

find_package(Boost COMPONENTS REQUIRED python)
#python能夠直接使用下面這個
#find_package(PythonLibs REQUIRED)
#或者自定義lib和include
#SET(PYTHON_INCLUDE_DIRS /usr/include/python2.7)
#SET(PYTHON_LIBRARIES ${PYTHON2_LIBRARY})
#========pick python stuff========================================

SET(PYTHON_INCLUDE_DIRS /usr/include/python2.7)
SET(PYTHON_LIBRARIES ${PYTHON2_LIBRARY})
SET(PYTHON_EXECUTABLE ${PYTHON2_EXECUTABLE})
SET(PYTHON_PACKAGES_PATH ${PYTHON2_PACKAGES_PATH})
SET(ARCHIVE_OUTPUT_NAME pbcvt_py2)


add_executable(project 
${CMAKE_CURRENT_SOURCE_DIR}/src/pyboost_cv2_converter.cpp 
${CMAKE_CURRENT_SOURCE_DIR}/src/test.cpp 
${CMAKE_CURRENT_SOURCE_DIR}/src/pyboost_cv3_converter.cpp 
${CMAKE_CURRENT_SOURCE_DIR}/include/pyboostcvconverter/pyboostcvconverter.hpp)

target_include_directories(project PUBLIC 
${CMAKE_CURRENT_SOURCE_DIR}/include 
${Boost_INCLUDE_DIRS} 
${OpenCV_INCLUDE_DIRS} 
${PYTHON_INCLUDE_DIRS}
${PCL_INCLUDE_DIRS})

target_link_libraries(project ${Boost_LIBRARIES} ${OpenCV_LIBS} ${PYTHON_LIBRARIES} ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES})

代碼中名空間須要加上using namespace pbcvt; 傳如圖片和化先將圖片轉化爲PyObject類型在進行傳輸就能夠了。注意python中image是使用numpy類型。

代碼以下:https://github.com/myBestLove/cppPython

相關文章
相關標籤/搜索