github.com/kaydxh/golang@v0.0.131/pkg/gocv/cgo/swig/pycv/pycv_linux_amd64.cpp (about)

     1  #include <pybind11/embed.h>
     2  
     3  #include <memory>
     4  #include <mutex>
     5  #include <sstream>
     6  #include <stdexcept>
     7  
     8  #include "pycv.h"
     9  
    10  namespace py = pybind11;
    11  using namespace pybind11::literals;  // to bring in the `_a` literal
    12  #ifdef __cplusplus
    13  #define UIKIT_EXTERN extern "C" __attribute__((visibility("default")))
    14  #else
    15  #define UIKIT_EXTERN extern __attribute__((visibility("default")))
    16  #endif
    17  static std::once_flag python_once;
    18  static std::unique_ptr<py::scoped_interpreter> python_interpreter_guard;
    19  static std::unique_ptr<py::gil_scoped_release>
    20      python_interpreter_gil_scoped_release;
    21  
    22  pycv::PyImage::~PyImage() {
    23      py::gil_scoped_acquire acquire;
    24      sdk_py.dec_ref();
    25  }
    26  
    27  void pycv::PyImage::GlobalInit(const std::string& model_dir, int gpu_id) {
    28      std::call_once(python_once, [] {
    29          python_interpreter_guard = std::unique_ptr<py::scoped_interpreter>(
    30              new py::scoped_interpreter());
    31          { pybind11::gil_scoped_acquire acquire; }
    32          python_interpreter_gil_scoped_release =
    33              std::unique_ptr<py::gil_scoped_release>(
    34                  new py::gil_scoped_release());
    35      });
    36  }
    37  
    38  void pycv::PyImage::GlobalRelease() {}
    39  
    40  void pycv::PyImage::LocalInit(const LocalInitRequest& req,
    41                                LocalInitResponse& resp) {
    42      // acquiring GIL as toPyObject creates new py::object
    43      // without grabbing the GIL.
    44      py::gil_scoped_acquire acquire;
    45  
    46      // https://pybind11.readthedocs.io/en/stable/advanced/pycpp/object.html#calling-python-methods
    47      // https://github.com/pybind/pybind11/issues/1201
    48      auto py_cv = py::module::import("pycv");
    49      if (py_cv.is_none()) {
    50          throw std::runtime_error("module pycv not found");
    51      }
    52  
    53      if (!py::hasattr(py_cv, "CVSDK")) {
    54          throw std::runtime_error("python class pycv.CVSD not found");
    55      }
    56  
    57      auto CVSDK = py_cv.attr("CVSDK");
    58      sdk_py = CVSDK();
    59      if (!py::hasattr(sdk_py, "init")) {
    60          throw std::runtime_error("python method py.CVSDK::init not found");
    61      }
    62      if (!py::hasattr(sdk_py, "do")) {
    63          throw std::runtime_error("python method py.CVSDK::do not found");
    64      }
    65      {  // 模型初始化
    66          py::dict dict("model_dir"_a = req.model_dir, "gpu_id"_a = req.gpu_id);
    67          dict["sdk_dir"] = req.sdk_dir;
    68          auto init_resp_py = sdk_py.attr("init")(**dict);
    69          auto init_resp = py::dict(init_resp_py);
    70          if (init_resp.contains("err")) {
    71              std::stringstream ss;
    72              ss << "py.CVSDK::init returns (";
    73              ss << init_resp["err"].cast<std::string>();
    74              ss << ")";
    75              throw std::runtime_error(ss.str());
    76          }
    77      }
    78  }
    79  
    80  void pycv::PyImage::Do(const DoRequest& req, DoResponse& resp) {
    81      py::gil_scoped_acquire acquire;
    82  
    83      if (sdk_py.is_none()) {
    84          throw std::runtime_error(
    85              "method py.CVSDK not initialized, call init at first");
    86      }
    87      if (!py::hasattr(sdk_py, "do")) {
    88          throw std::runtime_error("method py.do not found");
    89      }
    90      {
    91          py::dict dict("arg1"_a = py::bytes(req.arg1));
    92          dict["arg2"] = req.arg2;
    93          auto do_resp_py = sdk_py.attr("do")(**dict);
    94          auto do_resp = py::dict(do_resp_py);
    95          if (do_resp.contains("err")) {
    96              std::stringstream ss;
    97              ss << "py.CVSDK::do do_resp returns (";
    98              ss << do_resp["err"].cast<std::string>();
    99              ss << ")";
   100              throw std::runtime_error(ss.str());
   101          }
   102      }
   103  }
   104