Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Opencv
提交
44290af5
O
Opencv
项目概览
Greenplum
/
Opencv
大约 1 年 前同步成功
通知
7
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
Opencv
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
44290af5
编写于
2月 08, 2023
作者:
A
Alexander Alekhin
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #23224 from VadimLevin:dev/vlevin/cxx-named-arguments
上级
649841e6
b07031b5
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
250 addition
and
60 deletion
+250
-60
modules/core/include/opencv2/core/bindings_utils.hpp
modules/core/include/opencv2/core/bindings_utils.hpp
+27
-0
modules/core/include/opencv2/core/cvdef.h
modules/core/include/opencv2/core/cvdef.h
+1
-0
modules/python/src2/gen2.py
modules/python/src2/gen2.py
+186
-59
modules/python/src2/hdr_parser.py
modules/python/src2/hdr_parser.py
+13
-1
modules/python/test/test_misc.py
modules/python/test/test_misc.py
+23
-0
未找到文件。
modules/core/include/opencv2/core/bindings_utils.hpp
浏览文件 @
44290af5
...
...
@@ -243,6 +243,33 @@ struct CV_EXPORTS_W_SIMPLE ClassWithKeywordProperties {
}
};
struct
CV_EXPORTS_W_PARAMS
FunctionParams
{
CV_PROP_RW
int
lambda
=
-
1
;
CV_PROP_RW
float
sigma
=
0.0
f
;
FunctionParams
&
setLambda
(
int
value
)
CV_NOEXCEPT
{
lambda
=
value
;
return
*
this
;
}
FunctionParams
&
setSigma
(
float
value
)
CV_NOEXCEPT
{
sigma
=
value
;
return
*
this
;
}
};
CV_WRAP
static
inline
String
copyMatAndDumpNamedArguments
(
InputArray
src
,
OutputArray
dst
,
const
FunctionParams
&
params
=
FunctionParams
())
{
src
.
copyTo
(
dst
);
return
format
(
"lambda=%d, sigma=%.1f"
,
params
.
lambda
,
params
.
sigma
);
}
namespace
nested
{
CV_WRAP
static
inline
bool
testEchoBooleanFunction
(
bool
flag
)
{
return
flag
;
...
...
modules/core/include/opencv2/core/cvdef.h
浏览文件 @
44290af5
...
...
@@ -459,6 +459,7 @@ Cv64suf;
#define CV_EXPORTS_W_SIMPLE CV_EXPORTS
#define CV_EXPORTS_AS(synonym) CV_EXPORTS
#define CV_EXPORTS_W_MAP CV_EXPORTS
#define CV_EXPORTS_W_PARAMS CV_EXPORTS
#define CV_IN_OUT
#define CV_OUT
#define CV_PROP
...
...
modules/python/src2/gen2.py
浏览文件 @
44290af5
...
...
@@ -241,6 +241,7 @@ class ClassProp(object):
def
__init__
(
self
,
decl
):
self
.
tp
=
decl
[
0
].
replace
(
"*"
,
"_ptr"
)
self
.
name
=
decl
[
1
]
self
.
default_value
=
decl
[
2
]
self
.
readonly
=
True
if
"/RW"
in
decl
[
3
]:
self
.
readonly
=
False
...
...
@@ -268,6 +269,7 @@ class ClassInfo(object):
self
.
cname
=
name
.
replace
(
"."
,
"::"
)
self
.
ismap
=
False
self
.
is_parameters
=
False
self
.
issimple
=
False
self
.
isalgorithm
=
False
self
.
methods
=
{}
...
...
@@ -300,6 +302,9 @@ class ClassInfo(object):
self
.
ismap
=
True
elif
m
==
"/Simple"
:
self
.
issimple
=
True
elif
m
==
"/Params"
:
self
.
is_parameters
=
True
self
.
issimple
=
True
self
.
props
=
[
ClassProp
(
p
)
for
p
in
decl
[
3
]]
if
not
self
.
has_export_alias
and
self
.
original_name
.
startswith
(
"Cv"
):
...
...
@@ -421,39 +426,55 @@ def handle_ptr(tp):
class
ArgInfo
(
object
):
def
__init__
(
self
,
arg_tuple
):
self
.
tp
=
handle_ptr
(
arg_tuple
[
0
])
self
.
name
=
arg_tuple
[
1
]
if
self
.
name
in
python_reserved_keywords
:
self
.
name
+=
"_"
self
.
defval
=
arg_tuple
[
2
]
def
__init__
(
self
,
atype
,
name
,
default_value
,
modifiers
=
(),
enclosing_arg
=
None
):
# type: (ArgInfo, str, str, str, tuple[str, ...], ArgInfo | None) -> None
self
.
tp
=
handle_ptr
(
atype
)
self
.
name
=
name
self
.
defval
=
default_value
self
.
_modifiers
=
tuple
(
modifiers
)
self
.
isarray
=
False
self
.
is_smart_ptr
=
self
.
tp
.
startswith
(
'Ptr<'
)
# FIXIT: handle through modifiers - need to modify parser
self
.
arraylen
=
0
self
.
arraycvt
=
None
self
.
inputarg
=
True
self
.
outputarg
=
False
self
.
returnarg
=
False
self
.
isrvalueref
=
False
for
m
in
arg_tuple
[
3
]:
if
m
==
"/O"
:
self
.
inputarg
=
False
self
.
outputarg
=
True
self
.
returnarg
=
True
elif
m
==
"/IO"
:
self
.
inputarg
=
True
self
.
outputarg
=
True
self
.
returnarg
=
True
elif
m
.
startswith
(
"/A"
):
for
m
in
self
.
_modifiers
:
if
m
.
startswith
(
"/A"
):
self
.
isarray
=
True
self
.
arraylen
=
m
[
2
:].
strip
()
elif
m
.
startswith
(
"/CA"
):
self
.
isarray
=
True
self
.
arraycvt
=
m
[
2
:].
strip
()
elif
m
==
"/RRef"
:
self
.
isrvalueref
=
True
self
.
py_inputarg
=
False
self
.
py_outputarg
=
False
self
.
enclosing_arg
=
enclosing_arg
@
property
def
export_name
(
self
):
if
self
.
name
in
python_reserved_keywords
:
return
self
.
name
+
'_'
return
self
.
name
@
property
def
inputarg
(
self
):
return
'/O'
not
in
self
.
_modifiers
@
property
def
outputarg
(
self
):
return
'/O'
in
self
.
_modifiers
or
'/IO'
in
self
.
_modifiers
@
property
def
returnarg
(
self
):
return
self
.
outputarg
@
property
def
isrvalueref
(
self
):
return
'/RRef'
in
self
.
_modifiers
@
property
def
full_name
(
self
):
if
self
.
enclosing_arg
is
None
:
return
self
.
name
return
self
.
enclosing_arg
.
name
+
'.'
+
self
.
name
def
isbig
(
self
):
return
self
.
tp
in
[
"Mat"
,
"vector_Mat"
,
"cuda::GpuMat"
,
"GpuMat"
,
"vector_GpuMat"
,
"UMat"
,
"vector_UMat"
]
# or self.tp.startswith("vector")
...
...
@@ -462,9 +483,62 @@ class ArgInfo(object):
return
"ArgInfo(
\"
%s
\"
, %d)"
%
(
self
.
name
,
self
.
outputarg
)
def
find_argument_class_info
(
argument_type
,
function_namespace
,
function_class_name
,
known_classes
):
# type: (str, str, str, dict[str, ClassInfo]) -> ClassInfo | None
"""Tries to find corresponding class info for the provided argument type
Args:
argument_type (str): Function argument type
function_namespace (str): Namespace of the function declaration
function_class_name (str): Name of the class if function is a method of class
known_classes (dict[str, ClassInfo]): Mapping between string class
identifier and ClassInfo struct.
Returns:
Optional[ClassInfo]: class info struct if the provided argument type
refers to a known C++ class, None otherwise.
"""
possible_classes
=
tuple
(
filter
(
lambda
cls
:
cls
.
endswith
(
argument_type
),
known_classes
))
# If argument type is not a known class - just skip it
if
not
possible_classes
:
return
None
if
len
(
possible_classes
)
==
1
:
return
known_classes
[
possible_classes
[
0
]]
# If there is more than 1 matched class, try to select the most probable one
# Look for a matched class name in different scope, starting from the
# narrowest one
# First try to find argument inside class scope of the function (if any)
if
function_class_name
:
type_to_match
=
function_class_name
+
'_'
+
argument_type
if
type_to_match
in
possible_classes
:
return
known_classes
[
type_to_match
]
else
:
type_to_match
=
argument_type
# Trying to find argument type in the namespace of the function
type_to_match
=
'{}_{}'
.
format
(
function_namespace
.
lstrip
(
'cv.'
).
replace
(
'.'
,
'_'
),
type_to_match
)
if
type_to_match
in
possible_classes
:
return
known_classes
[
type_to_match
]
# Try to find argument name as is
if
argument_type
in
possible_classes
:
return
known_classes
[
argument_type
]
# NOTE: parser is broken - some classes might not be visible, depending on
# the order of parsed headers.
# print("[WARNING] Can't select an appropriate class for argument: '",
# argument_type, "'. Possible matches: '", possible_classes, "'")
return
None
class
FuncVariant
(
object
):
def
__init__
(
self
,
classname
,
name
,
decl
,
isconstructor
,
isphantom
=
False
):
self
.
classname
=
classname
def
__init__
(
self
,
namespace
,
classname
,
name
,
decl
,
isconstructor
,
known_classes
,
isphantom
=
False
):
self
.
name
=
self
.
wname
=
name
self
.
isconstructor
=
isconstructor
self
.
isphantom
=
isphantom
...
...
@@ -476,8 +550,14 @@ class FuncVariant(object):
self
.
rettype
=
""
self
.
args
=
[]
self
.
array_counters
=
{}
for
a
in
decl
[
3
]:
ainfo
=
ArgInfo
(
a
)
for
arg_decl
in
decl
[
3
]:
assert
len
(
arg_decl
)
==
4
,
\
'ArgInfo contract is violated. Arg declaration should contain:'
\
'"arg_type", "name", "default_value", "modifiers". '
\
'Got tuple: {}'
.
format
(
arg_decl
)
ainfo
=
ArgInfo
(
atype
=
arg_decl
[
0
],
name
=
arg_decl
[
1
],
default_value
=
arg_decl
[
2
],
modifiers
=
arg_decl
[
3
])
if
ainfo
.
isarray
and
not
ainfo
.
arraycvt
:
c
=
ainfo
.
arraylen
c_arrlist
=
self
.
array_counters
.
get
(
c
,
[])
...
...
@@ -486,9 +566,9 @@ class FuncVariant(object):
else
:
self
.
array_counters
[
c
]
=
[
ainfo
.
name
]
self
.
args
.
append
(
ainfo
)
self
.
init_pyproto
()
self
.
init_pyproto
(
namespace
,
classname
,
known_classes
)
def
init_pyproto
(
self
):
def
init_pyproto
(
self
,
namespace
,
classname
,
known_classes
):
# string representation of argument list, with '[', ']' symbols denoting optional arguments, e.g.
# "src1, src2[, dst[, mask]]" for cv.add
argstr
=
""
...
...
@@ -510,12 +590,44 @@ class FuncVariant(object):
outlist
=
[]
firstoptarg
=
1000000
argno
=
-
1
for
a
in
self
.
args
:
argno
+=
1
# Check if there is params structure in arguments
arguments
=
[]
for
arg
in
self
.
args
:
arg_class_info
=
find_argument_class_info
(
arg
.
tp
,
namespace
,
classname
,
known_classes
)
# If argument refers to the 'named arguments' structure - instead of
# the argument put its properties
if
arg_class_info
is
not
None
and
arg_class_info
.
is_parameters
:
for
prop
in
arg_class_info
.
props
:
# Convert property to ArgIfno and mark that argument is
# a part of the parameters structure:
arguments
.
append
(
ArgInfo
(
prop
.
tp
,
prop
.
name
,
prop
.
default_value
,
enclosing_arg
=
arg
)
)
else
:
arguments
.
append
(
arg
)
# Prevent names duplication after named arguments are merged
# to the main arguments list
argument_names
=
tuple
(
arg
.
name
for
arg
in
arguments
)
assert
len
(
set
(
argument_names
))
==
len
(
argument_names
),
\
"Duplicate arguments with names '{}' in function '{}'. "
\
"Please, check named arguments used in function interface"
.
format
(
argument_names
,
self
.
name
)
self
.
args
=
arguments
for
argno
,
a
in
enumerate
(
self
.
args
):
if
a
.
name
in
self
.
array_counters
:
continue
assert
not
a
.
tp
in
forbidden_arg_types
,
'Forbidden type "{}" for argument "{}" in "{}" ("{}")'
.
format
(
a
.
tp
,
a
.
name
,
self
.
name
,
self
.
classname
)
assert
a
.
tp
not
in
forbidden_arg_types
,
\
'Forbidden type "{}" for argument "{}" in "{}" ("{}")'
.
format
(
a
.
tp
,
a
.
name
,
self
.
name
,
self
.
classname
)
if
a
.
tp
in
ignored_arg_types
:
continue
if
a
.
returnarg
:
...
...
@@ -542,7 +654,7 @@ class FuncVariant(object):
firstoptarg
=
min
(
firstoptarg
,
len
(
arglist
))
noptargs
=
len
(
arglist
)
-
firstoptarg
argnamelist
=
[
aname
for
aname
,
argno
in
arglist
]
argnamelist
=
[
self
.
args
[
argno
].
export_name
for
_
,
argno
in
arglist
]
argstr
=
", "
.
join
(
argnamelist
[:
firstoptarg
])
argstr
=
"[, "
.
join
([
argstr
]
+
argnamelist
[
firstoptarg
:])
argstr
+=
"]"
*
noptargs
...
...
@@ -552,9 +664,8 @@ class FuncVariant(object):
assert
outlist
==
[]
outlist
=
[(
"self"
,
-
1
)]
if
self
.
isconstructor
:
classname
=
self
.
classname
if
classname
.
startswith
(
"Cv"
):
classname
=
classname
[
2
:]
classname
=
classname
[
2
:]
outstr
=
"<%s object>"
%
(
classname
,)
elif
outlist
:
outstr
=
", "
.
join
([
o
[
0
]
for
o
in
outlist
])
...
...
@@ -566,9 +677,9 @@ class FuncVariant(object):
self
.
py_prototype
=
"%s(%s) -> %s"
%
(
self
.
wname
,
argstr
,
outstr
)
self
.
py_noptargs
=
noptargs
self
.
py_arglist
=
arglist
for
aname
,
argno
in
arglist
:
for
_
,
argno
in
arglist
:
self
.
args
[
argno
].
py_inputarg
=
True
for
aname
,
argno
in
outlist
:
for
_
,
argno
in
outlist
:
if
argno
>=
0
:
self
.
args
[
argno
].
py_outputarg
=
True
self
.
py_outlist
=
outlist
...
...
@@ -584,8 +695,11 @@ class FuncInfo(object):
self
.
is_static
=
is_static
self
.
variants
=
[]
def
add_variant
(
self
,
decl
,
isphantom
=
False
):
self
.
variants
.
append
(
FuncVariant
(
self
.
classname
,
self
.
name
,
decl
,
self
.
isconstructor
,
isphantom
))
def
add_variant
(
self
,
decl
,
known_classes
,
isphantom
=
False
):
self
.
variants
.
append
(
FuncVariant
(
self
.
namespace
,
self
.
classname
,
self
.
name
,
decl
,
self
.
isconstructor
,
known_classes
,
isphantom
)
)
def
get_wrapper_name
(
self
):
name
=
self
.
name
...
...
@@ -698,6 +812,7 @@ class FuncInfo(object):
# add necessary conversions from Python objects to code_cvt_list,
# form the function/method call,
# for the list of type mappings
instantiated_args
=
set
()
for
a
in
v
.
args
:
if
a
.
tp
in
ignored_arg_types
:
defval
=
a
.
defval
...
...
@@ -738,17 +853,29 @@ class FuncInfo(object):
arg_type_info
=
ArgTypeInfo
(
tp
,
FormatStrings
.
object
,
defval0
,
True
)
parse_name
=
a
.
name
if
a
.
py_inputarg
:
if
arg_type_info
.
strict_conversion
:
code_decl
+=
" PyObject* pyobj_%s = NULL;
\n
"
%
(
a
.
name
,)
parse_name
=
"pyobj_"
+
a
.
name
if
a
.
tp
==
'char'
:
code_cvt_list
.
append
(
"convert_to_char(pyobj_%s, &%s, %s)"
%
(
a
.
name
,
a
.
name
,
a
.
crepr
()))
else
:
code_cvt_list
.
append
(
"pyopencv_to_safe(pyobj_%s, %s, %s)"
%
(
a
.
name
,
a
.
name
,
a
.
crepr
()))
if
a
.
py_inputarg
and
arg_type_info
.
strict_conversion
:
parse_name
=
"pyobj_"
+
a
.
full_name
.
replace
(
'.'
,
'_'
)
code_decl
+=
" PyObject* %s = NULL;
\n
"
%
(
parse_name
,)
if
a
.
tp
==
'char'
:
code_cvt_list
.
append
(
"convert_to_char(%s, &%s, %s)"
%
(
parse_name
,
a
.
full_name
,
a
.
crepr
()))
else
:
code_cvt_list
.
append
(
"pyopencv_to_safe(%s, %s, %s)"
%
(
parse_name
,
a
.
full_name
,
a
.
crepr
()))
all_cargs
.
append
([
arg_type_info
,
parse_name
])
# Argument is actually a part of the named arguments structure,
# but it is possible to mimic further processing like it is normal arg
if
a
.
enclosing_arg
:
a
=
a
.
enclosing_arg
arg_type_info
=
ArgTypeInfo
(
a
.
tp
,
FormatStrings
.
object
,
default_value
=
a
.
defval
,
strict_conversion
=
True
)
# Skip further actions if enclosing argument is already instantiated
# by its another field
if
a
.
name
in
instantiated_args
:
continue
instantiated_args
.
add
(
a
.
name
)
defval
=
a
.
defval
if
not
defval
:
defval
=
arg_type_info
.
default_value
...
...
@@ -773,9 +900,9 @@ class FuncInfo(object):
code_args
+=
", "
if
a
.
isrvalueref
:
a
.
name
=
'std::move('
+
a
.
name
+
')'
code_args
+=
amp
+
a
.
name
code_args
+=
amp
+
'std::move('
+
a
.
name
+
')'
else
:
code_args
+=
amp
+
a
.
name
code_args
+=
")"
...
...
@@ -821,7 +948,7 @@ class FuncInfo(object):
# form the format spec for PyArg_ParseTupleAndKeywords
fmtspec
=
""
.
join
([
get_type_format_string
(
all_cargs
[
argno
][
0
])
for
aname
,
argno
in
v
.
py_arglist
for
_
,
argno
in
v
.
py_arglist
])
if
v
.
py_noptargs
>
0
:
fmtspec
=
fmtspec
[:
-
v
.
py_noptargs
]
+
"|"
+
fmtspec
[
-
v
.
py_noptargs
:]
...
...
@@ -832,10 +959,10 @@ class FuncInfo(object):
# - calls PyArg_ParseTupleAndKeywords
# - converts complex arguments from PyObject's to native OpenCV types
code_parse
=
gen_template_parse_args
.
substitute
(
kw_list
=
", "
.
join
([
'"'
+
aname
+
'"'
for
aname
,
argno
in
v
.
py_arglist
]),
fmtspec
=
fmtspec
,
parse_arglist
=
", "
.
join
([
"&"
+
all_cargs
[
argno
][
1
]
for
aname
,
argno
in
v
.
py_arglist
]),
code_cvt
=
" &&
\n
"
.
join
(
code_cvt_list
))
kw_list
=
", "
.
join
([
'"'
+
v
.
args
[
argno
].
export_name
+
'"'
for
_
,
argno
in
v
.
py_arglist
]),
fmtspec
=
fmtspec
,
parse_arglist
=
", "
.
join
([
"&"
+
all_cargs
[
argno
][
1
]
for
_
,
argno
in
v
.
py_arglist
]),
code_cvt
=
" &&
\n
"
.
join
(
code_cvt_list
))
else
:
code_parse
=
"if(PyObject_Size(py_args) == 0 && (!kw || PyObject_Size(kw) == 0))"
...
...
@@ -1036,7 +1163,7 @@ class PythonWrapperGenerator(object):
# Add it as a method to the class
func_map
=
self
.
classes
[
classname
].
methods
func
=
func_map
.
setdefault
(
name
,
FuncInfo
(
classname
,
name
,
cname
,
isconstructor
,
namespace_str
,
is_static
))
func
.
add_variant
(
decl
,
isphantom
)
func
.
add_variant
(
decl
,
self
.
classes
,
isphantom
)
# Add it as global function
g_name
=
"_"
.
join
(
classes
+
[
name
])
...
...
@@ -1053,10 +1180,10 @@ class PythonWrapperGenerator(object):
func_map
=
self
.
namespaces
.
setdefault
(
namespace_str
,
Namespace
()).
funcs
# Exports static function with internal name (backward compatibility)
func
=
func_map
.
setdefault
(
g_name
,
FuncInfo
(
""
,
g_name
,
cname
,
isconstructor
,
namespace_str
,
False
))
func
.
add_variant
(
decl
,
isphantom
)
func
.
add_variant
(
decl
,
self
.
classes
,
isphantom
)
if
g_wname
!=
g_name
:
# TODO OpenCV 5.0
wfunc
=
func_map
.
setdefault
(
g_wname
,
FuncInfo
(
""
,
g_wname
,
cname
,
isconstructor
,
namespace_str
,
False
))
wfunc
.
add_variant
(
decl
,
isphantom
)
wfunc
.
add_variant
(
decl
,
self
.
classes
,
isphantom
)
else
:
if
classname
and
not
isconstructor
:
if
not
isphantom
:
...
...
@@ -1066,7 +1193,7 @@ class PythonWrapperGenerator(object):
func_map
=
self
.
namespaces
.
setdefault
(
namespace_str
,
Namespace
()).
funcs
func
=
func_map
.
setdefault
(
name
,
FuncInfo
(
classname
,
name
,
cname
,
isconstructor
,
namespace_str
,
is_static
))
func
.
add_variant
(
decl
,
isphantom
)
func
.
add_variant
(
decl
,
self
.
classes
,
isphantom
)
if
classname
and
isconstructor
:
self
.
classes
[
classname
].
constructor
=
func
...
...
modules/python/src2/hdr_parser.py
浏览文件 @
44290af5
...
...
@@ -259,6 +259,10 @@ class CppHeaderParser(object):
if
"CV_EXPORTS_W_SIMPLE"
in
l
:
l
=
l
.
replace
(
"CV_EXPORTS_W_SIMPLE"
,
""
)
modlist
.
append
(
"/Simple"
)
if
"CV_EXPORTS_W_PARAMS"
in
l
:
l
=
l
.
replace
(
"CV_EXPORTS_W_PARAMS"
,
""
)
modlist
.
append
(
"/Map"
)
modlist
.
append
(
"/Params"
)
npos
=
l
.
find
(
"CV_EXPORTS_AS"
)
if
npos
<
0
:
npos
=
l
.
find
(
'CV_WRAP_AS'
)
...
...
@@ -776,7 +780,15 @@ class CppHeaderParser(object):
var_list
=
[
var_name1
]
+
[
i
.
strip
()
for
i
in
var_list
[
1
:]]
for
v
in
var_list
:
class_decl
[
3
].
append
([
var_type
,
v
,
""
,
var_modlist
])
prop_definition
=
v
.
split
(
'='
)
prop_name
=
prop_definition
[
0
].
strip
()
if
len
(
prop_definition
)
==
1
:
# default value is not provided
prop_default_value
=
''
else
:
prop_default_value
=
prop_definition
[
-
1
]
class_decl
[
3
].
append
([
var_type
,
prop_name
,
prop_default_value
,
var_modlist
])
return
stmt_type
,
""
,
False
,
None
# something unknown
...
...
modules/python/test/test_misc.py
浏览文件 @
44290af5
...
...
@@ -738,6 +738,29 @@ class Arguments(NewOpenCVTests):
)
)
def
test_named_arguments_without_parameters
(
self
):
src
=
np
.
ones
((
5
,
5
,
3
),
dtype
=
np
.
uint8
)
arguments_dump
,
src_copy
=
cv
.
utils
.
copyMatAndDumpNamedArguments
(
src
)
np
.
testing
.
assert_equal
(
src
,
src_copy
)
self
.
assertEqual
(
arguments_dump
,
'lambda=-1, sigma=0.0'
)
def
test_named_arguments_without_output_argument
(
self
):
src
=
np
.
zeros
((
2
,
2
,
3
),
dtype
=
np
.
uint8
)
arguments_dump
,
src_copy
=
cv
.
utils
.
copyMatAndDumpNamedArguments
(
src
,
lambda_
=
15
,
sigma
=
3.5
)
np
.
testing
.
assert_equal
(
src
,
src_copy
)
self
.
assertEqual
(
arguments_dump
,
'lambda=15, sigma=3.5'
)
def
test_named_arguments_with_output_argument
(
self
):
src
=
np
.
zeros
((
3
,
3
,
3
),
dtype
=
np
.
uint8
)
dst
=
np
.
ones_like
(
src
)
arguments_dump
,
src_copy
=
cv
.
utils
.
copyMatAndDumpNamedArguments
(
src
,
dst
,
lambda_
=
25
,
sigma
=
5.5
)
np
.
testing
.
assert_equal
(
src
,
src_copy
)
np
.
testing
.
assert_equal
(
dst
,
src_copy
)
self
.
assertEqual
(
arguments_dump
,
'lambda=25, sigma=5.5'
)
class
CanUsePurePythonModuleFunction
(
NewOpenCVTests
):
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录