Merge pull request #3131 from znah:python_namespaces
This commit is contained in:
commit
b56933d9dc
@ -14,16 +14,10 @@ endforeach(mp)
|
|||||||
|
|
||||||
# module blacklist
|
# module blacklist
|
||||||
ocv_list_filterout(candidate_deps "^opencv_cud(a|ev)")
|
ocv_list_filterout(candidate_deps "^opencv_cud(a|ev)")
|
||||||
ocv_list_filterout(candidate_deps "^opencv_adas$")
|
|
||||||
ocv_list_filterout(candidate_deps "^opencv_face$")
|
|
||||||
ocv_list_filterout(candidate_deps "^opencv_matlab$")
|
ocv_list_filterout(candidate_deps "^opencv_matlab$")
|
||||||
ocv_list_filterout(candidate_deps "^opencv_tracking$")
|
|
||||||
ocv_list_filterout(candidate_deps "^opencv_optflow$")
|
|
||||||
ocv_list_filterout(candidate_deps "^opencv_bgsegm$")
|
|
||||||
ocv_list_filterout(candidate_deps "^opencv_xfeatures2d$")
|
|
||||||
ocv_list_filterout(candidate_deps "^opencv_ximgproc$")
|
|
||||||
ocv_list_filterout(candidate_deps "^opencv_xphoto$")
|
|
||||||
ocv_list_filterout(candidate_deps "^opencv_ts$")
|
ocv_list_filterout(candidate_deps "^opencv_ts$")
|
||||||
|
ocv_list_filterout(candidate_deps "^opencv_adas$")
|
||||||
|
ocv_list_filterout(candidate_deps "^opencv_tracking$")
|
||||||
|
|
||||||
ocv_add_module(${MODULE_NAME} BINDINGS OPTIONAL ${candidate_deps})
|
ocv_add_module(${MODULE_NAME} BINDINGS OPTIONAL ${candidate_deps})
|
||||||
|
|
||||||
@ -43,15 +37,14 @@ ocv_list_filterout(opencv_hdrs ".h$")
|
|||||||
ocv_list_filterout(opencv_hdrs "cuda")
|
ocv_list_filterout(opencv_hdrs "cuda")
|
||||||
ocv_list_filterout(opencv_hdrs "cudev")
|
ocv_list_filterout(opencv_hdrs "cudev")
|
||||||
ocv_list_filterout(opencv_hdrs "opencv2/objdetect/detection_based_tracker.hpp")
|
ocv_list_filterout(opencv_hdrs "opencv2/objdetect/detection_based_tracker.hpp")
|
||||||
ocv_list_filterout(opencv_hdrs "opencv2/optim.hpp")
|
ocv_list_filterout(opencv_hdrs "opencv2/ximgproc/structured_edge_detection.hpp")
|
||||||
|
|
||||||
set(cv2_generated_hdrs
|
set(cv2_generated_hdrs
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_include.h"
|
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_include.h"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_funcs.h"
|
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_funcs.h"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_func_tab.h"
|
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_types.h"
|
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_types.h"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_type_reg.h"
|
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_type_reg.h"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_const_reg.h")
|
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_ns_reg.h")
|
||||||
|
|
||||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/headers.txt" "${opencv_hdrs}")
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/headers.txt" "${opencv_hdrs}")
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
|
@ -83,8 +83,6 @@ catch (const cv::Exception &e) \
|
|||||||
}
|
}
|
||||||
|
|
||||||
using namespace cv;
|
using namespace cv;
|
||||||
using cv::flann::IndexParams;
|
|
||||||
using cv::flann::SearchParams;
|
|
||||||
|
|
||||||
typedef std::vector<uchar> vector_uchar;
|
typedef std::vector<uchar> vector_uchar;
|
||||||
typedef std::vector<char> vector_char;
|
typedef std::vector<char> vector_char;
|
||||||
@ -1194,9 +1192,7 @@ static int convert_to_char(PyObject *o, char *dst, const char *name = "no_name")
|
|||||||
#include "pyopencv_generated_types.h"
|
#include "pyopencv_generated_types.h"
|
||||||
#include "pyopencv_generated_funcs.h"
|
#include "pyopencv_generated_funcs.h"
|
||||||
|
|
||||||
static PyMethodDef methods[] = {
|
static PyMethodDef special_methods[] = {
|
||||||
|
|
||||||
#include "pyopencv_generated_func_tab.h"
|
|
||||||
{"createTrackbar", pycvCreateTrackbar, METH_VARARGS, "createTrackbar(trackbarName, windowName, value, count, onChange) -> None"},
|
{"createTrackbar", pycvCreateTrackbar, METH_VARARGS, "createTrackbar(trackbarName, windowName, value, count, onChange) -> None"},
|
||||||
{"setMouseCallback", (PyCFunction)pycvSetMouseCallback, METH_VARARGS | METH_KEYWORDS, "setMouseCallback(windowName, onMouse [, param]) -> None"},
|
{"setMouseCallback", (PyCFunction)pycvSetMouseCallback, METH_VARARGS | METH_KEYWORDS, "setMouseCallback(windowName, onMouse [, param]) -> None"},
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
@ -1205,6 +1201,53 @@ static PyMethodDef methods[] = {
|
|||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* Module init */
|
/* Module init */
|
||||||
|
|
||||||
|
struct ConstDef
|
||||||
|
{
|
||||||
|
const char * name;
|
||||||
|
long val;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void init_submodule(PyObject * root, const char * name, PyMethodDef * methods, ConstDef * consts)
|
||||||
|
{
|
||||||
|
// traverse and create nested submodules
|
||||||
|
std::string s = name;
|
||||||
|
size_t i = s.find('.');
|
||||||
|
while (i < s.length() && i != std::string::npos)
|
||||||
|
{
|
||||||
|
size_t j = s.find('.', i);
|
||||||
|
if (j == std::string::npos)
|
||||||
|
j = s.length();
|
||||||
|
std::string short_name = s.substr(i, j-i);
|
||||||
|
std::string full_name = s.substr(0, j);
|
||||||
|
i = j+1;
|
||||||
|
|
||||||
|
PyObject * d = PyModule_GetDict(root);
|
||||||
|
PyObject * submod = PyDict_GetItemString(d, short_name.c_str());
|
||||||
|
if (submod == NULL)
|
||||||
|
{
|
||||||
|
submod = PyImport_AddModule(full_name.c_str());
|
||||||
|
PyDict_SetItemString(d, short_name.c_str(), submod);
|
||||||
|
}
|
||||||
|
root = submod;
|
||||||
|
}
|
||||||
|
|
||||||
|
// populate module's dict
|
||||||
|
PyObject * d = PyModule_GetDict(root);
|
||||||
|
for (PyMethodDef * m = methods; m->ml_name != NULL; ++m)
|
||||||
|
{
|
||||||
|
PyObject * method_obj = PyCFunction_NewEx(m, NULL, NULL);
|
||||||
|
PyDict_SetItemString(d, m->ml_name, method_obj);
|
||||||
|
Py_DECREF(method_obj);
|
||||||
|
}
|
||||||
|
for (ConstDef * c = consts; c->name != NULL; ++c)
|
||||||
|
{
|
||||||
|
PyDict_SetItemString(d, c->name, PyInt_FromLong(c->val));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "pyopencv_generated_ns_reg.h"
|
||||||
|
|
||||||
static int to_ok(PyTypeObject *to)
|
static int to_ok(PyTypeObject *to)
|
||||||
{
|
{
|
||||||
to->tp_alloc = PyType_GenericAlloc;
|
to->tp_alloc = PyType_GenericAlloc;
|
||||||
@ -1223,7 +1266,7 @@ static struct PyModuleDef cv2_moduledef =
|
|||||||
"Python wrapper for OpenCV.",
|
"Python wrapper for OpenCV.",
|
||||||
-1, /* size of per-interpreter state of the module,
|
-1, /* size of per-interpreter state of the module,
|
||||||
or -1 if the module keeps state in global variables. */
|
or -1 if the module keeps state in global variables. */
|
||||||
methods
|
special_methods
|
||||||
};
|
};
|
||||||
|
|
||||||
PyObject* PyInit_cv2()
|
PyObject* PyInit_cv2()
|
||||||
@ -1240,8 +1283,10 @@ void initcv2()
|
|||||||
#if PY_MAJOR_VERSION >= 3
|
#if PY_MAJOR_VERSION >= 3
|
||||||
PyObject* m = PyModule_Create(&cv2_moduledef);
|
PyObject* m = PyModule_Create(&cv2_moduledef);
|
||||||
#else
|
#else
|
||||||
PyObject* m = Py_InitModule(MODULESTR, methods);
|
PyObject* m = Py_InitModule(MODULESTR, special_methods);
|
||||||
#endif
|
#endif
|
||||||
|
init_submodules(m); // from "pyopencv_generated_ns_reg.h"
|
||||||
|
|
||||||
PyObject* d = PyModule_GetDict(m);
|
PyObject* d = PyModule_GetDict(m);
|
||||||
|
|
||||||
PyDict_SetItemString(d, "__version__", PyString_FromString(CV_VERSION));
|
PyDict_SetItemString(d, "__version__", PyString_FromString(CV_VERSION));
|
||||||
@ -1289,7 +1334,6 @@ void initcv2()
|
|||||||
PUBLISH(CV_64FC3);
|
PUBLISH(CV_64FC3);
|
||||||
PUBLISH(CV_64FC4);
|
PUBLISH(CV_64FC4);
|
||||||
|
|
||||||
#include "pyopencv_generated_const_reg.h"
|
|
||||||
#if PY_MAJOR_VERSION >= 3
|
#if PY_MAJOR_VERSION >= 3
|
||||||
return m;
|
return m;
|
||||||
#endif
|
#endif
|
||||||
|
@ -267,7 +267,7 @@ class ClassInfo(object):
|
|||||||
#return sys.exit(-1)
|
#return sys.exit(-1)
|
||||||
if self.bases and self.bases[0].startswith("cv::"):
|
if self.bases and self.bases[0].startswith("cv::"):
|
||||||
self.bases[0] = self.bases[0][4:]
|
self.bases[0] = self.bases[0][4:]
|
||||||
if self.bases and self.bases[0] == "cv::Algorithm":
|
if self.bases and self.bases[0] == "Algorithm":
|
||||||
self.isalgorithm = True
|
self.isalgorithm = True
|
||||||
for m in decl[2]:
|
for m in decl[2]:
|
||||||
if m.startswith("="):
|
if m.startswith("="):
|
||||||
@ -341,16 +341,6 @@ class ClassInfo(object):
|
|||||||
return code
|
return code
|
||||||
|
|
||||||
|
|
||||||
class ConstInfo(object):
|
|
||||||
def __init__(self, name, val):
|
|
||||||
self.cname = name.replace(".", "::")
|
|
||||||
self.name = re.sub(r"^cv\.", "", name).replace(".", "_")
|
|
||||||
if self.name.startswith("Cv"):
|
|
||||||
self.name = self.name[2:]
|
|
||||||
self.name = re.sub(r"([a-z])([A-Z])", r"\1_\2", self.name)
|
|
||||||
self.name = self.name.upper()
|
|
||||||
self.value = val
|
|
||||||
|
|
||||||
def handle_ptr(tp):
|
def handle_ptr(tp):
|
||||||
if tp.startswith('Ptr_'):
|
if tp.startswith('Ptr_'):
|
||||||
tp = 'Ptr<' + "::".join(tp.split('_')[1:]) + '>'
|
tp = 'Ptr<' + "::".join(tp.split('_')[1:]) + '>'
|
||||||
@ -398,11 +388,6 @@ class FuncVariant(object):
|
|||||||
self.classname = classname
|
self.classname = classname
|
||||||
self.name = self.wname = name
|
self.name = self.wname = name
|
||||||
self.isconstructor = isconstructor
|
self.isconstructor = isconstructor
|
||||||
if self.isconstructor:
|
|
||||||
if self.wname.startswith("Cv"):
|
|
||||||
self.wname = self.wname[2:]
|
|
||||||
else:
|
|
||||||
self.wname = self.classname
|
|
||||||
|
|
||||||
self.rettype = handle_ptr(decl[1])
|
self.rettype = handle_ptr(decl[1])
|
||||||
if self.rettype == "void":
|
if self.rettype == "void":
|
||||||
@ -505,11 +490,12 @@ class FuncVariant(object):
|
|||||||
|
|
||||||
|
|
||||||
class FuncInfo(object):
|
class FuncInfo(object):
|
||||||
def __init__(self, classname, name, cname, isconstructor):
|
def __init__(self, classname, name, cname, isconstructor, namespace):
|
||||||
self.classname = classname
|
self.classname = classname
|
||||||
self.name = name
|
self.name = name
|
||||||
self.cname = cname
|
self.cname = cname
|
||||||
self.isconstructor = isconstructor
|
self.isconstructor = isconstructor
|
||||||
|
self.namespace = namespace
|
||||||
self.variants = []
|
self.variants = []
|
||||||
|
|
||||||
def add_variant(self, decl):
|
def add_variant(self, decl):
|
||||||
@ -523,7 +509,7 @@ class FuncInfo(object):
|
|||||||
name = "getelem"
|
name = "getelem"
|
||||||
else:
|
else:
|
||||||
classname = ""
|
classname = ""
|
||||||
return "pyopencv_" + classname + name
|
return "pyopencv_" + self.namespace.replace('.','_') + '_' + classname + name
|
||||||
|
|
||||||
def get_wrapper_prototype(self):
|
def get_wrapper_prototype(self):
|
||||||
full_fname = self.get_wrapper_name()
|
full_fname = self.get_wrapper_name()
|
||||||
@ -560,6 +546,7 @@ class FuncInfo(object):
|
|||||||
def gen_code(self, all_classes):
|
def gen_code(self, all_classes):
|
||||||
proto = self.get_wrapper_prototype()
|
proto = self.get_wrapper_prototype()
|
||||||
code = "%s\n{\n" % (proto,)
|
code = "%s\n{\n" % (proto,)
|
||||||
|
code += " using namespace %s;\n\n" % self.namespace.replace('.', '::')
|
||||||
|
|
||||||
selfinfo = ClassInfo("")
|
selfinfo = ClassInfo("")
|
||||||
ismethod = self.classname != "" and not self.isconstructor
|
ismethod = self.classname != "" and not self.isconstructor
|
||||||
@ -734,20 +721,25 @@ class FuncInfo(object):
|
|||||||
return code
|
return code
|
||||||
|
|
||||||
|
|
||||||
|
class Namespace(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.funcs = {}
|
||||||
|
self.consts = {}
|
||||||
|
|
||||||
|
|
||||||
class PythonWrapperGenerator(object):
|
class PythonWrapperGenerator(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.clear()
|
self.clear()
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self.classes = {}
|
self.classes = {}
|
||||||
self.funcs = {}
|
self.namespaces = {}
|
||||||
self.consts = {}
|
self.consts = {}
|
||||||
self.code_include = StringIO()
|
self.code_include = StringIO()
|
||||||
self.code_types = StringIO()
|
self.code_types = StringIO()
|
||||||
self.code_funcs = StringIO()
|
self.code_funcs = StringIO()
|
||||||
self.code_func_tab = StringIO()
|
|
||||||
self.code_type_reg = StringIO()
|
self.code_type_reg = StringIO()
|
||||||
self.code_const_reg = StringIO()
|
self.code_ns_reg = StringIO()
|
||||||
self.class_idx = 0
|
self.class_idx = 0
|
||||||
|
|
||||||
def add_class(self, stype, name, decl):
|
def add_class(self, stype, name, decl):
|
||||||
@ -760,65 +752,100 @@ class PythonWrapperGenerator(object):
|
|||||||
% (classinfo.name, classinfo.cname))
|
% (classinfo.name, classinfo.cname))
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
self.classes[classinfo.name] = classinfo
|
self.classes[classinfo.name] = classinfo
|
||||||
if classinfo.bases and not classinfo.isalgorithm:
|
|
||||||
classinfo.isalgorithm = self.classes[classinfo.bases[0].replace("::", "_")].isalgorithm
|
if classinfo.bases:
|
||||||
|
chunks = classinfo.bases[0].split('::')
|
||||||
|
base = '_'.join(chunks)
|
||||||
|
while base not in self.classes and len(chunks)>1:
|
||||||
|
del chunks[-2]
|
||||||
|
base = '_'.join(chunks)
|
||||||
|
if base not in self.classes:
|
||||||
|
print("Generator error: unable to resolve base %s for %s"
|
||||||
|
% (classinfo.bases[0], classinfo.name))
|
||||||
|
sys.exit(-1)
|
||||||
|
classinfo.bases[0] = "::".join(chunks)
|
||||||
|
classinfo.isalgorithm |= self.classes[base].isalgorithm
|
||||||
|
|
||||||
|
def split_decl_name(self, name):
|
||||||
|
chunks = name.split('.')
|
||||||
|
namespace = chunks[:-1]
|
||||||
|
classes = []
|
||||||
|
while namespace and '.'.join(namespace) not in self.parser.namespaces:
|
||||||
|
classes.insert(0, namespace.pop())
|
||||||
|
return namespace, classes, chunks[-1]
|
||||||
|
|
||||||
|
|
||||||
def add_const(self, name, decl):
|
def add_const(self, name, decl):
|
||||||
constinfo = ConstInfo(name, decl[1])
|
cname = name.replace('.','::')
|
||||||
|
namespace, classes, name = self.split_decl_name(name)
|
||||||
if constinfo.name in self.consts:
|
namespace = '.'.join(namespace)
|
||||||
|
name = '_'.join(classes+[name])
|
||||||
|
ns = self.namespaces.setdefault(namespace, Namespace())
|
||||||
|
if name in ns.consts:
|
||||||
print("Generator error: constant %s (cname=%s) already exists" \
|
print("Generator error: constant %s (cname=%s) already exists" \
|
||||||
% (constinfo.name, constinfo.cname))
|
% (name, cname))
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
self.consts[constinfo.name] = constinfo
|
ns.consts[name] = cname
|
||||||
|
|
||||||
def add_func(self, decl):
|
def add_func(self, decl):
|
||||||
classname = bareclassname = ""
|
namespace, classes, barename = self.split_decl_name(decl[0])
|
||||||
name = decl[0]
|
cname = "::".join(namespace+classes+[barename])
|
||||||
dpos = name.rfind(".")
|
name = barename
|
||||||
if dpos >= 0 and name[:dpos] not in ["cv", "cv.ocl"]:
|
classname = ''
|
||||||
classname = bareclassname = re.sub(r"^cv\.", "", name[:dpos])
|
bareclassname = ''
|
||||||
name = name[dpos+1:]
|
if classes:
|
||||||
dpos = classname.rfind(".")
|
classname = normalize_class_name('.'.join(namespace+classes))
|
||||||
if dpos >= 0:
|
bareclassname = classes[-1]
|
||||||
bareclassname = classname[dpos+1:]
|
namespace = '.'.join(namespace)
|
||||||
classname = classname.replace(".", "_")
|
|
||||||
cname = name
|
isconstructor = name == bareclassname
|
||||||
name = re.sub(r"^cv\.", "", name)
|
|
||||||
name = name.replace(".", "_")
|
|
||||||
isconstructor = cname == bareclassname
|
|
||||||
cname = cname.replace(".", "::")
|
|
||||||
isclassmethod = False
|
isclassmethod = False
|
||||||
customname = False
|
|
||||||
for m in decl[2]:
|
for m in decl[2]:
|
||||||
if m == "/S":
|
if m == "/S":
|
||||||
isclassmethod = True
|
isclassmethod = True
|
||||||
elif m.startswith("="):
|
elif m.startswith("="):
|
||||||
name = m[1:]
|
name = m[1:]
|
||||||
customname = True
|
if isclassmethod:
|
||||||
func_map = self.funcs
|
name = "_".join(classes+[name])
|
||||||
|
classname = ''
|
||||||
|
elif isconstructor:
|
||||||
|
name = "_".join(classes[:-1]+[name])
|
||||||
|
|
||||||
if not classname or isconstructor:
|
if classname and not isconstructor:
|
||||||
pass
|
cname = barename
|
||||||
elif isclassmethod:
|
func_map = self.classes[classname].methods
|
||||||
if not customname:
|
|
||||||
name = classname + "_" + name
|
|
||||||
cname = classname + "::" + cname
|
|
||||||
classname = ""
|
|
||||||
else:
|
else:
|
||||||
classinfo = self.classes.get(classname, ClassInfo(""))
|
func_map = self.namespaces.setdefault(namespace, Namespace()).funcs
|
||||||
if not classinfo.name:
|
|
||||||
print("Generator error: the class for method %s is missing" % (name,))
|
|
||||||
sys.exit(-1)
|
|
||||||
func_map = classinfo.methods
|
|
||||||
|
|
||||||
func = func_map.get(name, FuncInfo(classname, name, cname, isconstructor))
|
func = func_map.setdefault(name, FuncInfo(classname, name, cname, isconstructor, namespace))
|
||||||
func.add_variant(decl)
|
func.add_variant(decl)
|
||||||
if len(func.variants) == 1:
|
|
||||||
func_map[name] = func
|
|
||||||
|
|
||||||
def gen_const_reg(self, constinfo):
|
|
||||||
self.code_const_reg.write("PUBLISH2(%s,%s);\n" % (constinfo.name, constinfo.cname))
|
def gen_namespace(self, ns_name):
|
||||||
|
ns = self.namespaces[ns_name]
|
||||||
|
wname = normalize_class_name(ns_name)
|
||||||
|
|
||||||
|
self.code_ns_reg.write('static PyMethodDef methods_%s[] = {\n'%wname)
|
||||||
|
for name, func in sorted(ns.funcs.items()):
|
||||||
|
self.code_ns_reg.write(func.get_tab_entry())
|
||||||
|
self.code_ns_reg.write(' {NULL, NULL}\n};\n\n')
|
||||||
|
|
||||||
|
self.code_ns_reg.write('static ConstDef consts_%s[] = {\n'%wname)
|
||||||
|
for name, cname in sorted(ns.consts.items()):
|
||||||
|
self.code_ns_reg.write(' {"%s", %s},\n'%(name, cname))
|
||||||
|
compat_name = re.sub(r"([a-z])([A-Z])", r"\1_\2", name).upper()
|
||||||
|
if name != compat_name:
|
||||||
|
self.code_ns_reg.write(' {"%s", %s},\n'%(compat_name, cname))
|
||||||
|
self.code_ns_reg.write(' {NULL, 0}\n};\n\n')
|
||||||
|
|
||||||
|
def gen_namespaces_reg(self):
|
||||||
|
self.code_ns_reg.write('static void init_submodules(PyObject * root) \n{\n')
|
||||||
|
for ns_name in sorted(self.namespaces):
|
||||||
|
if ns_name.split('.')[0] == 'cv':
|
||||||
|
wname = normalize_class_name(ns_name)
|
||||||
|
self.code_ns_reg.write(' init_submodule(root, MODULESTR"%s", methods_%s, consts_%s);\n' % (ns_name[2:], wname, wname))
|
||||||
|
self.code_ns_reg.write('};\n')
|
||||||
|
|
||||||
|
|
||||||
def save(self, path, name, buf):
|
def save(self, path, name, buf):
|
||||||
f = open(path + "/" + name, "wt")
|
f = open(path + "/" + name, "wt")
|
||||||
@ -827,11 +854,11 @@ class PythonWrapperGenerator(object):
|
|||||||
|
|
||||||
def gen(self, srcfiles, output_path):
|
def gen(self, srcfiles, output_path):
|
||||||
self.clear()
|
self.clear()
|
||||||
parser = hdr_parser.CppHeaderParser()
|
self.parser = hdr_parser.CppHeaderParser()
|
||||||
|
|
||||||
# step 1: scan the headers and build more descriptive maps of classes, consts, functions
|
# step 1: scan the headers and build more descriptive maps of classes, consts, functions
|
||||||
for hdr in srcfiles:
|
for hdr in srcfiles:
|
||||||
decls = parser.parse(hdr)
|
decls = self.parser.parse(hdr)
|
||||||
if len(decls) == 0:
|
if len(decls) == 0:
|
||||||
continue
|
continue
|
||||||
self.code_include.write( '#include "{}"\n'.format(hdr[hdr.rindex('opencv2/'):]) )
|
self.code_include.write( '#include "{}"\n'.format(hdr[hdr.rindex('opencv2/'):]) )
|
||||||
@ -876,12 +903,14 @@ class PythonWrapperGenerator(object):
|
|||||||
self.code_type_reg.write("MKTYPE2(%s);\n" % (classinfo.name,) )
|
self.code_type_reg.write("MKTYPE2(%s);\n" % (classinfo.name,) )
|
||||||
|
|
||||||
# step 3: generate the code for all the global functions
|
# step 3: generate the code for all the global functions
|
||||||
funclist = list(self.funcs.items())
|
for ns_name, ns in sorted(self.namespaces.items()):
|
||||||
funclist.sort()
|
if ns_name.split('.')[0] != 'cv':
|
||||||
for name, func in funclist:
|
continue
|
||||||
|
for name, func in sorted(ns.funcs.items()):
|
||||||
code = func.gen_code(self.classes)
|
code = func.gen_code(self.classes)
|
||||||
self.code_funcs.write(code)
|
self.code_funcs.write(code)
|
||||||
self.code_func_tab.write(func.get_tab_entry())
|
self.gen_namespace(ns_name)
|
||||||
|
self.gen_namespaces_reg()
|
||||||
|
|
||||||
# step 4: generate the code for constants
|
# step 4: generate the code for constants
|
||||||
constlist = list(self.consts.items())
|
constlist = list(self.consts.items())
|
||||||
@ -892,10 +921,9 @@ class PythonWrapperGenerator(object):
|
|||||||
# That's it. Now save all the files
|
# That's it. Now save all the files
|
||||||
self.save(output_path, "pyopencv_generated_include.h", self.code_include)
|
self.save(output_path, "pyopencv_generated_include.h", self.code_include)
|
||||||
self.save(output_path, "pyopencv_generated_funcs.h", self.code_funcs)
|
self.save(output_path, "pyopencv_generated_funcs.h", self.code_funcs)
|
||||||
self.save(output_path, "pyopencv_generated_func_tab.h", self.code_func_tab)
|
|
||||||
self.save(output_path, "pyopencv_generated_const_reg.h", self.code_const_reg)
|
|
||||||
self.save(output_path, "pyopencv_generated_types.h", self.code_types)
|
self.save(output_path, "pyopencv_generated_types.h", self.code_types)
|
||||||
self.save(output_path, "pyopencv_generated_type_reg.h", self.code_type_reg)
|
self.save(output_path, "pyopencv_generated_type_reg.h", self.code_type_reg)
|
||||||
|
self.save(output_path, "pyopencv_generated_ns_reg.h", self.code_ns_reg)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
srcfiles = hdr_parser.opencv_hdr_list
|
srcfiles = hdr_parser.opencv_hdr_list
|
||||||
|
@ -38,6 +38,8 @@ class CppHeaderParser(object):
|
|||||||
self.PUBLIC_SECTION = 3
|
self.PUBLIC_SECTION = 3
|
||||||
self.CLASS_DECL = 4
|
self.CLASS_DECL = 4
|
||||||
|
|
||||||
|
self.namespaces = set()
|
||||||
|
|
||||||
def batch_replace(self, s, pairs):
|
def batch_replace(self, s, pairs):
|
||||||
for before, after in pairs:
|
for before, after in pairs:
|
||||||
s = s.replace(before, after)
|
s = s.replace(before, after)
|
||||||
@ -833,6 +835,9 @@ class CppHeaderParser(object):
|
|||||||
decls.append(d)
|
decls.append(d)
|
||||||
else:
|
else:
|
||||||
decls.append(decl)
|
decls.append(decl)
|
||||||
|
if stmt_type == "namespace":
|
||||||
|
chunks = [block[1] for block in self.block_stack if block[0] == 'namespace'] + [name]
|
||||||
|
self.namespaces.add('.'.join(chunks))
|
||||||
else:
|
else:
|
||||||
stmt_type, name, parse_flag = "block", "", False
|
stmt_type, name, parse_flag = "block", "", False
|
||||||
|
|
||||||
@ -877,3 +882,4 @@ if __name__ == '__main__':
|
|||||||
#decls += parser.parse(hname, wmode=False)
|
#decls += parser.parse(hname, wmode=False)
|
||||||
parser.print_decls(decls)
|
parser.print_decls(decls)
|
||||||
print(len(decls))
|
print(len(decls))
|
||||||
|
print("namespaces:", " ".join(sorted(parser.namespaces)))
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
Feature-based image matching sample.
|
Feature-based image matching sample.
|
||||||
|
|
||||||
USAGE
|
USAGE
|
||||||
find_obj.py [--feature=<sift|surf|orb|brisk>[-flann]] [ <image1> <image2> ]
|
find_obj.py [--feature=<sift|surf|orb|akaze|brisk>[-flann]] [ <image1> <image2> ]
|
||||||
|
|
||||||
--feature - Feature to use. Can be sift, surf, orb or brisk. Append '-flann'
|
--feature - Feature to use. Can be sift, surf, orb or brisk. Append '-flann'
|
||||||
to feature name to use Flann-based matcher instead bruteforce.
|
to feature name to use Flann-based matcher instead bruteforce.
|
||||||
@ -23,14 +23,17 @@ FLANN_INDEX_LSH = 6
|
|||||||
def init_feature(name):
|
def init_feature(name):
|
||||||
chunks = name.split('-')
|
chunks = name.split('-')
|
||||||
if chunks[0] == 'sift':
|
if chunks[0] == 'sift':
|
||||||
detector = cv2.SIFT()
|
detector = cv2.xfeatures2d.SIFT()
|
||||||
norm = cv2.NORM_L2
|
norm = cv2.NORM_L2
|
||||||
elif chunks[0] == 'surf':
|
elif chunks[0] == 'surf':
|
||||||
detector = cv2.SURF(800)
|
detector = cv2.xfeatures2d.SURF(800)
|
||||||
norm = cv2.NORM_L2
|
norm = cv2.NORM_L2
|
||||||
elif chunks[0] == 'orb':
|
elif chunks[0] == 'orb':
|
||||||
detector = cv2.ORB(400)
|
detector = cv2.ORB(400)
|
||||||
norm = cv2.NORM_HAMMING
|
norm = cv2.NORM_HAMMING
|
||||||
|
elif chunks[0] == 'akaze':
|
||||||
|
detector = cv2.AKAZE()
|
||||||
|
norm = cv2.NORM_HAMMING
|
||||||
elif chunks[0] == 'brisk':
|
elif chunks[0] == 'brisk':
|
||||||
detector = cv2.BRISK()
|
detector = cv2.BRISK()
|
||||||
norm = cv2.NORM_HAMMING
|
norm = cv2.NORM_HAMMING
|
||||||
@ -136,8 +139,8 @@ if __name__ == '__main__':
|
|||||||
try:
|
try:
|
||||||
fn1, fn2 = args
|
fn1, fn2 = args
|
||||||
except:
|
except:
|
||||||
fn1 = '../c/box.png'
|
fn1 = '../cpp/box.png'
|
||||||
fn2 = '../c/box_in_scene.png'
|
fn2 = '../cpp/box_in_scene.png'
|
||||||
|
|
||||||
img1 = cv2.imread(fn1, 0)
|
img1 = cv2.imread(fn1, 0)
|
||||||
img2 = cv2.imread(fn2, 0)
|
img2 = cv2.imread(fn2, 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user