项目背景为使用C++调用YOLACT网络检测的结果
1. 主函数
#include <Python.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
#include "iostream"
#include <numpy/arrayobject.h>
#include "chrono"
using namespace cv;
using namespace std;
class YOLACT{
public:
YOLACT(int imagerows, int imagecols, int channals){
Py_Initialize();
import_array1();
image_rows=imagerows, image_cols=imagecols, image_channals=imagecols;
if(!Py_IsInitialized())
{
printf("Python init failed!\n");
}
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('/home/jinln/jinln/python_project/yolact-our')");
PyRun_SimpleString("print(sys.path)");
pModule = PyImport_ImportModule("slam_yolact");
if (!pModule) {
printf("Can not open python file!\n");
}
pFunc_test_numpy = PyObject_GetAttrString(pModule, "get_mask");
};
cv::Mat yolact_seg(cv::Mat preImg){
try{
npy_intp Dims[3]={image_rows,image_cols,1};
PyObject *PyImg = PyArray_SimpleNewFromData(3, Dims, NPY_UBYTE, preImg.data);
PyObject *pArgs = PyTuple_New(1);
PyTuple_SetItem(pArgs,0, PyImg);
PyObject *ret2 = PyObject_CallObject(pFunc_test_numpy, pArgs);
Mat retImg2(image_rows,image_cols,CV_8UC1,PyArray_DATA(ret2));
return retImg2;
}
catch (...) {
cerr<<"python seg image error!"<<endl;
}
};
private:
PyObject* pModule;
PyObject* pFunc_test_numpy;
int image_rows, image_cols, image_channals;
};
int main(int argc, char *argv[]){
YOLACT Slam_yolact(962,1218,1);
Mat img=imread("/home/jinln/CLionProjects/cpp_py/000498.png",cv::IMREAD_GRAYSCALE);
Mat mask=Slam_yolact.yolact_seg(img);
imshow("1",mask);
waitKey(0);
return 0;
}
2. cpp_python.cpp
#include <Python.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <utility>
#include "iostream"
#include "map"
#include <numpy/arrayobject.h>
using namespace cv;
using namespace std;
class CppPython {
public:
CppPython(std::string pythonFolder, std::string pythonModule)
: pyFolderPath(std::move(pythonFolder)), pyModuleName(std::move(pythonModule)) {
Py_Initialize();
if (!Py_IsInitialized()) printf("初始化python失败!\n");
import_array1();
PyRun_SimpleString("import sys");
PyRun_SimpleString(("sys.path.append('" + pyFolderPath + "')").c_str());
pyModule = PyImport_ImportModule(pyModuleName.c_str());
if (!pyModule) printf("导入python模块%s失败!\n", pyModuleName.c_str());
}
int usePythonFunc(const std::string &funcName, int val) {
if (funcMap.find(funcName) == funcMap.end()) {
funcMap[funcName] = PyObject_GetAttrString(pyModule, funcName.c_str());
printf("第一次调用%s!\n",funcName.c_str());
}
PyObject *arg = Py_BuildValue("(i)", val);
PyObject *ret = PyObject_CallObject(funcMap[funcName], arg);
int retVal;
PyArg_Parse(ret, "i", &retVal);
return retVal;
}
Mat usePythonFunc(const std::string &funcName, cv::Mat &img) {
if (funcMap.find(funcName) == funcMap.end()) {
funcMap[funcName] = PyObject_GetAttrString(pyModule, funcName.c_str());
printf("第一次调用%s!\n",funcName.c_str());
}
npy_intp Dims[3] = {img.rows, img.cols, img.channels()};
int dim = img.channels() == 1 ? 1 : 3;
PyObject *PyImg = PyArray_SimpleNewFromData(dim, Dims, NPY_UBYTE, img.data);
PyObject *arg = PyTuple_New(1);
PyTuple_SetItem(arg, 0, PyImg);
PyObject *retData = PyObject_CallObject(funcMap[funcName], arg);
Mat retImg(img.rows, img.cols, CV_8UC1, PyArray_DATA(retData));
return retImg;
}
public:
std::string pyFolderPath;
std::string pyModuleName;
private:
PyObject *pyModule = nullptr;
std::map<std::string, PyObject *> funcMap;
};
int main(int argc, char *argv[]) {
CppPython test("/home/anan/CPPCODE/AnanCode/demo/python","python_module");
int ret = test.usePythonFunc("number_add_1",5);
cout<<ret<<endl;
Mat img = imread("/home/anan/CLionProjects/CppPython/1.png");
resize(img, img, Size(500, 500));
for(int i=0;i<20;i++)
{
Mat retImg = test.usePythonFunc("img_to_gray",img);
imshow("1",retImg);
waitKey();
}
return 0;
}
3. CmakeLists
cmake_minimum_required(VERSION 3.5)
project(cpp_py)
set(CMAKE_CXX_STANDARD 14)
if(CMAKE_COMPILER_IS_GNUCC)
message("COMPILER IS GNUCC")
ADD_DEFINITIONS ( -std=c++11 )
endif(CMAKE_COMPILER_IS_GNUCC)
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
# 添加头文件路径
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(/home/jinln/anaconda3/envs/yolact-env/include/python3.8) # 虚拟环境python头文件
set(OpenCV_DIR "/home/jinln/installProgram/opencv-4.5.4/build") #OpenCVConfig.cmake所在的文件目录
find_package(OpenCV)
MESSAGE("OPENCV VERSION:")
MESSAGE(${OpenCV_VERSION})
include_directories(${OpenCV_INCLUDE_DIRS})
# 添加要编译的可执行文件
add_executable(${PROJECT_NAME} main.cpp )
# 隐式链接库文件
target_link_libraries(${PROJECT_NAME} /home/jinln/anaconda3/envs/yolact-env/lib/libpython3.8.so ${OpenCV_LIBS}
)