Pybind11 用于 C++ 代码,内部结构通过静态工厂方法创建
Pybind11 for C++ code with inner struct created via static factory method
我有自己的 C++,我正在尝试使用 Pybind11 生成 python 绑定:
auto markerParams = MarkerDetector::Params::create(MarkerType::chessboard);
markerDetector.detect(image, markerParams);
我在为 MarkerDetector::Params
结构生成绑定时遇到问题,因为它是使用以枚举作为参数的工厂方法构造的内部结构:
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];
}
};
};
有人知道如何处理这种更高级的情况吗?
我已经根据您的设计使用内部结构对您的代码进行了基本实现 运行。为简洁起见,我只包含了 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
我有自己的 C++,我正在尝试使用 Pybind11 生成 python 绑定:
auto markerParams = MarkerDetector::Params::create(MarkerType::chessboard);
markerDetector.detect(image, markerParams);
我在为 MarkerDetector::Params
结构生成绑定时遇到问题,因为它是使用以枚举作为参数的工厂方法构造的内部结构:
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];
}
};
};
有人知道如何处理这种更高级的情况吗?
我已经根据您的设计使用内部结构对您的代码进行了基本实现 运行。为简洁起见,我只包含了 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