C++调python程序示例

背景

平台:Xavier nvidia AGX板子
编写c++程序测试单目3D目标检测DEVIANT(https://blog.csdn.net/qq_39523365/article/details/130982966?spm=1001.2014.3001.5501)python算法的过程。代码如下:

文件结构

请添加图片描述

具体代码:

test.cpp

#include <opencv2/opencv.hpp>
#include <iostream>
#include <time.h>
#include "LD_Detection.h"
#include <torch/torch.h>
#include <sys/timeb.h>


LD_Detection *  InitDetection(int m_ichannel, int m_iWidth, int m_iHeight) {
    // 程序执行路径
    std::string application_dir = "/home/nvidia/sd/DEVIANT";
    // qDebug() << "current path: " << qApp->applicationDirPath() << endl;
    application_dir += "/code/tools/";
    const char *m_cPyDir        = application_dir.c_str();
    std::string m_cPyFile       = "demo_inference_zs";
    std::string m_cPyFunction   = "detect_online";
    LD_Detection * m_pLD_Detection = new LD_Detection(m_ichannel, m_iWidth, m_iHeight, m_cPyDir, m_cPyFile.c_str(), m_cPyFunction.c_str() );
    std::cout << "*****************" << std::endl;
	return m_pLD_Detection;
}




int main()
{
	printf("##########%d***",torch::cuda::is_available());
	// 用 OpenCV 打开摄像头读取文件(你随便咋样获取图片都OK哪)
	//cv::VideoCapture cap = cv::VideoCapture(0);
	cv::VideoCapture cap;
	cap.open("/home/nvidia/sd/128G/test/data/video/0320/result2.avi");
	// 设置宽高 无所谓多宽多高后面都会通过一个算法转换为固定宽高的
	// 固定宽高值应该是你通过YoloV5训练得到的模型所需要的
	// 传入方式是构造 YoloV5 对象时传入 width 默认值为 640,height 默认值为 640
	cap.set(cv::CAP_PROP_FRAME_WIDTH, 1920);
	cap.set(cv::CAP_PROP_FRAME_HEIGHT, 1080);

	std::string videoname = "/home/nvidia/sd/128G/test/data/video/0320/result.avi";
	int videoFps = cap.get(cv::CAP_PROP_FPS);
	int myFourCC = cv::VideoWriter::fourcc('m', 'p', '4', 'v');
	cv::VideoWriter g_writer = cv::VideoWriter(videoname, myFourCC, videoFps, cv::Size(cap.get(cv::CAP_PROP_FRAME_WIDTH), cap.get(cv::CAP_PROP_FRAME_HEIGHT)));
	LD_Detection * m_pLD_Detection = InitDetection(0,1920,1080);
	// sleep(5);
	cv::Mat frame;
	int count = 0;
	while (cap.isOpened())
	{
		// 读取一帧
		cap.read(frame);
		if (frame.empty())
		{
			std::cout << "Read frame failed!" << std::endl;
			break;
		}

		std::cout << "------------------------" << std::endl;

		// 预测
		// 简单吧,两行代码预测结果就出来了,封装的还可以吧 嘚瑟
		clock_t start = clock();
		//void LD_Detection::startDetect(int camChan, unsigned char *image)
		m_pLD_Detection->startDetect(count, frame.data);
		clock_t ends = clock();
		// std::cout << start << std::endl;
		// std::cout << ends << std::endl;
		std::cout <<"Running Time : "<<(double)(ends - start) / CLOCKS_PER_SEC << CLOCKS_PER_SEC << std::endl;
		// show 图片
		g_writer << frame;
		// if(count++ > 2000)
		// {
		// 	break;
		// }
		//cv::imshow("", frame);
		//if (cv::waitKey(1) == 27) break;
	}
	g_writer.release();
	return 0;
}

LD_Detection.cpp

// #include <numpy/arrayobject.h>
#include </home/nvidia/sd/miniforge-pypy3/envs/centerpoint/include/python3.6m/Python.h>
#include </home/nvidia/sd/miniforge-pypy3/envs/centerpoint/lib/python3.6/site-packages/numpy/core/include/numpy/arrayobject.h>
// #include </usr/include/python2.7/Python.h>
// #include </usr/lib/python2.7/dist-packages/numpy/core/include/numpy/arrayobject.h>

//#include <json.h>
//#include <writer.h>
//#include <reader.h>
//#include <value.h>
#include "LD_Detection.h"
#include <thread>

// #include <QPainter>
// #include <QThread>

PyObject *pModule = nullptr;
PyObject *pDict = nullptr;
PyObject *pFunc = nullptr;
PyObject *pFunc1 = nullptr;
// PyObject *pFuncrelease = nullptr;
PyThreadState *pyThreadState = nullptr;

// LD_Detection::LD_Detection(QObject *parent, int camCount, int width, int
// height, const char *pyDir, const char *pyFile, const char *pyFunction) :
// QObject(parent)
// {
//     // Python脚本所在路径(绝对路径)
//     m_cPyDir = pyDir;
//     // Python脚本文件名
//     m_cPyFile = pyFile;
//     // Python脚本中要运行的函数名
//     m_cPyFunction = pyFunction;
//
//     m_iCamCount = camCount;
//     m_iCamWidth = width;
//     m_iCamHeight = height;
//     InitPython();
//     ImportPyModule();
//     m_bDetection = false;
//
//     m_pDetectionthread = nullptr;
// }

LD_Detection::LD_Detection(int camChan, int width, int height,
                           const char *pyDir, const char *pyFile,
                           const char *pyFunction) {
  // Python脚本所在路径(绝对路径)
  m_cPyDir = pyDir;
  // Python脚本文件名
  m_cPyFile = pyFile;
  // Python脚本中要运行的函数名
  m_cPyFunction = pyFunction;
  m_iCamChan = camChan;
  m_iCamWidth = width;
  m_iCamHeight = height;
  InitPython();
  ImportPyModule();
  m_bDetection = false;
  std::cout  << m_iCamWidth <<"-----startDetect----- " <<m_iCamHeight << std::endl;
  // std::string videoname = "/Leador_storage/zs/result/result.avi";
  // int myFourCC = cv::VideoWriter::fourcc('m', 'p', '4', 'v');
  // g_writer = cv::VideoWriter(videoname, myFourCC, 20, cv::Size(m_iCamWidth, m_iCamHeight));

}

LD_Detection::~LD_Detection() { 
  ReleasePython();
  // g_writer.release(); 
  }

bool LD_Detection::InitPython() {
  // qDebug() << "-----Initialize Python-----" << endl;
  Py_Initialize();
  if (!Py_IsInitialized()) {
    // qDebug() << "【error】: Python is not initialized" << endl;
    std::cout << "Python is not initialized";

    return false;
  }
  PyEval_InitThreads();
  PyRun_SimpleString("import sys");
  PyRun_SimpleString("print(sys.version)");
  PyRun_SimpleString("print(sys.executable)");
  std::cout << "-----------000-------------" << std::endl;
  
  std::cout << "-----------111-------------" << std::endl;
  import_array();
  std::cout << "-----------222-------------" << std::endl;
  if (PyErr_Occurred()) {
    std::cerr << "【error】: Failed to import numpy Python module" << std::endl;
    return false;
  }
  assert(PyArray_API);
  pyThreadState = PyEval_SaveThread();
  return true;
}

bool LD_Detection::ReleasePython() {
  // PyObject_CallObject(pFuncrelease, NULL);
  PyEval_RestoreThread(pyThreadState);
  Py_DECREF(pModule);
  Py_DECREF(pDict);
  Py_DECREF(pFunc);
  Py_DECREF(pFunc1);
  Py_Finalize();
  return true;
}

void LD_Detection::ImportPyModule() {
  PyGILState_STATE state = PyGILState_Ensure();
  // qDebug() << "-----Add python file path-----" << endl;
  std::cout << "-----Add python file path-----" << m_cPyDir << std::endl;

  char tempPath[256] = {};
  PyRun_SimpleString("import sys");
  sprintf(tempPath, "sys.path.append('%s')", m_cPyDir);
  PyRun_SimpleString(tempPath);
  PyRun_SimpleString("print('curr sys.path: ', sys.path)");
  PyRun_SimpleString("print(sys.version)");
  PyRun_SimpleString("print(sys.executable)");

  std::cout  << "PyRun_SimpleString " << tempPath << std::endl;
  // qDebug() << "-----Add python file-----" << endl;
  std::cout  << "-----Add python file----- " << m_cPyFile << std::endl;
  pModule = PyImport_ImportModule(m_cPyFile);
  std::cout  << "-----Add zs file----- " << m_cPyFile << std::endl;
  if (!pModule) {
    // qDebug() << "【error】: Can't find python file" << endl;
    std::cout  << "-----Can't find python file-----" << m_cPyFile << std::endl;
    return;
  }

  pDict = PyModule_GetDict(pModule);
  if (!pDict) {
    return;
  }

  // qDebug() << "-----Get python function-----" << endl;
  std::cout  << "-----Get python function----- "
               << " pModule " << pModule << " m_cPyFunction " << m_cPyFunction<< endl;
  pFunc1 = PyObject_GetAttrString(pModule, "print_version");
  PyObject *pValue_result =  PyObject_CallObject(pFunc1, NULL);
  int result = PyLong_AsLong(pValue_result);
  std::cout  << "-----zssssssss----- " << result << endl;

  // pFuncrelease = PyObject_GetAttrString(pModule, "release_resource");

  pFunc = PyObject_GetAttrString(pModule, m_cPyFunction);
  // pFunc = PyObject_GetAttrString(pModule, "detect_online");
  // PyObject_CallObject(pFunc, NULL);


  std::cout  << "-----Add python function-----"<< m_cPyFunction << endl;
  if (!pFunc || !PyCallable_Check(pFunc)) {
    // qDebug() << "【error】: Can't find python function" << endl;
    std::cout  << "-----Can't find python function----- " << pFunc;
    return;
  }
  PyGILState_Release(state);
}

void LD_Detection::slotStartDetection() {

  m_bDetection = true;
  //开启推流线程
  m_pDetectionthread =
      new std::thread(&LD_Detection::StartDetectionSingle, this);
}

void LD_Detection::slotStopDetection() {
  m_bDetection = false;
  if (m_pDetectionthread != nullptr) {
    m_pDetectionthread->join();
    delete m_pDetectionthread;
    m_pDetectionthread = nullptr;
  }
}

void LD_Detection::setParam(int nChan, unsigned char *image) {
  m_iChan = nChan;
  m_VideoOrgImage = image;
}

void LD_Detection::setParamMulti(unsigned char *images[]) {
  for (int i = 0; i < m_iCamCount; i++) {
    m_VideoOrgImages[i] = images[i];
  }
}

// 直接传单个图像参数进行检测
void LD_Detection::startDetect(int camChan, unsigned char *image) {
  PyGILState_STATE state = PyGILState_Ensure();
  PyObject *pArgs = PyTuple_New(2);
  cv::Mat temp = cv::Mat(m_iCamHeight, m_iCamWidth, CV_8UC3, image, 0);
  // std::cout  << "-----startDetect----- " << m_iCamWidth << std::endl;
  npy_intp Dims[3] = {temp.rows, temp.cols, temp.channels()};
  PyObject *image_channel = Py_BuildValue("i", camChan);
  PyObject *image_array =
      PyArray_SimpleNewFromData(3, Dims, NPY_UBYTE, temp.data);
  PyTuple_SetItem(pArgs, 0, image_channel);
  PyTuple_SetItem(pArgs, 1, image_array);
  PyObject *pReturnValue = PyObject_CallObject(pFunc, pArgs);
  // std::cout  << "-----startDetect----- " << m_iCamWidth << std::endl;
  if (PyList_Check(pReturnValue)) {
    int SizeOfObjects = PyList_Size(pReturnValue);
    std::cout  << "Size of return list: " << SizeOfObjects << std::endl;
    sign_objects.clear();
    for (int i = 0; i < SizeOfObjects; i++) {
      PyObject *pObject = PyList_GetItem(pReturnValue, i);
      int SizeOfObject = PyList_Size(pObject);
      std::cout  << "Size of return sublist: " << SizeOfObject << std::endl;

      struct SignObject object;
      PyArg_Parse(PyList_GetItem(pObject, 2), "f", &object.x_min);
      PyArg_Parse(PyList_GetItem(pObject, 3), "f", &object.y_min);
      PyArg_Parse(PyList_GetItem(pObject, 4), "f", &object.x_max);
      PyArg_Parse(PyList_GetItem(pObject, 5), "f", &object.y_max);
      PyArg_Parse(PyList_GetItem(pObject, 13), "f", &object.confidence);
      PyArg_Parse(PyList_GetItem(pObject, 0), "i", &object.clas);
      // PyArg_Parse(PyList_GetItem(pObject, 6), "s", &object.clas_name);
      std::cout  << "Object's x_min: " << object.x_min << std::endl;
      std::cout  << "Object's y_min: " << object.y_min << std::endl;
      std::cout  << "Object's x_max: " << object.x_max << std::endl;
      std::cout  << "Object's y_max: " << object.y_max << std::endl;
      std::cout  << "Object's confidence: " << object.confidence << std::endl;
      std::cout  << "Object's class name: " << object.clas << std::endl;
      sign_objects.push_back(object);

      cv::Point point_min((int)object.x_min, (int)object.y_min),
          point_max((int)object.x_max, (int)object.y_max);
      cv::Scalar colorRectangle(255, 0, 0);
      int thicknessRectangle = 3;
      cv::resize(temp,temp, cv::Size(768, 512));
      cv::rectangle(temp, point_min, point_max, colorRectangle,
      thicknessRectangle);
      
      cv::imwrite("test.jpg", temp);
      // cv::imshow("test", temp);
      // g_writer<<temp;
    }
  }
  PyGILState_Release(state);
}

// 直接传多个图像参数进行检测
void LD_Detection::startDetection(unsigned char *images[]) {
  PyGILState_STATE state = PyGILState_Ensure();
  PyObject *pArgImages = PyTuple_New(m_iCamChan);
  for (int i = 0; i < m_iCamChan; i++) {
    cv::Mat temp = cv::Mat(m_iCamHeight, m_iCamWidth, CV_8UC3, images[i], 0);
    npy_intp Dims[3] = {temp.rows, temp.cols, temp.channels()};
    PyObject *image_array =
        PyArray_SimpleNewFromData(3, Dims, NPY_UBYTE, temp.data);
    PyTuple_SetItem(pArgImages, i, image_array);
  }
  PyObject *pArgs = PyTuple_New(1);
  PyTuple_SetItem(pArgs, 0, pArgImages);
  PyObject_CallObject(pFunc, pArgs);

  PyGILState_Release(state);

  // QThread::msleep(1);
}

// Muilt Camera detection
void LD_Detection::StartDetectionMulti() {
  // qDebug() << "-----Video data to python function-----" << endl;
  while (m_bDetection) {
    PyGILState_STATE state = PyGILState_Ensure();
    PyObject *pArgImages = PyTuple_New(m_iCamCount);
    for (int i = 0; i < m_iCamCount; i++) {
      cv::Mat temp =
          cv::Mat(m_iCamHeight, m_iCamWidth, CV_8UC3, m_VideoOrgImages[i], 0);
      npy_intp Dims[3] = {temp.rows, temp.cols, temp.channels()};
      PyObject *image_array =
          PyArray_SimpleNewFromData(3, Dims, NPY_UBYTE, temp.data);
      PyTuple_SetItem(pArgImages, i, image_array);
    }
    PyObject *pArgs = PyTuple_New(1);
    PyTuple_SetItem(pArgs, 0, pArgImages);
    PyObject_CallObject(pFunc, pArgs);

    PyGILState_Release(state);

    // QThread::msleep(1);
    std::chrono::milliseconds dura(2);
    std::this_thread::sleep_for(dura);
  }
}

// Single Camera detection
void LD_Detection::StartDetectionSingle() {
  // qDebug() << "-----Video data to python function-----" << endl;
  int count = 0;
  while (m_bDetection) {
    PyGILState_STATE state = PyGILState_Ensure();
    PyObject *pArgs = PyTuple_New(2);
    PyObject *pReturnValue;
    cv::Mat temp =
        cv::Mat(m_iCamHeight, m_iCamWidth, CV_8UC3, m_VideoOrgImage, 0);
    //        qDebug() << "CVImage exist: " << temp.empty() << endl;
    //        cv::cvtColor(temp, *image, cv::COLOR_BGR2RGB);
    //        QString title = QString("test%1").arg(m_iChan);
    //        cv::imshow(title.toStdString(), *image);
    npy_intp Dims[3] = {temp.rows, temp.cols, temp.channels()};
    PyObject *image_channel = Py_BuildValue("i", count);
    PyObject *image_array =
        PyArray_SimpleNewFromData(3, Dims, NPY_UBYTE, temp.data);
    PyTuple_SetItem(pArgs, 0, image_channel);
    PyTuple_SetItem(pArgs, 1, image_array);
    // PyObject_CallObject(pFunc, pArgs);

    pReturnValue = PyObject_CallObject(pFunc, pArgs);

    if (PyList_Check(pReturnValue)) {
      int SizeOfObjects = PyList_Size(pReturnValue);
      // qDebug() << "Size of return list" << SizeOfObjects << endl;
      sign_objects.clear();
      for (int i = 0; i < SizeOfObjects; i++) {
        PyObject *pObject = PyList_GetItem(pReturnValue, i);
        int SizeOfObject = PyList_Size(pObject);

        //                for(int j = 0; j < pObject; j ++)
        //                {
        //                    float item = 0.0;
        //                    PyObject *pItem = PyList_GetItem(pObject, j);
        //                    PyArg_Parse(pItem, "f", &item);
        //                    qDebug() << "Data: " << item << " ";
        //                }
        struct SignObject object;
        PyArg_Parse(PyList_GetItem(pObject, 0), "i", &object.x_min);
        PyArg_Parse(PyList_GetItem(pObject, 1), "i", &object.y_min);
        PyArg_Parse(PyList_GetItem(pObject, 2), "i", &object.x_max);
        PyArg_Parse(PyList_GetItem(pObject, 3), "i", &object.y_max);
        PyArg_Parse(PyList_GetItem(pObject, 4), "f", &object.confidence);
        PyArg_Parse(PyList_GetItem(pObject, 5), "i", &object.clas);
        PyArg_Parse(PyList_GetItem(pObject, 6), "s", &object.clas_name);
        // qDebug() << "Object's x_min: " << object.x_min;
        // qDebug() << "Object's y_min: " << object.y_min;
        // qDebug() << "Object's x_max: " << object.x_max;
        // qDebug() << "Object's y_max: " << object.y_max;
        // qDebug() << "Object's confidence: " << object.confidence;
        // qDebug() << "Object's class name: " << object.clas_name;
        sign_objects.push_back(object);

        cv::Point point_min(object.x_min, object.y_min),
            point_max(object.x_max, object.y_max);
        cv::Scalar colorRectangle(255, 0, 0);
        int thicknessRectangle = 3;

        cv::rectangle(temp, point_min, point_max, colorRectangle,
                      thicknessRectangle);
      }
      // QString title = QString("test%1").arg(m_iChan);
      //            cv::imshow(title.toStdString(), temp);

      // qDebug() << "Number of objects in cur image: " << sign_objects.size()
      // << endl;
    }

    count++;
    PyGILState_Release(state);

    // QThread::msleep(1);
    std::chrono::milliseconds dura(1);
    std::this_thread::sleep_for(dura);
  }
}

LD_Detection.h

#ifndef LD_DETECTION_H
#define LD_DETECTION_H

#include <iostream>
// #include <QObject>
// #include <QDebug>
// #include <QImage>
// #include <QVector>
#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/opencv.hpp>
#include <thread>
#include <numpy/arrayobject.h>

#define MAX_CAMER_NUM 8

using namespace std;

class LD_Detection {
public:
  struct SignObject {
    float x_min;
    float y_min;
    float x_max;
    float y_max;
    float confidence;
    int clas;
    char *clas_name;
  };

  std::vector<SignObject> sign_objects;

public:
  // LD_Detection(int camCount, int width, int height, const char *pyDir,
  //              const char *pyFile, const char *pyFunction);
  LD_Detection(int camChan, int width, int height, const char *pyDir,
               const char *pyFile, const char *pyFunction);
  ~LD_Detection();

  void setParam(int nChan, unsigned char *image);
  void setParamMulti(unsigned char *images[]);
  void startDetect(int camChan, unsigned char *image);
  void startDetection(unsigned char *images[]);
  void StartDetectionSingle();
  void StartDetectionMulti();

  void RunDetection(bool bDetection);

private:
  bool InitPython();
  bool ReleasePython();
  void ImportPyModule();

private:
  int m_iCamChan = 0;
  int m_iCamCount = 0;
  int m_iCamWidth = 0;
  int m_iCamHeight = 0;
  const char *m_cPyDir;
  const char *m_cPyFile;
  const char *m_cPyFunction;
  unsigned char *m_VideoOrgImage;
  unsigned char *m_VideoOrgImages[MAX_CAMER_NUM];
  int m_iChan = 0;

  std::thread *m_pDetectionthread;
  bool m_bDetection;

  cv::VideoWriter g_writer;

  void slotStartDetection();
  void slotStopDetection();
};

#endif // LD_DETECTION_H

CMakeLists.txt

#1.cmake verson,指定cmake版本 
cmake_minimum_required(VERSION 3.2)

#2.project name,指定项目的名称,一般和项目的文件夹名称对应
PROJECT(TEST)

option(USE_PYTORCH " set ON detection mode change to USE_PYTORCH" ON)
option(NO_Encrtyption " set ON 测试模式,不需要license,且模型是未加密的模型" OFF)

set(op_cnt 0)
if (USE_PYTORCH)
    math(EXPR op_cnt ${op_cnt}+1)
    message("Using RefineDet detection 2")
endif()


#3.head file path,头文件目录
INCLUDE_DIRECTORIES(
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${CMAKE_CURRENT_SOURCE_DIR}/include
)
#set(OpenCV_DIR /usr/local/share/OpenCV)
find_package (OpenCV REQUIRED NO_CMAKE_FIND_ROOT_PATH)
if(OpenCV_FOUND)
    INCLUDE_DIRECTORIES(${OpenCV_INCLUDE_DIRS})
    message(STATUS "OpenCV library status:")
    message(STATUS "    version: ${OpenCV_VERSION}")
    message(STATUS "    libraries: ${OpenCV_LIBS}")
    message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")
endif()

if(USE_PYTORCH)
    IF(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
        MESSAGE(STATUS "Now is aarch64 OS's.")
        #Set library path
        set(CMAKE_PREFIX_PATH /home/nvidia/sd/miniforge-pypy3/envs/centerpoint/lib/python3.6/site-packages/torch)
    ELSE()
        MESSAGE(STATUS "Now is UNIX-like PC OS's.")
        #Set library path
        #set(CMAKE_PREFIX_PATH /home/he/miniconda/envs/py36/lib/python3.6/site-packages/torch)
        #set(TensorRT_DIR /home/he/work/TensorRT/tensorrt_v5.1_x64_release)
        #if(DEFINED TensorRT_DIR)
        #    include_directories("${TensorRT_DIR}/include" )
        #    link_directories("${TensorRT_DIR}/lib")
        #    link_directories("/usr/local/cuda/lib64")
        #endif(DEFINED TensorRT_DIR)
    ENDIF()
endif()


message("${ALGORITHM_SDK_INCLUDE_DIR}")

find_package (Torch REQUIRED NO_CMAKE_FIND_ROOT_PATH)


#4.source directory,APP源文件目录
#AUX_SOURCE_DIRECTORY(libosa/src DIR_SRCS)
AUX_SOURCE_DIRECTORY(src DIR_SRCS)

AUX_SOURCE_DIRECTORY(test TEST_SRCS)

SET(CMAKE_BUILD_TYPE RELEASE) #DEBUG RELEASE
#设置编译器版本
SET(CMAKE_C_COMPILER gcc)
SET(CMAKE_CXX_COMPILER g++)
if(CMAKE_COMPILER_IS_GNUCXX)
    #add_compile_options(-std=c++11)
    #message(STATUS "optional:-std=c++11")
endif(CMAKE_COMPILER_IS_GNUCXX)


#5.set environment variable,置环境变量,编译用到的源文件全部都要放到这里,否则编译能够通过,但是执行的时候会出现各种问题
SET(PROC_ALL_FILES
${DIR_SRCS}
)

set(TEST_APP Test_app)
# cuda
include_directories("/usr/local/cuda/include"
    /home/nvidia/sd/miniforge-pypy3/envs/centerpoint/include/python3.6m
    /home/nvidia/sd/miniforge-pypy3/envs/centerpoint/lib/python3.6/site-packages/numpy/core/include/numpy
    )
link_directories("/usr/local/cuda/lib64")
link_directories(BEFORE "/home/nvidia/sd/miniforge-pypy3/envs/centerpoint/lib")
link_directories(BEFORE "/home/nvidia/sd/miniforge-pypy3/envs/centerpoint/lib/python3.6/site-packages/numpy/core")
link_directories(BEFORE "/home/nvidia/sd/miniforge-pypy3/envs/centerpoint/lib/python3.6/config-3.6m-aarch64-linux-gnu")

#6.add executable file,添加要编译的可执行文件
#ADD_EXECUTABLE(${PROJECT_NAME} ${PROC_ALL_FILES})    #编译成可执行文件
add_library(${PROJECT_NAME} SHARED ${PROC_ALL_FILES}) #编译成动态库
add_executable(${TEST_APP} ${TEST_SRCS})

FILE(GLOB_RECURSE LIBS_CUDA /usr/local/cuda/lib64)
FILE(GLOB_RECURSE LIBS_BOOST_SYS /usr/lib/x86_64-linux-gnu/libboost_system.so)

#7.add link library,添加可执行文件所需要的库,比如我们用到了libm.so(命名规则:lib+name+.so),就添加该库的名称
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OpenCV_LIBS})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${TORCH_LIBRARIES} pthread)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} -ldl  -lcudart -lcublas -lcurand -lcudnn)

TARGET_LINK_LIBRARIES(${TEST_APP} ${OpenCV_LIBS})
TARGET_LINK_LIBRARIES(${TEST_APP} ${TORCH_LIBRARIES} pthread)
TARGET_LINK_LIBRARIES(${TEST_APP} ${PROJECT_NAME} )
#TARGET_LINK_LIBRARIES(${TEST_APP} -ldl)
TARGET_LINK_LIBRARIES(${TEST_APP} -ldl /home/nvidia/sd/miniforge-pypy3/envs/centerpoint/lib/libpython3.6m.so)

1.txt

export LD_LIBRARY_PATH=/home/nvidia/sd/miniforge-pypy3/envs/centerpoint/lib:/home/nvidia/sd/miniforge-pypy3/envs/centerpoint/lib/python3.6/site-packages/numpy/core:/home/nvidia/sd/miniforge-pypy3/envs/centerpoint/lib/python3.6/config-3.6m-aarch64-linux-gnu:$LD_LIBRARY_PATH
nvidia的torch cuda要确认
link_directories是编译代码所需要链接的库,不包含链接库又链接的库,链接库又链接的库找的不对时,可以用LD_LIBRARY_PATH指定程序执行时链接的路径;LD_LIBRARY_PATH是程序运行时曲查找链接库的路径。

1.gdb ./TeTest_app; 2.r; 3.where/bt
ros代码软件路径被修改后,需要重新catkin_make编译一下,具体可以运行命令“catkin_make clean”,或者将build和devel文件夹删除。
    ros::Publisher pub_Monocular_result;
    pub_Monocular_result =nh_.advertise<gmsl_pub::Detection_result>( "/Detection_result", 1 );

    gmsl_pub::Detection_result image_resultMsg;
    image_resultMsg.header.stamp    = ros::Time::now();
    image_resultMsg.header.frame_id = "camera_2";
    uint32 size = ;                   //size代表检测目标的个数
    uint32 origin_flag  = 2;            //origin_flag代表检测算法来源
    gmsl_pub::Object_result[] ob_result = ;     //代表object_result.msg的数组

    pub_Monocular_result.publish( image_resultMsg );

调用的python文件如下:

demo_inference_zs.py

import os
import sys
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
ROOT_DIR = os.path.dirname(BASE_DIR)
sys.path.append(ROOT_DIR)
sys.path.append('/home/nvidia/sd/DEVIANT/code/tools')
sys.path.append('/home/nvidia/sd/miniforge-pypy3/envs/centerpoint/lib/python3.6/site-packages')
import yaml
import logging
import argparse
import numpy as np
print(np.__path__)
import torch
import time
import random

from lib.helpers.dataloader_helper import build_dataloader
from lib.helpers.model_helper import build_model
from lib.helpers.optimizer_helper import build_optimizer
from lib.helpers.scheduler_helper import build_lr_scheduler
from lib.helpers.trainer_helper import Trainer
from lib.helpers.tester_helper import Tester
from lib.datasets.kitti_utils import get_affine_transform
from lib.datasets.kitti_utils import Calibration
from lib.datasets.kitti_utils import compute_box_3d
from lib.datasets.waymo import affine_transform

from lib.helpers.save_helper import load_checkpoint
from lib.helpers.decode_helper import extract_dets_from_outputs
from lib.helpers.decode_helper import decode_detections
from lib.helpers.rpn_util import *

from datetime import datetime

sys.path.append('%s')
sys.path.append('%s')


def print_version():
    print(torch.__version__)
    print(torch.__path__)
    return 100

def create_logger(log_file):
    log_format = '%(asctime)s  %(levelname)5s  %(message)s'
    logging.basicConfig(level=logging.INFO, format=log_format, filename=log_file)
    console = logging.StreamHandler()
    console.setLevel(logging.INFO)
    console.setFormatter(logging.Formatter(log_format))
    logging.getLogger().addHandler(console)
    return logging.getLogger(__name__)

def init_torch(rng_seed, cuda_seed):
    """
    Initializes the seeds for ALL potential randomness, including torch, numpy, and random packages.

    Args:
        rng_seed (int): the shared random seed to use for numpy and random
        cuda_seed (int): the random seed to use for pytorch's torch.cuda.manual_seed_all function
    """
    # seed everything
    os.environ['PYTHONHASHSEED'] = str(rng_seed)
    torch.manual_seed(rng_seed)
    np.random.seed(rng_seed)
    random.seed(rng_seed)
    torch.cuda.manual_seed(cuda_seed)
    torch.cuda.manual_seed_all(cuda_seed)

    # make the code deterministic
    torch.backends.cudnn.deterministic = True
    torch.backends.cudnn.benchmark = False

def pretty_print(name, input, val_width=40, key_width=0):
    """
    This function creates a formatted string from a given dictionary input.
    It may not support all data types, but can probably be extended.

    Args:
        name (str): name of the variable root
        input (dict): dictionary to print
        val_width (int): the width of the right hand side values
        key_width (int): the minimum key width, (always auto-defaults to the longest key!)

    Example:
        pretty_str = pretty_print('conf', conf.__dict__)
        pretty_str = pretty_print('conf', {'key1': 'example', 'key2': [1,2,3,4,5], 'key3': np.random.rand(4,4)})

        print(pretty_str)
        or
        logging.info(pretty_str)
    """
    pretty_str = name + ': {\n'
    for key in input.keys(): key_width = max(key_width, len(str(key)) + 4)

    for key in input.keys():
        val = input[key]
        # round values to 3 decimals..
        if type(val) == np.ndarray: val = np.round(val, 3).tolist()
        # difficult formatting
        val_str = str(val)
        if len(val_str) > val_width:
            # val_str = pprint.pformat(val, width=val_width, compact=True)
            val_str = val_str.replace('\n', '\n{tab}')
            tab = ('{0:' + str(4 + key_width) + '}').format('')
            val_str = val_str.replace('{tab}', tab)
        # more difficult formatting
        format_str = '{0:' + str(4) + '}{1:' + str(key_width) + '} {2:' + str(val_width) + '}\n'
        pretty_str += format_str.format('', key + ':', val_str)

    # close root object
    pretty_str += '}'
    return pretty_str
def np2tuple(n):
    return (int(n[0]), int(n[1]))

# def main(): 
# load cfg
config = "/home/nvidia/sd/DEVIANT/code/experiments/run_test.yaml"
cfg = yaml.load(open(config, 'r'), Loader=yaml.Loader)
exp_parent_dir = os.path.join(cfg['trainer']['log_dir'], os.path.basename(config).split(".")[0])
cfg['trainer']['log_dir'] = exp_parent_dir
logger_dir     = os.path.join(exp_parent_dir, "log")
os.makedirs(exp_parent_dir, exist_ok=True)
os.makedirs(logger_dir, exist_ok=True)
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
logger = create_logger(os.path.join(logger_dir, timestamp))
pretty = pretty_print('conf', cfg)
logging.info(pretty)
# init torch
init_torch(rng_seed= cfg['random_seed']-3, cuda_seed= cfg['random_seed'])
##w,h,l
# Ped  [1.7431 0.8494 0.911 ]
# Car  [1.8032 2.1036 4.8104]
# Cyc  [1.7336 0.823  1.753 ]
# Sign [0.6523 0.6208 0.1254]
cls_mean_size = np.array([[1.7431, 0.8494, 0.9110],
                                [1.8032, 2.1036, 4.8104],
                                [1.7336, 0.8230, 1.7530],
                                [0.6523, 0.6208, 0.1254]])

# build model
model = build_model(cfg,cls_mean_size)

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)
print(cfg['tester']['resume_model'])
load_checkpoint(model = model,
                optimizer = None,
                filename = cfg['tester']['resume_model'],
                logger=logger,
                map_location= device)
model.to(device)

torch.set_grad_enabled(False)
model.eval()
calibs = np.array([9.5749393532104671e+02/1920.0*768.0*0.9, 0., (1.0143950223349893e+03)/1920.0*768.0, 0., 
0., 9.5697913744394737e+02/1080.0*512.0*0.9, 5.4154074349276050e+02/1080.0*512.0, 0., 
0.0, 0.0, 1.0, 0.], dtype=np.float32)
calibsP2=calibs.reshape(3, 4)
calibs = torch.from_numpy(calibsP2).unsqueeze(0).to(device) 

resolution = np.array([768, 512])
downsample = 4
# coord_ranges = np.array([center-crop_size/2,center+crop_size/2]).astype(np.float32)
coord_ranges = np.array([np.array([0, 0]),resolution]).astype(np.float32)
coord_ranges = torch.from_numpy(coord_ranges).unsqueeze(0).to(device) 
features_size = resolution // downsample

# c++调用的接口
def detect_online(frame_chan, frame):
    print("image channel :", frame_chan)
    img        = frame
    index = np.array([frame_chan])
    #img = img[0:1080, int(150-1):int(1920-150-1)]
    # img = cv2.resize(img, (768, 512))
    img_cv_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    img    = Image.fromarray(img_cv_rgb)
    img_size = np.array(img.size)
    center = img_size / 2
    crop_size = img_size

    info = {'img_id': index,
            'img_size': resolution,
            'bbox_downsample_ratio': resolution / features_size}

    # add affine transformation for 2d images.
    trans, trans_inv = get_affine_transform(center, crop_size, 0, resolution, inv=1)
    img = img.transform(tuple(resolution.tolist()),
                        method=Image.AFFINE,
                        data=tuple(trans_inv.reshape(-1).tolist()),
                        resample=Image.BILINEAR)
                  
    # image encoding
    img = np.array(img).astype(np.float32) / 255.0
    mean = np.array([0.485, 0.456, 0.406], dtype=np.float32)
    std  = np.array([0.229, 0.224, 0.225], dtype=np.float32)
    img = (img - mean) / std
    img = img.transpose(2, 0, 1)  # C * H * W
    inputs = img

    inputs = torch.from_numpy(inputs)
    inputs = inputs.unsqueeze(0)  
    inputs = inputs.to(device)
    # the outputs of centernet
    outputs = model(inputs,coord_ranges,calibs,K=50,mode='test')
    print(np.__path__)
    dets = extract_dets_from_outputs(outputs=outputs, K=50)
    dets = dets.detach().cpu().numpy()

    calibs1 = Calibration(calibsP2)
    dets = decode_detections(dets = dets,
                                info = info,
                                calibs = calibs1,
                                cls_mean_size=cls_mean_size,
                                threshold = cfg['tester']['threshold'])

    print(dets)
    # img        = cv2.imread(img_file, cv2.IMREAD_COLOR)
    # # img = cv2.resize(img, (768, 512))

    # for i in range(len(dets)):
    #     #cv2.rectangle(img, (int(dets[i][2]), int(dets[i][3])), (int(dets[i][4]), int(dets[i][5])), (0, 0, 255), 1)
    #     corners_2d,corners_3d=compute_box_3d(dets[i][6], dets[i][7], dets[i][8], dets[i][12],
    #      (dets[i][9], dets[i][10], dets[i][11]), calibs)
    #     for i in range(corners_2d.shape[0]):
    #         corners_2d[i] = affine_transform(corners_2d[i], trans_inv)
    #     cv2.line(img,np2tuple(corners_2d[0]),np2tuple(corners_2d[1]),(255,255,0),1,cv2.LINE_4)
    #     cv2.line(img,np2tuple(corners_2d[1]),np2tuple(corners_2d[2]),(255,255,0),1,cv2.LINE_4)
    #     cv2.line(img,np2tuple(corners_2d[2]),np2tuple(corners_2d[3]),(255,255,0),1,cv2.LINE_4)
    #     cv2.line(img,np2tuple(corners_2d[3]),np2tuple(corners_2d[0]),(255,255,0),1,cv2.LINE_4)

    #     cv2.line(img,np2tuple(corners_2d[4]),np2tuple(corners_2d[5]),(255,255,0),1,cv2.LINE_4)
    #     cv2.line(img,np2tuple(corners_2d[5]),np2tuple(corners_2d[6]),(255,255,0),1,cv2.LINE_4)
    #     cv2.line(img,np2tuple(corners_2d[6]),np2tuple(corners_2d[7]),(255,255,0),1,cv2.LINE_4)
    #     cv2.line(img,np2tuple(corners_2d[7]),np2tuple(corners_2d[4]),(255,255,0),1,cv2.LINE_4)

    #     cv2.line(img,np2tuple(corners_2d[5]),np2tuple(corners_2d[1]),(255,255,0),1,cv2.LINE_4)
    #     cv2.line(img,np2tuple(corners_2d[4]),np2tuple(corners_2d[0]),(255,255,0),1,cv2.LINE_4)

    #     cv2.line(img,np2tuple(corners_2d[6]),np2tuple(corners_2d[2]),(255,255,0),1,cv2.LINE_4)
    #     cv2.line(img,np2tuple(corners_2d[7]),np2tuple(corners_2d[3]),(255,255,0),1,cv2.LINE_4)
    # cv2.imwrite("3.jpg", img)
    return dets

if __name__ == '__main__':
    img_file = "./code/tools/img/result2_00000575.jpg"
    frame        = cv2.imread(img_file, cv2.IMREAD_COLOR)
    frame_chan = 0
    detect_online(frame_chan, frame)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值