I have my own C++ that I'm trying to generate python binding using Pybind11:
auto markerParams = MarkerDetector::Params::create(MarkerType::chessboard);
markerDetector.detect(image, markerParams);
I have problem of generating binding for MarkerDetector::Params
struct since it's an inner struct constructed with a factory method that takes enum as parameter:
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];
}
};
};
Does any one know how to handle this more advanced case?
I've got a basic implementation of your code to run, using the inner struct as per your design. For brevity I've only included the relevant details for MarkerDetector and Params but it should match what you've done.
The c++ code:
#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)
;
}
(If you're interested, the command line to compile the above:)
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
The python code:
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)
This gives the following output, which appears correct as per the design:
MarkerType.chessboard
<example.MarkerDetectorParams object at 0x1043e35a8>
1
2
<example.MarkerDetectorParams object at 0x1043e3768>
3
4
I hope this gives you something to work from. Regards, AS
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With