【问题标题】:Pybind11 for C++ code with inner struct created via static factory methodPybind11 用于 C++ 代码,内部结构通过静态工厂方法创建
【发布时间】:2018-01-21 22:51:01
【问题描述】:

我有自己的 C++,我正在尝试使用 Pybind11 生成 python 绑定:

auto markerParams = MarkerDetector::Params::create(MarkerType::chessboard);
markerDetector.detect(image, markerParams);

我在为MarkerDetector::Params struct 生成绑定时遇到问题,因为它是一个使用以枚举为参数的工厂方法构造的内部结构:

enum MarkerType { chessboard, tag };

typedef std::vector<cv::Point> ContourType;
typedef std::vector<cv::Point2d> ContourTyped;

//              contour full, contour approximate, area, corners
typedef std::tuple<ContourType, ContourType, double, ContourTyped> MarkerDescriptor;


class MarkerDetector {
    public:
        std::vector<MarkerDescriptor> detect(Mat image, const Params params);

        struct Params {
            int rows, cols;
            ColorRange borderColor;
            ShapeDetector::Params borderShape;
            cv::Size borderSize;
            cv::Size Size;


            static Params create(MarkerType markerType) {
                static Params markerTypes[] = {
                    { 3, 6, ColorRange::GREEN, ShapeDetector::Params::RECTANGLE, cv::Size(30,30), cv::Size(140, 140) }
                };
                return markerTypes[markerType];
            }
        };
    };

有人知道如何处理这个更高级的案例吗?

【问题讨论】:

    标签: python c++ binding pybind11


    【解决方案1】:

    我已经根据您的设计使用内部结构来运行您的代码的基本实现。为简洁起见,我只包含了 MarkerDetector 和 Params 的相关详细信息,但它应该与您所做的相匹配。

    c++代码:

    #include <pybind11/pybind11.h>
    
    namespace py = pybind11;
    
    enum MarkerType { chessboard, tag };
    
    
    class MarkerDetector {
        public:
        MarkerDetector() { }
        struct Params {
            int rows;
            int cols;
            static Params create(MarkerType markerType) {
                static Params markerTypes[] = {
                        { 1, 2 },
                        { 3, 4 }
                };
                return markerTypes[markerType];
            }
        };
    
    };
    
    
    PYBIND11_MODULE(example, m) {
        m.doc() = "pybind11 example"; // optional module docstring
    
        py::enum_<MarkerType>(m, "MarkerType")
             .value("chessboard", MarkerType::chessboard)
             .value("tag",        MarkerType::tag)
             .export_values();
    
        py::class_<MarkerDetector>(m, "MarkerDetector")
                .def(py::init<>())
                ;
    
        py::class_<MarkerDetector::Params>(m, "MarkerDetectorParams")
                .def(py::init<>())
                .def_readwrite("rows", &MarkerDetector::Params::rows)
                .def_readwrite("cols", &MarkerDetector::Params::cols)
                .def("create", (MarkerDetector::Params (*)(MarkerType)) &MarkerDetector::Params::create)
                ;
    }
    

    (如果你有兴趣,上面的命令行编译:)

    c++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` example.cpp -o example`python3-config --extension-suffix` -L /usr/local/Cellar/python3/3.6.4/Frameworks/Python.framework/Versions/3.6/lib/ -lpython3.6
    

    python代码:

    import sys
    sys.path.append('/Volumes/Programs/workspaces/workspace 1/Project CPP 2')
    
    import example
    
    mtype = example.MarkerType.chessboard
    print (mtype)
    
    x = example.MarkerDetectorParams.create(example.MarkerType.chessboard)
    print (x)
    print (x.rows)
    print (x.cols)
    
    y = example.MarkerDetectorParams.create(example.MarkerType.tag)
    print (y)
    print (y.rows)
    print (y.cols)
    

    这给出了以下输出,根据设计看起来是正确的:

    MarkerType.chessboard
    <example.MarkerDetectorParams object at 0x1043e35a8>
    1
    2
    <example.MarkerDetectorParams object at 0x1043e3768>
    3
    4
    

    我希望这能给你一些工作。问候,AS

    【讨论】:

      猜你喜欢
      • 2010-10-17
      • 1970-01-01
      • 2011-06-04
      • 1970-01-01
      • 2011-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多