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