【问题标题】:Using opencv types with pybind11在 pybind11 中使用 opencv 类型
【发布时间】:2019-02-14 08:23:59
【问题描述】:

我想使用 pybind11 为使用 opencv 类型的函数创建一个包装器。

这是我的尝试:

example.hpp

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

class MyClass
{
public:
    MyClass();

    void func1(cv::Rect &rc);
    cv::Rect func2(cv::Rect &rc);
    static void func3(cv::Rect &rc);
    static cv::Rect func4(cv::Rect &rc);
    void func5(int f);
};

example.cpp

#include "example.hpp"

#include <iostream>

    MyClass::MyClass()
    {
        std::cout << "MyClass::MyClass() called! " << std::endl;
    }

    void MyClass::func1(cv::Rect &rc)
    {

    }

    cv::Rect MyClass::func2(cv::Rect &rc)
    {
        cv::Rect rc2(10,20,30,40);
        return rc2;
    }

    void MyClass::func3(cv::Rect &rc)
    {

    }

    cv::Rect MyClass::func4(cv::Rect &rc)
    {
        cv::Rect rc2(10,20,30,40);
        return rc2;
    }


    void MyClass::func5(int f)
    {

    }

pybind11_example.cpp

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/numpy.h>

#include "example.hpp"

namespace py = pybind11;

PYBIND11_MODULE(pybind11_example, m) {
    py::class_<MyClass>(m, "MyClass")
    .def(py::init<>())
    .def("func1", &MyClass::func1, "some func1", py::arg("rc"))
    .def("func5", &MyClass::func5, "some func5", py::arg("f"));


    // Static function binding with passing custom type and return custom type
    m.def("func4", [](std::vector<int> &v) -> py::array {
        if (v.size()!=4)
        {
            throw std::runtime_error("v.size()!=4");
        }

        cv::Rect rc;
        cv::Rect rc2 = MyClass::func4(rc);
        std::vector<int> v2;
        v2.push_back(rc2.x);
        v2.push_back(rc2.y);
        v2.push_back(rc2.width);
        v2.push_back(rc2.height);
        return py::array(v2.size(), v2.data());
    });
}

CMakeLists.txt

project("pybind11_example")
cmake_minimum_required(VERSION 2.8)

find_package(PythonLibs)
execute_process(
    COMMAND "python3" "-c" "import os, numpy.distutils; print(os.pathsep.join(numpy.distutils.misc_util.get_numpy_include_dirs()))"
    RESULT_VARIABLE _numpy_process
    OUTPUT_VARIABLE _numpy_include_dirs
    OUTPUT_STRIP_TRAILING_WHITESPACE
)
if (NOT _numpy_process EQUAL 0)
    message(FATAL_ERROR "Can't locate numpy include dirs")
endif()
include_directories(${PYTHON_INCLUDE_DIRS} ${_numpy_include_dirs})
message("Python libs: ${PYTHON_LIBRARIES}")

find_package(pybind11 REQUIRED)
pybind11_add_module(pybind11_example pybind11_example.cpp example.cpp)
target_link_libraries(pybind11_example PRIVATE ${OpenCV_LIBS} ${Boost_LIBRARIES})

这是我的问题:

func5 绑定有什么问题?当我做from pybind11_example import MyClass 和例如MyClass.func5(3) 我得到错误:

MyClass.func5(3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: func5(): incompatible function arguments. The following argument types are supported:
    1. (self: pybind11_example.MyClass, f: int) -> None

Invoked with: 3

我能够通过一个技巧(参见 func4)将静态函数与 opencv 类型 cv::Rect 绑定,但是如何绑定非静态函数,即 func2?以及如何保证MyClass的构造函数会被调用?

【问题讨论】:

    标签: python c++ opencv pybind11


    【解决方案1】:

    这非常有用。

    我今天尝试使用 Python 调用 C++ API 和 OpenCV。并遇到了错误消息:

    Expected in: flat namespace.
    

    按照你的代码我在target_link_libraries中添加PRIVATE,bug解决了。

    【讨论】:

      【解决方案2】:

      MyClass::func5 不是静态成员函数。在调用它之前将其设为静态或创建一个实例:

      from pybind11_example import MyClass
      m = MyClass()
      m.func5(3)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-01-29
        • 1970-01-01
        • 2018-05-09
        • 1970-01-01
        • 2020-07-10
        • 2021-10-18
        • 2020-02-29
        • 1970-01-01
        相关资源
        最近更新 更多