Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenCV
opencv
提交
eb68476a
O
opencv
项目概览
OpenCV
/
opencv
上一次同步 8 个月
通知
985
Star
71100
Fork
55581
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
opencv
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
eb68476a
编写于
7月 01, 2021
作者:
M
Maxim Pashchenkov
提交者:
Alexander Alekhin
10月 12, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
G-API: Python. Desync.
* Desync. GMat. * Alignment original commit:
05f1939b
上级
8d0fc8bf
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
334 addition
and
69 deletion
+334
-69
modules/gapi/include/opencv2/gapi/gstreaming.hpp
modules/gapi/include/opencv2/gapi/gstreaming.hpp
+10
-1
modules/gapi/misc/python/pyopencv_gapi.hpp
modules/gapi/misc/python/pyopencv_gapi.hpp
+77
-35
modules/gapi/misc/python/shadow_gapi.hpp
modules/gapi/misc/python/shadow_gapi.hpp
+17
-14
modules/gapi/misc/python/test/test_gapi_streaming.py
modules/gapi/misc/python/test/test_gapi_streaming.py
+66
-2
modules/gapi/src/compiler/gstreaming.cpp
modules/gapi/src/compiler/gstreaming.cpp
+7
-11
modules/gapi/src/compiler/gstreaming_priv.hpp
modules/gapi/src/compiler/gstreaming_priv.hpp
+1
-0
modules/gapi/src/executor/gstreamingexecutor.cpp
modules/gapi/src/executor/gstreamingexecutor.cpp
+78
-0
modules/gapi/src/executor/gstreamingexecutor.hpp
modules/gapi/src/executor/gstreamingexecutor.hpp
+3
-0
modules/gapi/test/streaming/gapi_streaming_tests.cpp
modules/gapi/test/streaming/gapi_streaming_tests.cpp
+75
-6
未找到文件。
modules/gapi/include/opencv2/gapi/gstreaming.hpp
浏览文件 @
eb68476a
...
...
@@ -71,6 +71,15 @@ using GOptRunArgP = util::variant<
>
;
using
GOptRunArgsP
=
std
::
vector
<
GOptRunArgP
>
;
using
GOptRunArg
=
util
::
variant
<
optional
<
cv
::
Mat
>
,
optional
<
cv
::
RMat
>
,
optional
<
cv
::
Scalar
>
,
optional
<
cv
::
detail
::
VectorRef
>
,
optional
<
cv
::
detail
::
OpaqueRef
>
>
;
using
GOptRunArgs
=
std
::
vector
<
GOptRunArg
>
;
namespace
detail
{
template
<
typename
T
>
inline
GOptRunArgP
wrap_opt_arg
(
optional
<
T
>&
arg
)
{
...
...
@@ -255,7 +264,7 @@ public:
// NB: Used from python
/// @private -- Exclude this function from OpenCV documentation
GAPI_WRAP
std
::
tuple
<
bool
,
cv
::
GRunArgs
>
pull
();
GAPI_WRAP
std
::
tuple
<
bool
,
cv
::
util
::
variant
<
cv
::
GRunArgs
,
cv
::
GOptRunArgs
>
>
pull
();
/**
* @brief Get some next available data from the pipeline.
...
...
modules/gapi/misc/python/pyopencv_gapi.hpp
浏览文件 @
eb68476a
...
...
@@ -131,7 +131,8 @@ PyObject* pyopencv_from(const cv::detail::PyObjectHolder& v)
template
<
>
PyObject
*
pyopencv_from
(
const
cv
::
gapi
::
wip
::
draw
::
Prim
&
prim
)
{
switch
(
prim
.
index
())
{
switch
(
prim
.
index
())
{
case
cv
::
gapi
::
wip
::
draw
::
Prim
::
index_of
<
cv
::
gapi
::
wip
::
draw
::
Rect
>
():
return
pyopencv_from
(
cv
::
util
::
get
<
cv
::
gapi
::
wip
::
draw
::
Rect
>
(
prim
));
case
cv
::
gapi
::
wip
::
draw
::
Prim
::
index_of
<
cv
::
gapi
::
wip
::
draw
::
Text
>
():
...
...
@@ -319,40 +320,69 @@ PyObject* pyopencv_from(const GRunArg& v)
return
pyopencv_from
(
util
::
get
<
cv
::
detail
::
OpaqueRef
>
(
v
));
}
PyErr_SetString
(
PyExc_TypeError
,
"Failed to unpack GRunArgs"
);
PyErr_SetString
(
PyExc_TypeError
,
"Failed to unpack GRunArgs
. Index of variant is unknown
"
);
return
NULL
;
}
template
<
>
PyObject
*
pyopencv_from
(
const
GRunArgs
&
value
)
template
<
typename
T
>
PyObject
*
pyopencv_from
(
const
cv
::
optional
<
T
>&
opt
)
{
size_t
i
,
n
=
value
.
size
();
if
(
!
opt
.
has_value
())
{
Py_RETURN_NONE
;
}
return
pyopencv_from
(
*
opt
);
}
// NB: It doesn't make sense to return list with a single element
if
(
n
==
1
)
template
<
>
PyObject
*
pyopencv_from
(
const
GOptRunArg
&
v
)
{
switch
(
v
.
index
())
{
PyObject
*
item
=
pyopencv_from
(
value
[
0
]);
if
(
!
item
)
{
return
NULL
;
}
return
item
;
case
GOptRunArg
::
index_of
<
cv
::
optional
<
cv
::
Mat
>>
():
return
pyopencv_from
(
util
::
get
<
cv
::
optional
<
cv
::
Mat
>>
(
v
));
case
GOptRunArg
::
index_of
<
cv
::
optional
<
cv
::
Scalar
>>
():
return
pyopencv_from
(
util
::
get
<
cv
::
optional
<
cv
::
Scalar
>>
(
v
));
case
GOptRunArg
::
index_of
<
optional
<
cv
::
detail
::
VectorRef
>>
():
return
pyopencv_from
(
util
::
get
<
optional
<
cv
::
detail
::
VectorRef
>>
(
v
));
case
GOptRunArg
::
index_of
<
optional
<
cv
::
detail
::
OpaqueRef
>>
():
return
pyopencv_from
(
util
::
get
<
optional
<
cv
::
detail
::
OpaqueRef
>>
(
v
));
}
PyObject
*
list
=
PyList_New
(
n
);
for
(
i
=
0
;
i
<
n
;
++
i
)
PyErr_SetString
(
PyExc_TypeError
,
"Failed to unpack GOptRunArg. Index of variant is unknown"
);
return
NULL
;
}
template
<
>
PyObject
*
pyopencv_from
(
const
GRunArgs
&
value
)
{
return
value
.
size
()
==
1
?
pyopencv_from
(
value
[
0
])
:
pyopencv_from_generic_vec
(
value
);
}
template
<
>
PyObject
*
pyopencv_from
(
const
GOptRunArgs
&
value
)
{
return
value
.
size
()
==
1
?
pyopencv_from
(
value
[
0
])
:
pyopencv_from_generic_vec
(
value
);
}
// FIXME: cv::variant should be wrapped once for all types.
template
<
>
PyObject
*
pyopencv_from
(
const
cv
::
util
::
variant
<
cv
::
GRunArgs
,
cv
::
GOptRunArgs
>&
v
)
{
using
RunArgs
=
cv
::
util
::
variant
<
cv
::
GRunArgs
,
cv
::
GOptRunArgs
>
;
switch
(
v
.
index
())
{
PyObject
*
item
=
pyopencv_from
(
value
[
i
]);
if
(
!
item
)
{
Py_DECREF
(
list
);
PyErr_SetString
(
PyExc_TypeError
,
"Failed to unpack GRunArgs"
);
return
NULL
;
}
PyList_SetItem
(
list
,
i
,
item
);
case
RunArgs
::
index_of
<
cv
::
GRunArgs
>
():
return
pyopencv_from
(
util
::
get
<
cv
::
GRunArgs
>
(
v
));
case
RunArgs
::
index_of
<
cv
::
GOptRunArgs
>
():
return
pyopencv_from
(
util
::
get
<
cv
::
GOptRunArgs
>
(
v
));
}
return
list
;
PyErr_SetString
(
PyExc_TypeError
,
"Failed to recognize kind of RunArgs. Index of variant is unknown"
);
return
NULL
;
}
template
<
typename
T
>
...
...
@@ -634,7 +664,8 @@ static cv::GRunArgs run_py_kernel(cv::detail::PyObjectHolder kernel,
cv
::
detail
::
PyObjectHolder
result
(
PyObject_CallObject
(
kernel
.
get
(),
args
.
get
()),
false
);
if
(
PyErr_Occurred
())
{
if
(
PyErr_Occurred
())
{
PyErr_PrintEx
(
0
);
PyErr_Clear
();
throw
std
::
logic_error
(
"Python kernel failed with error!"
);
...
...
@@ -717,8 +748,9 @@ static cv::GMetaArgs get_meta_args(PyObject* tuple)
}
static
GMetaArgs
run_py_meta
(
cv
::
detail
::
PyObjectHolder
out_meta
,
const
cv
::
GMetaArgs
&
meta
,
const
cv
::
GArgs
&
gargs
)
{
const
cv
::
GMetaArgs
&
meta
,
const
cv
::
GArgs
&
gargs
)
{
PyGILState_STATE
gstate
;
gstate
=
PyGILState_Ensure
();
...
...
@@ -760,7 +792,8 @@ static GMetaArgs run_py_meta(cv::detail::PyObjectHolder out_meta,
cv
::
detail
::
PyObjectHolder
result
(
PyObject_CallObject
(
out_meta
.
get
(),
args
.
get
()),
false
);
if
(
PyErr_Occurred
())
{
if
(
PyErr_Occurred
())
{
PyErr_PrintEx
(
0
);
PyErr_Clear
();
throw
std
::
logic_error
(
"Python outMeta failed with error!"
);
...
...
@@ -792,21 +825,24 @@ static PyObject* pyopencv_cv_gapi_kernels(PyObject* , PyObject* py_args, PyObjec
PyObject
*
user_kernel
=
PyTuple_GetItem
(
py_args
,
i
);
PyObject
*
id_obj
=
PyObject_GetAttrString
(
user_kernel
,
"id"
);
if
(
!
id_obj
)
{
if
(
!
id_obj
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Python kernel should contain id, please use cv.gapi.kernel to define kernel"
);
return
NULL
;
}
PyObject
*
out_meta
=
PyObject_GetAttrString
(
user_kernel
,
"outMeta"
);
if
(
!
out_meta
)
{
if
(
!
out_meta
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Python kernel should contain outMeta, please use cv.gapi.kernel to define kernel"
);
return
NULL
;
}
PyObject
*
run
=
PyObject_GetAttrString
(
user_kernel
,
"run"
);
if
(
!
run
)
{
if
(
!
run
)
{
PyErr_SetString
(
PyExc_TypeError
,
"Python kernel should contain run, please use cv.gapi.kernel to define kernel"
);
return
NULL
;
...
...
@@ -951,9 +987,12 @@ struct PyOpenCV_Converter<cv::GArray<T>>
if
(
PyObject_TypeCheck
(
obj
,
reinterpret_cast
<
PyTypeObject
*>
(
pyopencv_GArrayT_TypePtr
)))
{
auto
&
array
=
reinterpret_cast
<
pyopencv_GArrayT_t
*>
(
obj
)
->
v
;
try
{
try
{
value
=
cv
::
util
::
get
<
cv
::
GArray
<
T
>>
(
array
.
arg
());
}
catch
(...)
{
}
catch
(...)
{
return
false
;
}
return
true
;
...
...
@@ -974,9 +1013,12 @@ struct PyOpenCV_Converter<cv::GOpaque<T>>
if
(
PyObject_TypeCheck
(
obj
,
reinterpret_cast
<
PyTypeObject
*>
(
pyopencv_GOpaqueT_TypePtr
)))
{
auto
&
opaque
=
reinterpret_cast
<
pyopencv_GOpaqueT_t
*>
(
obj
)
->
v
;
try
{
try
{
value
=
cv
::
util
::
get
<
cv
::
GOpaque
<
T
>>
(
opaque
.
arg
());
}
catch
(...)
{
}
catch
(...)
{
return
false
;
}
return
true
;
...
...
modules/gapi/misc/python/shadow_gapi.hpp
浏览文件 @
eb68476a
...
...
@@ -3,39 +3,40 @@
namespace
cv
{
struct
GAPI_EXPORTS_W_SIMPLE
GCompileArg
{
GAPI_WRAP
GCompileArg
(
gapi
::
GKernelPackage
pkg
);
GAPI_WRAP
GCompileArg
(
gapi
::
GNetPackage
pkg
);
struct
GAPI_EXPORTS_W_SIMPLE
GCompileArg
{
GAPI_WRAP
GCompileArg
(
gapi
::
GKernelPackage
pkg
);
GAPI_WRAP
GCompileArg
(
gapi
::
GNetPackage
pkg
);
};
class
GAPI_EXPORTS_W_SIMPLE
GInferInputs
{
public:
GAPI_WRAP
GInferInputs
();
GAPI_WRAP
GInferInputs
&
setInput
(
const
std
::
string
&
name
,
const
cv
::
GMat
&
value
);
GAPI_WRAP
GInferInputs
&
setInput
(
const
std
::
string
&
name
,
const
cv
::
GFrame
&
value
);
GAPI_WRAP
GInferInputs
();
GAPI_WRAP
GInferInputs
&
setInput
(
const
std
::
string
&
name
,
const
cv
::
GMat
&
value
);
GAPI_WRAP
GInferInputs
&
setInput
(
const
std
::
string
&
name
,
const
cv
::
GFrame
&
value
);
};
class
GAPI_EXPORTS_W_SIMPLE
GInferListInputs
{
public:
GAPI_WRAP
GInferListInputs
();
GAPI_WRAP
GInferListInputs
setInput
(
const
std
::
string
&
name
,
const
cv
::
GArray
<
cv
::
GMat
>&
value
);
GAPI_WRAP
GInferListInputs
setInput
(
const
std
::
string
&
name
,
const
cv
::
GArray
<
cv
::
Rect
>&
value
);
GAPI_WRAP
GInferListInputs
();
GAPI_WRAP
GInferListInputs
setInput
(
const
std
::
string
&
name
,
const
cv
::
GArray
<
cv
::
GMat
>&
value
);
GAPI_WRAP
GInferListInputs
setInput
(
const
std
::
string
&
name
,
const
cv
::
GArray
<
cv
::
Rect
>&
value
);
};
class
GAPI_EXPORTS_W_SIMPLE
GInferOutputs
{
public:
GAPI_WRAP
GInferOutputs
();
GAPI_WRAP
cv
::
GMat
at
(
const
std
::
string
&
name
);
GAPI_WRAP
GInferOutputs
();
GAPI_WRAP
cv
::
GMat
at
(
const
std
::
string
&
name
);
};
class
GAPI_EXPORTS_W_SIMPLE
GInferListOutputs
{
public:
GAPI_WRAP
GInferListOutputs
();
GAPI_WRAP
cv
::
GArray
<
cv
::
GMat
>
at
(
const
std
::
string
&
name
);
GAPI_WRAP
GInferListOutputs
();
GAPI_WRAP
cv
::
GArray
<
cv
::
GMat
>
at
(
const
std
::
string
&
name
);
};
namespace
gapi
...
...
@@ -69,11 +70,13 @@ namespace streaming
cv
::
GOpaque
<
int64_t
>
GAPI_EXPORTS_W
timestamp
(
cv
::
GMat
);
cv
::
GOpaque
<
int64_t
>
GAPI_EXPORTS_W
seqNo
(
cv
::
GMat
);
cv
::
GOpaque
<
int64_t
>
GAPI_EXPORTS_W
seq_id
(
cv
::
GMat
);
GAPI_EXPORTS_W
cv
::
GMat
desync
(
const
cv
::
GMat
&
g
);
}
// namespace streaming
}
// namespace gapi
namespace
detail
{
gapi
::
GNetParam
GAPI_EXPORTS_W
strip
(
gapi
::
ie
::
PyParams
params
);
gapi
::
GNetParam
GAPI_EXPORTS_W
strip
(
gapi
::
ie
::
PyParams
params
);
}
// namespace detail
}
// namespace cv
modules/gapi/misc/python/test/test_gapi_streaming.py
浏览文件 @
eb68476a
...
...
@@ -5,16 +5,35 @@ import cv2 as cv
import
os
import
sys
import
unittest
import
time
from
tests_common
import
NewOpenCVTests
try
:
if
sys
.
version_info
[:
2
]
<
(
3
,
0
):
raise
unittest
.
SkipTest
(
'Python 2.x is not supported'
)
@
cv
.
gapi
.
op
(
'custom.delay'
,
in_types
=
[
cv
.
GMat
],
out_types
=
[
cv
.
GMat
])
class
GDelay
:
"""Delay for 10 ms."""
@
staticmethod
def
outMeta
(
desc
):
return
desc
@
cv
.
gapi
.
kernel
(
GDelay
)
class
GDelayImpl
:
"""Implementation for GDelay operation."""
@
staticmethod
def
run
(
img
):
time
.
sleep
(
0.01
)
return
img
class
test_gapi_streaming
(
NewOpenCVTests
):
def
test_image_input
(
self
):
...
...
@@ -148,7 +167,7 @@ try:
proc_num_frames
+=
1
if
proc_num_frames
==
max_num_frames
:
break
;
break
def
test_video_good_features_to_track
(
self
):
...
...
@@ -242,6 +261,51 @@ try:
if
curr_frame_number
==
max_num_frames
:
break
def
test_desync
(
self
):
path
=
self
.
find_file
(
'cv/video/768x576.avi'
,
[
os
.
environ
[
'OPENCV_TEST_DATA_PATH'
]])
# G-API
g_in
=
cv
.
GMat
()
g_out1
=
cv
.
gapi
.
copy
(
g_in
)
des
=
cv
.
gapi
.
streaming
.
desync
(
g_in
)
g_out2
=
GDelay
.
on
(
des
)
c
=
cv
.
GComputation
(
cv
.
GIn
(
g_in
),
cv
.
GOut
(
g_out1
,
g_out2
))
kernels
=
cv
.
gapi
.
kernels
(
GDelayImpl
)
ccomp
=
c
.
compileStreaming
(
args
=
cv
.
gapi
.
compile_args
(
kernels
))
source
=
cv
.
gapi
.
wip
.
make_capture_src
(
path
)
ccomp
.
setSource
(
cv
.
gin
(
source
))
ccomp
.
start
()
# Assert
max_num_frames
=
10
proc_num_frames
=
0
out_counter
=
0
desync_out_counter
=
0
none_counter
=
0
while
True
:
has_frame
,
(
out1
,
out2
)
=
ccomp
.
pull
()
if
not
has_frame
:
break
if
not
out1
is
None
:
out_counter
+=
1
if
not
out2
is
None
:
desync_out_counter
+=
1
else
:
none_counter
+=
1
proc_num_frames
+=
1
if
proc_num_frames
==
max_num_frames
:
ccomp
.
stop
()
break
self
.
assertLess
(
0
,
proc_num_frames
)
self
.
assertLess
(
desync_out_counter
,
out_counter
)
self
.
assertLess
(
0
,
none_counter
)
except
unittest
.
SkipTest
as
e
:
...
...
modules/gapi/src/compiler/gstreaming.cpp
浏览文件 @
eb68476a
...
...
@@ -75,6 +75,11 @@ bool cv::GStreamingCompiled::Priv::pull(cv::GOptRunArgsP &&outs)
return
m_exec
->
pull
(
std
::
move
(
outs
));
}
std
::
tuple
<
bool
,
cv
::
util
::
variant
<
cv
::
GRunArgs
,
cv
::
GOptRunArgs
>>
cv
::
GStreamingCompiled
::
Priv
::
pull
()
{
return
m_exec
->
pull
();
}
bool
cv
::
GStreamingCompiled
::
Priv
::
try_pull
(
cv
::
GRunArgsP
&&
outs
)
{
return
m_exec
->
try_pull
(
std
::
move
(
outs
));
...
...
@@ -123,18 +128,9 @@ bool cv::GStreamingCompiled::pull(cv::GRunArgsP &&outs)
return
m_priv
->
pull
(
std
::
move
(
outs
));
}
std
::
tuple
<
bool
,
cv
::
GRunArgs
>
cv
::
GStreamingCompiled
::
pull
()
std
::
tuple
<
bool
,
cv
::
util
::
variant
<
cv
::
GRunArgs
,
cv
::
GOptRunArgs
>
>
cv
::
GStreamingCompiled
::
pull
()
{
GRunArgs
run_args
;
GRunArgsP
outs
;
const
auto
&
out_info
=
m_priv
->
outInfo
();
run_args
.
reserve
(
out_info
.
size
());
outs
.
reserve
(
out_info
.
size
());
cv
::
detail
::
constructGraphOutputs
(
m_priv
->
outInfo
(),
run_args
,
outs
);
bool
is_over
=
m_priv
->
pull
(
std
::
move
(
outs
));
return
std
::
make_tuple
(
is_over
,
run_args
);
return
m_priv
->
pull
();
}
bool
cv
::
GStreamingCompiled
::
pull
(
cv
::
GOptRunArgsP
&&
outs
)
...
...
modules/gapi/src/compiler/gstreaming_priv.hpp
浏览文件 @
eb68476a
...
...
@@ -46,6 +46,7 @@ public:
void
start
();
bool
pull
(
cv
::
GRunArgsP
&&
outs
);
bool
pull
(
cv
::
GOptRunArgsP
&&
outs
);
std
::
tuple
<
bool
,
cv
::
util
::
variant
<
cv
::
GRunArgs
,
cv
::
GOptRunArgs
>>
pull
();
bool
try_pull
(
cv
::
GRunArgsP
&&
outs
);
void
stop
();
...
...
modules/gapi/src/executor/gstreamingexecutor.cpp
浏览文件 @
eb68476a
...
...
@@ -1017,6 +1017,49 @@ void check_DesyncObjectConsumedByMultipleIslands(const cv::gimpl::GIslandModel::
}
// for(nodes)
}
// NB: Construct GRunArgsP based on passed info and store the memory in passed cv::GRunArgs.
// Needed for python bridge, because in case python user doesn't pass output arguments to apply.
void
constructOptGraphOutputs
(
const
cv
::
GTypesInfo
&
out_info
,
cv
::
GOptRunArgs
&
args
,
cv
::
GOptRunArgsP
&
outs
)
{
for
(
auto
&&
info
:
out_info
)
{
switch
(
info
.
shape
)
{
case
cv
::
GShape
::
GMAT
:
{
args
.
emplace_back
(
cv
::
optional
<
cv
::
Mat
>
{});
outs
.
emplace_back
(
&
cv
::
util
::
get
<
cv
::
optional
<
cv
::
Mat
>>
(
args
.
back
()));
break
;
}
case
cv
::
GShape
::
GSCALAR
:
{
args
.
emplace_back
(
cv
::
optional
<
cv
::
Scalar
>
{});
outs
.
emplace_back
(
&
cv
::
util
::
get
<
cv
::
optional
<
cv
::
Scalar
>>
(
args
.
back
()));
break
;
}
case
cv
::
GShape
::
GARRAY
:
{
cv
::
detail
::
VectorRef
ref
;
cv
::
util
::
get
<
cv
::
detail
::
ConstructVec
>
(
info
.
ctor
)(
ref
);
args
.
emplace_back
(
cv
::
util
::
make_optional
(
std
::
move
(
ref
)));
outs
.
emplace_back
(
wrap_opt_arg
(
cv
::
util
::
get
<
cv
::
optional
<
cv
::
detail
::
VectorRef
>>
(
args
.
back
())));
break
;
}
case
cv
::
GShape
::
GOPAQUE
:
{
cv
::
detail
::
OpaqueRef
ref
;
cv
::
util
::
get
<
cv
::
detail
::
ConstructOpaque
>
(
info
.
ctor
)(
ref
);
args
.
emplace_back
(
cv
::
util
::
make_optional
(
std
::
move
(
ref
)));
outs
.
emplace_back
(
wrap_opt_arg
(
cv
::
util
::
get
<
cv
::
optional
<
cv
::
detail
::
OpaqueRef
>>
(
args
.
back
())));
break
;
}
default:
cv
::
util
::
throw_error
(
std
::
logic_error
(
"Unsupported optional output shape for Python"
));
}
}
}
}
// anonymous namespace
class
cv
::
gimpl
::
GStreamingExecutor
::
Synchronizer
final
{
...
...
@@ -1320,6 +1363,16 @@ cv::gimpl::GStreamingExecutor::GStreamingExecutor(std::unique_ptr<ade::Graph> &&
// per the same input frame, so the output traffic multiplies)
GAPI_Assert
(
m_collector_map
.
size
()
>
0u
);
m_out_queue
.
set_capacity
(
queue_capacity
*
m_collector_map
.
size
());
// FIXME: The code duplicates logic of collectGraphInfo()
cv
::
gimpl
::
GModel
::
ConstGraph
cgr
(
*
m_orig_graph
);
auto
meta
=
cgr
.
metadata
().
get
<
cv
::
gimpl
::
Protocol
>
().
out_nhs
;
out_info
.
reserve
(
meta
.
size
());
ade
::
util
::
transform
(
meta
,
std
::
back_inserter
(
out_info
),
[
&
cgr
](
const
ade
::
NodeHandle
&
nh
)
{
const
auto
&
data
=
cgr
.
metadata
(
nh
).
get
<
cv
::
gimpl
::
Data
>
();
return
cv
::
GTypeInfo
{
data
.
shape
,
data
.
kind
,
data
.
ctor
};
});
}
cv
::
gimpl
::
GStreamingExecutor
::~
GStreamingExecutor
()
...
...
@@ -1653,6 +1706,31 @@ bool cv::gimpl::GStreamingExecutor::pull(cv::GOptRunArgsP &&outs)
return
true
;
}
std
::
tuple
<
bool
,
cv
::
util
::
variant
<
cv
::
GRunArgs
,
cv
::
GOptRunArgs
>>
cv
::
gimpl
::
GStreamingExecutor
::
pull
()
{
using
RunArgs
=
cv
::
util
::
variant
<
cv
::
GRunArgs
,
cv
::
GOptRunArgs
>
;
bool
is_over
=
false
;
if
(
m_desync
)
{
GOptRunArgs
opt_run_args
;
GOptRunArgsP
opt_outs
;
opt_outs
.
reserve
(
out_info
.
size
());
opt_run_args
.
reserve
(
out_info
.
size
());
constructOptGraphOutputs
(
out_info
,
opt_run_args
,
opt_outs
);
is_over
=
pull
(
std
::
move
(
opt_outs
));
return
std
::
make_tuple
(
is_over
,
RunArgs
(
opt_run_args
));
}
GRunArgs
run_args
;
GRunArgsP
outs
;
run_args
.
reserve
(
out_info
.
size
());
outs
.
reserve
(
out_info
.
size
());
constructGraphOutputs
(
out_info
,
run_args
,
outs
);
is_over
=
pull
(
std
::
move
(
outs
));
return
std
::
make_tuple
(
is_over
,
RunArgs
(
run_args
));
}
bool
cv
::
gimpl
::
GStreamingExecutor
::
try_pull
(
cv
::
GRunArgsP
&&
outs
)
{
...
...
modules/gapi/src/executor/gstreamingexecutor.hpp
浏览文件 @
eb68476a
...
...
@@ -195,6 +195,8 @@ protected:
void
wait_shutdown
();
cv
::
GTypesInfo
out_info
;
public:
explicit
GStreamingExecutor
(
std
::
unique_ptr
<
ade
::
Graph
>
&&
g_model
,
const
cv
::
GCompileArgs
&
comp_args
);
...
...
@@ -203,6 +205,7 @@ public:
void
start
();
bool
pull
(
cv
::
GRunArgsP
&&
outs
);
bool
pull
(
cv
::
GOptRunArgsP
&&
outs
);
std
::
tuple
<
bool
,
cv
::
util
::
variant
<
cv
::
GRunArgs
,
cv
::
GOptRunArgs
>>
pull
();
bool
try_pull
(
cv
::
GRunArgsP
&&
outs
);
void
stop
();
bool
running
()
const
;
...
...
modules/gapi/test/streaming/gapi_streaming_tests.cpp
浏览文件 @
eb68476a
...
...
@@ -244,6 +244,35 @@ public:
}
};
void
checkPullOverload
(
const
cv
::
Mat
&
ref
,
const
bool
has_output
,
cv
::
util
::
variant
<
cv
::
GRunArgs
,
cv
::
GOptRunArgs
>&
args
)
{
EXPECT_TRUE
(
has_output
);
using
runArgs
=
cv
::
util
::
variant
<
cv
::
GRunArgs
,
cv
::
GOptRunArgs
>
;
cv
::
Mat
out_mat
;
switch
(
args
.
index
())
{
case
runArgs
::
index_of
<
cv
::
GRunArgs
>
():
{
auto
outputs
=
util
::
get
<
cv
::
GRunArgs
>
(
args
);
EXPECT_EQ
(
1u
,
outputs
.
size
());
out_mat
=
cv
::
util
::
get
<
cv
::
Mat
>
(
outputs
[
0
]);
break
;
}
case
runArgs
::
index_of
<
cv
::
GOptRunArgs
>
():
{
auto
outputs
=
util
::
get
<
cv
::
GOptRunArgs
>
(
args
);
EXPECT_EQ
(
1u
,
outputs
.
size
());
auto
opt_mat
=
cv
::
util
::
get
<
cv
::
optional
<
cv
::
Mat
>>
(
outputs
[
0
]);
ASSERT_TRUE
(
opt_mat
.
has_value
());
out_mat
=
*
opt_mat
;
break
;
}
default:
GAPI_Assert
(
false
&&
"Incorrect type of Args"
);
}
EXPECT_EQ
(
0.
,
cv
::
norm
(
ref
,
out_mat
,
cv
::
NORM_INF
));
}
}
// anonymous namespace
TEST_P
(
GAPI_Streaming
,
SmokeTest_ConstInput_GMat
)
...
...
@@ -1336,13 +1365,45 @@ TEST(Streaming, Python_Pull_Overload)
bool
has_output
;
cv
::
GRunArgs
outputs
;
std
::
tie
(
has_output
,
outputs
)
=
ccomp
.
pull
();
using
RunArgs
=
cv
::
util
::
variant
<
cv
::
GRunArgs
,
cv
::
GOptRunArgs
>
;
RunArgs
args
;
EXPECT_TRUE
(
has_output
);
EXPECT_EQ
(
1u
,
outputs
.
size
());
std
::
tie
(
has_output
,
args
)
=
ccomp
.
pull
();
checkPullOverload
(
in_mat
,
has_output
,
args
);
ccomp
.
stop
();
EXPECT_FALSE
(
ccomp
.
running
());
}
TEST
(
GAPI_Streaming_Desync
,
Python_Pull_Overload
)
{
cv
::
GMat
in
;
cv
::
GMat
out
=
cv
::
gapi
::
streaming
::
desync
(
in
);
cv
::
GComputation
c
(
in
,
out
);
cv
::
Size
sz
(
3
,
3
);
cv
::
Mat
in_mat
(
sz
,
CV_8UC3
);
cv
::
randu
(
in_mat
,
cv
::
Scalar
::
all
(
0
),
cv
::
Scalar
(
255
));
auto
out_mat
=
cv
::
util
::
get
<
cv
::
Mat
>
(
outputs
[
0
]);
EXPECT_EQ
(
0.
,
cv
::
norm
(
in_mat
,
out_mat
,
cv
::
NORM_INF
));
auto
ccomp
=
c
.
compileStreaming
();
EXPECT_TRUE
(
ccomp
);
EXPECT_FALSE
(
ccomp
.
running
());
ccomp
.
setSource
(
cv
::
gin
(
in_mat
));
ccomp
.
start
();
EXPECT_TRUE
(
ccomp
.
running
());
bool
has_output
;
cv
::
GRunArgs
outputs
;
using
RunArgs
=
cv
::
util
::
variant
<
cv
::
GRunArgs
,
cv
::
GOptRunArgs
>
;
RunArgs
args
;
std
::
tie
(
has_output
,
args
)
=
ccomp
.
pull
();
checkPullOverload
(
in_mat
,
has_output
,
args
);
ccomp
.
stop
();
EXPECT_FALSE
(
ccomp
.
running
());
...
...
@@ -2132,9 +2193,17 @@ TEST(GAPI_Streaming, TestPythonAPI)
bool
is_over
=
false
;
cv
::
GRunArgs
out_args
;
using
RunArgs
=
cv
::
util
::
variant
<
cv
::
GRunArgs
,
cv
::
GOptRunArgs
>
;
RunArgs
args
;
// NB: Used by python bridge
std
::
tie
(
is_over
,
out_args
)
=
cc
.
pull
();
std
::
tie
(
is_over
,
args
)
=
cc
.
pull
();
switch
(
args
.
index
())
{
case
RunArgs
::
index_of
<
cv
::
GRunArgs
>
():
out_args
=
util
::
get
<
cv
::
GRunArgs
>
(
args
);
break
;
default:
GAPI_Assert
(
false
&&
"Incorrect type of return value"
);
}
ASSERT_EQ
(
1u
,
out_args
.
size
());
ASSERT_TRUE
(
cv
::
util
::
holds_alternative
<
cv
::
Mat
>
(
out_args
[
0
]));
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录