Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Opencv
提交
c0076b58
O
Opencv
项目概览
Greenplum
/
Opencv
12 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
c0076b58
编写于
2月 18, 2019
作者:
R
Ruslan Garnov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Added NV12 support to fluid backend
上级
322115bf
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
306 addition
and
45 deletion
+306
-45
modules/gapi/include/opencv2/gapi/fluid/gfluidbuffer.hpp
modules/gapi/include/opencv2/gapi/fluid/gfluidbuffer.hpp
+4
-0
modules/gapi/include/opencv2/gapi/fluid/gfluidkernel.hpp
modules/gapi/include/opencv2/gapi/fluid/gfluidkernel.hpp
+2
-1
modules/gapi/src/backends/fluid/gfluidbackend.cpp
modules/gapi/src/backends/fluid/gfluidbackend.cpp
+105
-40
modules/gapi/src/backends/fluid/gfluidbackend.hpp
modules/gapi/src/backends/fluid/gfluidbackend.hpp
+6
-4
modules/gapi/src/backends/fluid/gfluidbuffer.cpp
modules/gapi/src/backends/fluid/gfluidbuffer.cpp
+3
-0
modules/gapi/test/gapi_fluid_resize_test.cpp
modules/gapi/test/gapi_fluid_resize_test.cpp
+73
-0
modules/gapi/test/gapi_fluid_test.cpp
modules/gapi/test/gapi_fluid_test.cpp
+42
-0
modules/gapi/test/gapi_fluid_test_kernels.cpp
modules/gapi/test/gapi_fluid_test_kernels.cpp
+71
-0
未找到文件。
modules/gapi/include/opencv2/gapi/fluid/gfluidbuffer.hpp
浏览文件 @
c0076b58
...
...
@@ -53,6 +53,10 @@ public:
inline
const
uint8_t
*
linePtr
(
int
index
)
const
{
// "out_of_window" check:
// user must not request the lines which are outside of specified kernel window
GAPI_DbgAssert
(
index
>=
-
m_border_size
&&
index
<
-
m_border_size
+
static_cast
<
int
>
(
m_linePtrs
.
size
()));
return
m_linePtrs
[
index
+
m_border_size
];
}
};
...
...
modules/gapi/include/opencv2/gapi/fluid/gfluidkernel.hpp
浏览文件 @
c0076b58
...
...
@@ -49,7 +49,8 @@ public:
enum
class
Kind
{
Filter
,
Resize
Resize
,
NV12toRGB
};
// This function is a generic "doWork" callback
...
...
modules/gapi/src/backends/fluid/gfluidbackend.cpp
浏览文件 @
c0076b58
...
...
@@ -67,7 +67,7 @@ namespace
{
GFluidModel
fm
(
graph
);
auto
fluid_impl
=
cv
::
util
::
any_cast
<
cv
::
GFluidKernel
>
(
impl
.
opaque
);
fm
.
metadata
(
op_node
).
set
(
cv
::
gimpl
::
FluidUnit
{
fluid_impl
,
{},
0
,
0
,
0.0
});
fm
.
metadata
(
op_node
).
set
(
cv
::
gimpl
::
FluidUnit
{
fluid_impl
,
{},
0
,
{}
,
0.0
});
}
virtual
EPtr
compile
(
const
ade
::
Graph
&
graph
,
...
...
@@ -138,8 +138,8 @@ private:
struct
FluidFilterAgent
:
public
FluidAgent
{
private:
virtual
int
firstWindow
()
const
override
;
virtual
std
::
pair
<
int
,
int
>
linesReadAndnextWindow
()
const
override
;
virtual
int
firstWindow
(
std
::
size_t
inPort
)
const
override
;
virtual
std
::
pair
<
int
,
int
>
linesReadAndnextWindow
(
std
::
size_t
inPort
)
const
override
;
virtual
void
setRatio
(
double
)
override
{
/* nothing */
}
public:
using
FluidAgent
::
FluidAgent
;
...
...
@@ -148,14 +148,24 @@ public:
struct
FluidResizeAgent
:
public
FluidAgent
{
private:
virtual
int
firstWindow
()
const
override
;
virtual
std
::
pair
<
int
,
int
>
linesReadAndnextWindow
()
const
override
;
virtual
int
firstWindow
(
std
::
size_t
inPort
)
const
override
;
virtual
std
::
pair
<
int
,
int
>
linesReadAndnextWindow
(
std
::
size_t
inPort
)
const
override
;
virtual
void
setRatio
(
double
ratio
)
override
;
std
::
unique_ptr
<
FluidMapper
>
m_mapper
;
public:
using
FluidAgent
::
FluidAgent
;
};
struct
FluidNV12toRGBAgent
:
public
FluidAgent
{
private:
virtual
int
firstWindow
(
std
::
size_t
inPort
)
const
override
;
virtual
std
::
pair
<
int
,
int
>
linesReadAndnextWindow
(
std
::
size_t
inPort
)
const
override
;
virtual
void
setRatio
(
double
)
override
{
/* nothing */
}
public:
using
FluidAgent
::
FluidAgent
;
};
}}
// namespace cv::gimpl
cv
::
gimpl
::
FluidAgent
::
FluidAgent
(
const
ade
::
Graph
&
g
,
ade
::
NodeHandle
nh
)
...
...
@@ -182,11 +192,13 @@ void cv::gimpl::FluidAgent::reset()
{
m_producedLines
=
0
;
auto
lines
=
firstWindow
();
for
(
auto
&
v
:
in_views
)
for
(
const
auto
&
it
:
ade
::
util
::
indexed
(
in_views
))
{
auto
&
v
=
ade
::
util
::
value
(
it
);
if
(
v
)
{
auto
idx
=
ade
::
util
::
index
(
it
);
auto
lines
=
firstWindow
(
idx
);
v
.
priv
().
reset
(
lines
);
}
}
...
...
@@ -240,7 +252,7 @@ static int calcResizeWindow(int inH, int outH)
}
}
static
int
maxLineConsumption
(
const
cv
::
GFluidKernel
&
k
,
int
inH
,
int
outH
,
int
lpi
)
static
int
maxLineConsumption
(
const
cv
::
GFluidKernel
&
k
,
int
inH
,
int
outH
,
int
lpi
,
std
::
size_t
inPort
)
{
switch
(
k
.
m_kind
)
{
...
...
@@ -260,6 +272,7 @@ static int maxLineConsumption(const cv::GFluidKernel& k, int inH, int outH, int
return
(
inH
==
1
)
?
1
:
2
+
lpi
-
1
;
}
}
break
;
case
cv
::
GFluidKernel
::
Kind
::
NV12toRGB
:
return
inPort
==
0
?
2
:
1
;
break
;
default:
GAPI_Assert
(
false
);
return
0
;
}
}
...
...
@@ -271,6 +284,7 @@ static int borderSize(const cv::GFluidKernel& k)
case
cv
::
GFluidKernel
::
Kind
::
Filter
:
return
(
k
.
m_window
-
1
)
/
2
;
break
;
// Resize never reads from border pixels
case
cv
::
GFluidKernel
::
Kind
::
Resize
:
return
0
;
break
;
case
cv
::
GFluidKernel
::
Kind
::
NV12toRGB
:
return
0
;
break
;
default:
GAPI_Assert
(
false
);
return
0
;
}
}
...
...
@@ -354,31 +368,43 @@ std::pair<int,int> cv::gimpl::FluidUpscaleMapper::linesReadAndNextWindow(int out
return
std
::
make_pair
(
lines_read
,
next_window
);
}
int
cv
::
gimpl
::
FluidFilterAgent
::
firstWindow
()
const
int
cv
::
gimpl
::
FluidFilterAgent
::
firstWindow
(
std
::
size_t
)
const
{
return
k
.
m_window
+
k
.
m_lpi
-
1
;
}
std
::
pair
<
int
,
int
>
cv
::
gimpl
::
FluidFilterAgent
::
linesReadAndnextWindow
()
const
std
::
pair
<
int
,
int
>
cv
::
gimpl
::
FluidFilterAgent
::
linesReadAndnextWindow
(
std
::
size_t
)
const
{
int
lpi
=
std
::
min
(
k
.
m_lpi
,
m_outputLines
-
m_producedLines
-
k
.
m_lpi
);
return
std
::
make_pair
(
k
.
m_lpi
,
k
.
m_window
-
1
+
lpi
);
}
int
cv
::
gimpl
::
FluidResizeAgent
::
firstWindow
()
const
int
cv
::
gimpl
::
FluidResizeAgent
::
firstWindow
(
std
::
size_t
)
const
{
auto
outIdx
=
out_buffers
[
0
]
->
priv
().
y
();
auto
lpi
=
std
::
min
(
m_outputLines
-
m_producedLines
,
k
.
m_lpi
);
return
m_mapper
->
firstWindow
(
outIdx
,
lpi
);
}
std
::
pair
<
int
,
int
>
cv
::
gimpl
::
FluidResizeAgent
::
linesReadAndnextWindow
()
const
std
::
pair
<
int
,
int
>
cv
::
gimpl
::
FluidResizeAgent
::
linesReadAndnextWindow
(
std
::
size_t
)
const
{
auto
outIdx
=
out_buffers
[
0
]
->
priv
().
y
();
auto
lpi
=
std
::
min
(
m_outputLines
-
m_producedLines
-
k
.
m_lpi
,
k
.
m_lpi
);
return
m_mapper
->
linesReadAndNextWindow
(
outIdx
,
lpi
);
}
int
cv
::
gimpl
::
FluidNV12toRGBAgent
::
firstWindow
(
std
::
size_t
inPort
)
const
{
// 2 lines for Y, 1 for UV
return
inPort
==
0
?
2
:
1
;
}
std
::
pair
<
int
,
int
>
cv
::
gimpl
::
FluidNV12toRGBAgent
::
linesReadAndnextWindow
(
std
::
size_t
inPort
)
const
{
// 2 lines for Y, 1 for UV
return
inPort
==
0
?
std
::
make_pair
(
2
,
2
)
:
std
::
make_pair
(
1
,
1
);
}
void
cv
::
gimpl
::
FluidResizeAgent
::
setRatio
(
double
ratio
)
{
if
(
ratio
>=
1.0
)
...
...
@@ -438,11 +464,14 @@ void cv::gimpl::FluidAgent::doWork()
k
.
m_f
(
in_args
,
out_buffers
);
for
(
auto
&
in_view
:
in_views
)
for
(
const
auto
&
it
:
ade
::
util
::
indexed
(
in_views
)
)
{
auto
&
in_view
=
ade
::
util
::
value
(
it
);
if
(
in_view
)
{
auto
pair
=
linesReadAndnextWindow
();
auto
idx
=
ade
::
util
::
index
(
it
);
auto
pair
=
linesReadAndnextWindow
(
idx
);
in_view
.
priv
().
readDone
(
pair
.
first
,
pair
.
second
);
};
}
...
...
@@ -554,14 +583,15 @@ void cv::gimpl::GFluidExecutable::initBufferRois(std::vector<int>& readStarts,
// only GMats participate in the process so it's valid to obtain GMatDesc
const
auto
&
meta
=
util
::
get
<
GMatDesc
>
(
data
.
meta
);
for
(
const
auto
&
in
Node
:
oh
->
inNod
es
())
for
(
const
auto
&
in
_edge
:
oh
->
inEdg
es
())
{
const
auto
&
in_data
=
m_gm
.
metadata
(
inNode
).
get
<
Data
>
();
const
auto
&
in_node
=
in_edge
->
srcNode
();
const
auto
&
in_data
=
m_gm
.
metadata
(
in_node
).
get
<
Data
>
();
if
(
in_data
.
shape
==
GShape
::
GMAT
&&
fg
.
metadata
(
in
N
ode
).
contains
<
FluidData
>
())
if
(
in_data
.
shape
==
GShape
::
GMAT
&&
fg
.
metadata
(
in
_n
ode
).
contains
<
FluidData
>
())
{
const
auto
&
in_meta
=
util
::
get
<
GMatDesc
>
(
in_data
.
meta
);
const
auto
&
fd
=
fg
.
metadata
(
in
N
ode
).
get
<
FluidData
>
();
const
auto
&
fd
=
fg
.
metadata
(
in
_n
ode
).
get
<
FluidData
>
();
auto
adjFilterRoi
=
[](
cv
::
gapi
::
own
::
Rect
produced
,
int
b
,
int
max_height
)
{
// Extend with border roi which should be produced, crop to logical image size
...
...
@@ -599,13 +629,29 @@ void cv::gimpl::GFluidExecutable::initBufferRois(std::vector<int>& readStarts,
return
roi
;
};
auto
adjNV12Roi
=
[
&
](
cv
::
gapi
::
own
::
Rect
produced
,
std
::
size_t
port
)
{
GAPI_Assert
(
produced
.
x
%
2
==
0
);
GAPI_Assert
(
produced
.
y
%
2
==
0
);
GAPI_Assert
(
produced
.
width
%
2
==
0
);
GAPI_Assert
(
produced
.
height
%
2
==
0
);
cv
::
gapi
::
own
::
Rect
roi
;
switch
(
port
)
{
case
0
:
roi
=
produced
;
break
;
case
1
:
roi
=
cv
::
gapi
::
own
::
Rect
{
produced
.
x
/
2
,
produced
.
y
/
2
,
produced
.
width
/
2
,
produced
.
height
/
2
};
break
;
default:
GAPI_Assert
(
false
);
}
return
roi
;
};
cv
::
gapi
::
own
::
Rect
produced
=
rois
[
m_id_map
.
at
(
data
.
rc
)];
cv
::
gapi
::
own
::
Rect
resized
;
switch
(
fg
.
metadata
(
oh
).
get
<
FluidUnit
>
().
k
.
m_kind
)
{
case
GFluidKernel
::
Kind
::
Filter
:
resized
=
produced
;
break
;
case
GFluidKernel
::
Kind
::
Resize
:
resized
=
adjResizeRoi
(
produced
,
in_meta
.
size
,
meta
.
size
);
break
;
case
GFluidKernel
::
Kind
::
Filter
:
resized
=
produced
;
break
;
case
GFluidKernel
::
Kind
::
Resize
:
resized
=
adjResizeRoi
(
produced
,
in_meta
.
size
,
meta
.
size
);
break
;
case
GFluidKernel
::
Kind
::
NV12toRGB
:
resized
=
adjNV12Roi
(
produced
,
m_gm
.
metadata
(
in_edge
).
get
<
Input
>
().
port
);
break
;
default:
GAPI_Assert
(
false
);
}
...
...
@@ -618,7 +664,7 @@ void cv::gimpl::GFluidExecutable::initBufferRois(std::vector<int>& readStarts,
readStarts
[
in_id
]
=
readStart
;
rois
[
in_id
]
=
roi
;
// Continue traverse on internal (w.r.t Island) data nodes only.
if
(
fd
.
internal
)
nodesToVisit
.
push
(
in
N
ode
);
if
(
fd
.
internal
)
nodesToVisit
.
push
(
in
_n
ode
);
}
else
{
...
...
@@ -626,7 +672,7 @@ void cv::gimpl::GFluidExecutable::initBufferRois(std::vector<int>& readStarts,
GAPI_Assert
(
rois
[
in_id
]
==
roi
);
}
}
// if (in_data.shape == GShape::GMAT)
}
// for (const auto& in
Node : oh->inNod
es())
}
// for (const auto& in
_edge : oh->inEdg
es())
}
// if (!startNode->inNodes().empty())
}
// while (!nodesToVisit.empty())
}
...
...
@@ -666,8 +712,9 @@ cv::gimpl::GFluidExecutable::GFluidExecutable(const ade::Graph &g,
const
auto
&
fu
=
fg
.
metadata
(
nh
).
get
<
FluidUnit
>
();
switch
(
fu
.
k
.
m_kind
)
{
case
GFluidKernel
::
Kind
::
Filter
:
m_agents
.
emplace_back
(
new
FluidFilterAgent
(
m_g
,
nh
));
break
;
case
GFluidKernel
::
Kind
::
Resize
:
m_agents
.
emplace_back
(
new
FluidResizeAgent
(
m_g
,
nh
));
break
;
case
GFluidKernel
::
Kind
::
Filter
:
m_agents
.
emplace_back
(
new
FluidFilterAgent
(
m_g
,
nh
));
break
;
case
GFluidKernel
::
Kind
::
Resize
:
m_agents
.
emplace_back
(
new
FluidResizeAgent
(
m_g
,
nh
));
break
;
case
GFluidKernel
::
Kind
::
NV12toRGB
:
m_agents
.
emplace_back
(
new
FluidNV12toRGBAgent
(
m_g
,
nh
));
break
;
default:
GAPI_Assert
(
false
);
}
// NB.: in_buffer_ids size is equal to Arguments size, not Edges size!!!
...
...
@@ -849,21 +896,35 @@ namespace
}
}
GAPI_Assert
(
in_hs
.
size
()
==
1
&&
out_ws
.
size
()
==
1
&&
out_hs
.
size
()
==
1
);
auto
&
fu
=
fg
.
metadata
(
node
).
get
<
FluidUnit
>
();
GAPI_Assert
((
out_ws
.
size
()
==
1
&&
out_hs
.
size
()
==
1
)
&&
((
in_hs
.
size
()
==
1
)
||
((
in_hs
.
size
()
==
2
)
&&
fu
.
k
.
m_kind
==
cv
::
GFluidKernel
::
Kind
::
NV12toRGB
)));
const
auto
&
op
=
g
.
metadata
(
node
).
get
<
Op
>
();
fu
.
line_consumption
.
resize
(
op
.
args
.
size
(),
0
);
auto
in_h
=
*
in_hs
.
cbegin
();
auto
out_h
=
*
out_hs
.
cbegin
();
auto
&
fu
=
fg
.
metadata
(
node
).
get
<
FluidUnit
>
();
fu
.
ratio
=
(
double
)
in_h
/
out_h
;
int
line_consumption
=
maxLineConsumption
(
fu
.
k
,
in_h
,
out_h
,
fu
.
k
.
m_lpi
);
int
border_size
=
borderSize
(
fu
.
k
);
// Set line consumption for each image (GMat) input
for
(
const
auto
&
in_edge
:
node
->
inEdges
())
{
const
auto
&
d
=
g
.
metadata
(
in_edge
->
srcNode
()).
get
<
Data
>
();
if
(
d
.
shape
==
cv
::
GShape
::
GMAT
)
{
auto
port
=
g
.
metadata
(
in_edge
).
get
<
Input
>
().
port
;
fu
.
line_consumption
[
port
]
=
maxLineConsumption
(
fu
.
k
,
in_h
,
out_h
,
fu
.
k
.
m_lpi
,
port
);
fu
.
border_size
=
border_size
;
fu
.
line_consumption
=
line_consumption
;
GModel
::
log
(
g
,
node
,
"Line consumption (port "
+
std
::
to_string
(
port
)
+
"): "
+
std
::
to_string
(
fu
.
line_consumption
[
port
]));
}
}
GModel
::
log
(
g
,
node
,
"Line consumption: "
+
std
::
to_string
(
fu
.
line_consumption
)
);
fu
.
border_size
=
borderSize
(
fu
.
k
);
GModel
::
log
(
g
,
node
,
"Border size: "
+
std
::
to_string
(
fu
.
border_size
));
}
}
...
...
@@ -884,17 +945,20 @@ namespace
{
const
auto
&
fu
=
fg
.
metadata
(
node
).
get
<
FluidUnit
>
();
for
(
const
auto
&
in_
data_node
:
node
->
inNod
es
())
for
(
const
auto
&
in_
edge
:
node
->
inEdg
es
())
{
const
auto
&
in_data_node
=
in_edge
->
srcNode
();
auto
port
=
g
.
metadata
(
in_edge
).
get
<
Input
>
().
port
;
auto
&
fd
=
fg
.
metadata
(
in_data_node
).
get
<
FluidData
>
();
// Update (not Set) fields here since a single data node may be
// accessed by multiple consumers
fd
.
max_consumption
=
std
::
max
(
fu
.
line_consumption
,
fd
.
max_consumption
);
fd
.
max_consumption
=
std
::
max
(
fu
.
line_consumption
[
port
]
,
fd
.
max_consumption
);
fd
.
border_size
=
std
::
max
(
fu
.
border_size
,
fd
.
border_size
);
GModel
::
log
(
g
,
in_data_node
,
"Line consumption: "
+
std
::
to_string
(
fd
.
max_consumption
)
+
" (upd by "
+
std
::
to_string
(
fu
.
line_consumption
)
+
")"
,
node
);
+
" (upd by "
+
std
::
to_string
(
fu
.
line_consumption
[
port
]
)
+
")"
,
node
);
GModel
::
log
(
g
,
in_data_node
,
"Border size: "
+
std
::
to_string
(
fd
.
border_size
),
node
);
}
}
...
...
@@ -914,17 +978,18 @@ namespace
{
const
auto
&
fu
=
fg
.
metadata
(
node
).
get
<
FluidUnit
>
();
const
int
own_latency
=
fu
.
line_consumption
-
fu
.
border_size
;
GModel
::
log
(
g
,
node
,
"LPI: "
+
std
::
to_string
(
fu
.
k
.
m_lpi
));
// Output latency is max(input_latency) + own_latency
int
in
_latency
=
0
;
for
(
const
auto
&
in_
data_node
:
node
->
inNod
es
())
int
out
_latency
=
0
;
for
(
const
auto
&
in_
edge
:
node
->
inEdg
es
())
{
// FIXME: ASSERT(DATA), ASSERT(FLUIDDATA)
in_latency
=
std
::
max
(
in_latency
,
fg
.
metadata
(
in_data_node
).
get
<
FluidData
>
().
latency
);
const
auto
port
=
g
.
metadata
(
in_edge
).
get
<
Input
>
().
port
;
const
auto
own_latency
=
fu
.
line_consumption
[
port
]
-
fu
.
border_size
;
const
auto
in_latency
=
fg
.
metadata
(
in_edge
->
srcNode
()).
get
<
FluidData
>
().
latency
;
out_latency
=
std
::
max
(
out_latency
,
in_latency
+
own_latency
);
}
const
int
out_latency
=
in_latency
+
own_latency
;
for
(
const
auto
&
out_data_node
:
node
->
outNodes
())
{
...
...
@@ -1018,7 +1083,7 @@ void cv::gimpl::GFluidExecutable::makeReshape(const std::vector<gapi::own::Rect>
if
(
buf_idx
>=
0
)
{
agent
->
in_views
[
in_idx
].
priv
().
allocate
(
fu
.
line_consumption
,
fu
.
border
);
agent
->
in_views
[
in_idx
].
priv
().
allocate
(
fu
.
line_consumption
[
in_idx
]
,
fu
.
border
);
}
}
...
...
modules/gapi/src/backends/fluid/gfluidbackend.hpp
浏览文件 @
c0076b58
...
...
@@ -4,10 +4,12 @@
//
// Copyright (C) 2018 Intel Corporation
#ifndef OPENCV_GAPI_FLUID_BACKEND_HPP
#define OPENCV_GAPI_FLUID_BACKEND_HPP
// FIXME? Actually gfluidbackend.hpp is not included anywhere
// and can be placed in gfluidbackend.cpp
#include "opencv2/gapi/garg.hpp"
#include "opencv2/gapi/gproto.hpp"
#include "opencv2/gapi/fluid/gfluidkernel.hpp"
...
...
@@ -25,7 +27,7 @@ struct FluidUnit
GFluidKernel
k
;
gapi
::
fluid
::
BorderOpt
border
;
int
border_size
;
int
line_consumption
;
std
::
vector
<
int
>
line_consumption
;
double
ratio
;
};
...
...
@@ -90,8 +92,8 @@ public:
private:
// FIXME!!!
// move to another class
virtual
int
firstWindow
()
const
=
0
;
virtual
std
::
pair
<
int
,
int
>
linesReadAndnextWindow
()
const
=
0
;
virtual
int
firstWindow
(
std
::
size_t
inPort
)
const
=
0
;
virtual
std
::
pair
<
int
,
int
>
linesReadAndnextWindow
(
std
::
size_t
inPort
)
const
=
0
;
};
class
GFluidExecutable
final
:
public
GIslandExecutable
...
...
modules/gapi/src/backends/fluid/gfluidbuffer.cpp
浏览文件 @
c0076b58
...
...
@@ -519,6 +519,9 @@ void fluid::Buffer::Priv::allocate(BorderOpt border,
// Init physical buffer
// FIXME? combine line_consumption with skew?
// FIXME? This formula serves general case to avoid possible deadlock,
// in some cases this value can be smaller:
// 2 lines produced, 2 consumed, data_height can be 2, not 3
auto
data_height
=
std
::
max
(
line_consumption
,
skew
)
+
m_writer_lpi
-
1
;
m_storage
=
createStorage
(
data_height
,
...
...
modules/gapi/test/gapi_fluid_resize_test.cpp
浏览文件 @
c0076b58
...
...
@@ -717,4 +717,77 @@ INSTANTIATE_TEST_CASE_P(ResizeTestCPU, BlursAfterResizeTest,
std
::
make_tuple
(
cv
::
Size
{
64
,
64
},
cv
::
Size
{
49
,
49
},
cv
::
Rect
{
0
,
39
,
49
,
10
}))));
struct
NV12PlusResizeTest
:
public
TestWithParam
<
std
::
tuple
<
cv
::
Size
,
cv
::
Size
,
cv
::
Rect
>>
{};
TEST_P
(
NV12PlusResizeTest
,
Test
)
{
cv
::
Size
y_sz
,
out_sz
;
cv
::
Rect
roi
;
std
::
tie
(
y_sz
,
out_sz
,
roi
)
=
GetParam
();
int
interp
=
cv
::
INTER_LINEAR
;
cv
::
Size
uv_sz
(
y_sz
.
width
/
2
,
y_sz
.
height
/
2
);
cv
::
Size
in_sz
(
y_sz
.
width
,
y_sz
.
height
*
3
/
2
);
cv
::
Mat
in_mat
=
cv
::
Mat
(
in_sz
,
CV_8UC1
);
cv
::
Scalar
mean
=
cv
::
Scalar
(
127.0
f
);
cv
::
Scalar
stddev
=
cv
::
Scalar
(
40.
f
);
cv
::
randn
(
in_mat
,
mean
,
stddev
);
cv
::
Mat
y_mat
=
cv
::
Mat
(
y_sz
,
CV_8UC1
,
in_mat
.
data
);
cv
::
Mat
uv_mat
=
cv
::
Mat
(
uv_sz
,
CV_8UC2
,
in_mat
.
data
+
in_mat
.
step1
()
*
y_sz
.
height
);
cv
::
Mat
out_mat
,
out_mat_ocv
;
cv
::
GMat
y
,
uv
;
auto
rgb
=
cv
::
gapi
::
NV12toRGB
(
y
,
uv
);
auto
out
=
cv
::
gapi
::
resize
(
rgb
,
out_sz
,
0
,
0
,
interp
);
cv
::
GComputation
c
(
cv
::
GIn
(
y
,
uv
),
cv
::
GOut
(
out
));
auto
pkg
=
cv
::
gapi
::
combine
(
fluidTestPackage
,
cv
::
gapi
::
core
::
fluid
::
kernels
(),
cv
::
unite_policy
::
KEEP
);
c
.
apply
(
cv
::
gin
(
y_mat
,
uv_mat
),
cv
::
gout
(
out_mat
)
,
cv
::
compile_args
(
pkg
,
cv
::
GFluidOutputRois
{{
to_own
(
roi
)}}));
cv
::
Mat
rgb_mat
;
cv
::
cvtColor
(
in_mat
,
rgb_mat
,
cv
::
COLOR_YUV2RGB_NV12
);
cv
::
resize
(
rgb_mat
,
out_mat_ocv
,
out_sz
,
0
,
0
,
interp
);
EXPECT_EQ
(
0
,
cv
::
countNonZero
(
out_mat
(
roi
)
!=
out_mat_ocv
(
roi
)));
}
INSTANTIATE_TEST_CASE_P
(
Fluid
,
NV12PlusResizeTest
,
Values
(
std
::
make_tuple
(
cv
::
Size
{
8
,
8
},
cv
::
Size
{
4
,
4
},
cv
::
Rect
{
0
,
0
,
4
,
4
})
,
std
::
make_tuple
(
cv
::
Size
{
8
,
8
},
cv
::
Size
{
4
,
4
},
cv
::
Rect
{
0
,
0
,
4
,
1
})
,
std
::
make_tuple
(
cv
::
Size
{
8
,
8
},
cv
::
Size
{
4
,
4
},
cv
::
Rect
{
0
,
1
,
4
,
2
})
,
std
::
make_tuple
(
cv
::
Size
{
8
,
8
},
cv
::
Size
{
4
,
4
},
cv
::
Rect
{
0
,
2
,
4
,
2
})
,
std
::
make_tuple
(
cv
::
Size
{
64
,
64
},
cv
::
Size
{
49
,
49
},
cv
::
Rect
{
0
,
0
,
49
,
49
})
,
std
::
make_tuple
(
cv
::
Size
{
64
,
64
},
cv
::
Size
{
49
,
49
},
cv
::
Rect
{
0
,
0
,
49
,
12
})
,
std
::
make_tuple
(
cv
::
Size
{
64
,
64
},
cv
::
Size
{
49
,
49
},
cv
::
Rect
{
0
,
11
,
49
,
15
})
,
std
::
make_tuple
(
cv
::
Size
{
64
,
64
},
cv
::
Size
{
49
,
49
},
cv
::
Rect
{
0
,
39
,
49
,
10
})
,
std
::
make_tuple
(
cv
::
Size
{
1920
,
1080
},
cv
::
Size
{
320
,
256
},
cv
::
Rect
{
0
,
0
,
320
,
64
})
,
std
::
make_tuple
(
cv
::
Size
{
1920
,
1080
},
cv
::
Size
{
320
,
256
},
cv
::
Rect
{
0
,
64
,
320
,
64
})
,
std
::
make_tuple
(
cv
::
Size
{
1920
,
1080
},
cv
::
Size
{
320
,
256
},
cv
::
Rect
{
0
,
128
,
320
,
64
})
,
std
::
make_tuple
(
cv
::
Size
{
1920
,
1080
},
cv
::
Size
{
320
,
256
},
cv
::
Rect
{
0
,
192
,
320
,
64
})
,
std
::
make_tuple
(
cv
::
Size
{
256
,
400
},
cv
::
Size
{
32
,
64
},
cv
::
Rect
{
0
,
0
,
32
,
16
})
,
std
::
make_tuple
(
cv
::
Size
{
256
,
400
},
cv
::
Size
{
32
,
64
},
cv
::
Rect
{
0
,
16
,
32
,
16
})
,
std
::
make_tuple
(
cv
::
Size
{
256
,
400
},
cv
::
Size
{
32
,
64
},
cv
::
Rect
{
0
,
32
,
32
,
16
})
,
std
::
make_tuple
(
cv
::
Size
{
256
,
400
},
cv
::
Size
{
32
,
64
},
cv
::
Rect
{
0
,
48
,
32
,
16
})
));
}
// namespace opencv_test
modules/gapi/test/gapi_fluid_test.cpp
浏览文件 @
c0076b58
...
...
@@ -710,4 +710,46 @@ TEST(FluidTwoIslands, SanityTest)
EXPECT_EQ
(
0
,
countNonZero
(
in_mat2
!=
out_mat2
));
}
struct
NV12RoiTest
:
public
TestWithParam
<
std
::
pair
<
cv
::
Size
,
cv
::
Rect
>>
{};
TEST_P
(
NV12RoiTest
,
Test
)
{
cv
::
Size
y_sz
;
cv
::
Rect
roi
;
std
::
tie
(
y_sz
,
roi
)
=
GetParam
();
cv
::
Size
uv_sz
(
y_sz
.
width
/
2
,
y_sz
.
height
/
2
);
cv
::
Size
in_sz
(
y_sz
.
width
,
y_sz
.
height
*
3
/
2
);
cv
::
Mat
in_mat
=
cv
::
Mat
(
in_sz
,
CV_8UC1
);
cv
::
Scalar
mean
=
cv
::
Scalar
(
127.0
f
);
cv
::
Scalar
stddev
=
cv
::
Scalar
(
40.
f
);
cv
::
randn
(
in_mat
,
mean
,
stddev
);
cv
::
Mat
y_mat
=
cv
::
Mat
(
y_sz
,
CV_8UC1
,
in_mat
.
data
);
cv
::
Mat
uv_mat
=
cv
::
Mat
(
uv_sz
,
CV_8UC2
,
in_mat
.
data
+
in_mat
.
step1
()
*
y_sz
.
height
);
cv
::
Mat
out_mat
,
out_mat_ocv
;
cv
::
GMat
y
,
uv
;
auto
rgb
=
cv
::
gapi
::
NV12toRGB
(
y
,
uv
);
cv
::
GComputation
c
(
cv
::
GIn
(
y
,
uv
),
cv
::
GOut
(
rgb
));
c
.
apply
(
cv
::
gin
(
y_mat
,
uv_mat
),
cv
::
gout
(
out_mat
),
cv
::
compile_args
(
fluidTestPackage
,
cv
::
GFluidOutputRois
{{
to_own
(
roi
)}}));
cv
::
cvtColor
(
in_mat
,
out_mat_ocv
,
cv
::
COLOR_YUV2RGB_NV12
);
EXPECT_EQ
(
0
,
cv
::
countNonZero
(
out_mat
(
roi
)
!=
out_mat_ocv
(
roi
)));
}
INSTANTIATE_TEST_CASE_P
(
Fluid
,
NV12RoiTest
,
Values
(
std
::
make_pair
(
cv
::
Size
{
8
,
8
},
cv
::
Rect
{
0
,
0
,
8
,
2
})
,
std
::
make_pair
(
cv
::
Size
{
8
,
8
},
cv
::
Rect
{
0
,
2
,
8
,
2
})
,
std
::
make_pair
(
cv
::
Size
{
8
,
8
},
cv
::
Rect
{
0
,
4
,
8
,
2
})
,
std
::
make_pair
(
cv
::
Size
{
8
,
8
},
cv
::
Rect
{
0
,
6
,
8
,
2
})
,
std
::
make_pair
(
cv
::
Size
{
1920
,
1080
},
cv
::
Rect
{
0
,
0
,
1920
,
270
})
,
std
::
make_pair
(
cv
::
Size
{
1920
,
1080
},
cv
::
Rect
{
0
,
270
,
1920
,
270
})
,
std
::
make_pair
(
cv
::
Size
{
1920
,
1080
},
cv
::
Rect
{
0
,
540
,
1920
,
270
})
,
std
::
make_pair
(
cv
::
Size
{
1920
,
1080
},
cv
::
Rect
{
0
,
710
,
1920
,
270
})
));
}
// namespace opencv_test
modules/gapi/test/gapi_fluid_test_kernels.cpp
浏览文件 @
c0076b58
...
...
@@ -416,6 +416,76 @@ GAPI_FLUID_KERNEL(FSum2MatsAndScalar, TSum2MatsAndScalar, false)
}
};
static
const
int
ITUR_BT_601_CY
=
1220542
;
static
const
int
ITUR_BT_601_CUB
=
2116026
;
static
const
int
ITUR_BT_601_CUG
=
-
409993
;
static
const
int
ITUR_BT_601_CVG
=
-
852492
;
static
const
int
ITUR_BT_601_CVR
=
1673527
;
static
const
int
ITUR_BT_601_SHIFT
=
20
;
static
inline
void
uvToRGBuv
(
const
uchar
u
,
const
uchar
v
,
int
&
ruv
,
int
&
guv
,
int
&
buv
)
{
int
uu
,
vv
;
uu
=
int
(
u
)
-
128
;
vv
=
int
(
v
)
-
128
;
ruv
=
(
1
<<
(
ITUR_BT_601_SHIFT
-
1
))
+
ITUR_BT_601_CVR
*
vv
;
guv
=
(
1
<<
(
ITUR_BT_601_SHIFT
-
1
))
+
ITUR_BT_601_CVG
*
vv
+
ITUR_BT_601_CUG
*
uu
;
buv
=
(
1
<<
(
ITUR_BT_601_SHIFT
-
1
))
+
ITUR_BT_601_CUB
*
uu
;
}
static
inline
void
yRGBuvToRGB
(
const
uchar
vy
,
const
int
ruv
,
const
int
guv
,
const
int
buv
,
uchar
&
r
,
uchar
&
g
,
uchar
&
b
)
{
int
y
=
std
::
max
(
0
,
vy
-
16
)
*
ITUR_BT_601_CY
;
r
=
saturate_cast
<
uchar
>
((
y
+
ruv
)
>>
ITUR_BT_601_SHIFT
);
g
=
saturate_cast
<
uchar
>
((
y
+
guv
)
>>
ITUR_BT_601_SHIFT
);
b
=
saturate_cast
<
uchar
>
((
y
+
buv
)
>>
ITUR_BT_601_SHIFT
);
}
GAPI_FLUID_KERNEL
(
FNV12toRGB
,
cv
::
gapi
::
imgproc
::
GNV12toRGB
,
false
)
{
static
const
int
Window
=
1
;
static
const
int
LPI
=
2
;
static
const
auto
Kind
=
GFluidKernel
::
Kind
::
NV12toRGB
;
static
void
run
(
const
cv
::
gapi
::
fluid
::
View
&
in1
,
const
cv
::
gapi
::
fluid
::
View
&
in2
,
cv
::
gapi
::
fluid
::
Buffer
&
out
)
{
const
auto
w
=
out
.
length
();
GAPI_Assert
(
w
%
2
==
0
);
GAPI_Assert
(
out
.
lpi
()
==
2
);
const
uchar
*
uv_row
=
in2
.
InLineB
(
0
);
const
uchar
*
y_rows
[]
=
{
in1
.
InLineB
(
0
),
in1
.
InLineB
(
1
)};
uchar
*
out_rows
[]
=
{
out
.
OutLineB
(
0
),
out
.
OutLineB
(
1
)};
for
(
int
i
=
0
;
i
<
w
/
2
;
i
++
)
{
uchar
u
=
uv_row
[
2
*
i
];
uchar
v
=
uv_row
[
2
*
i
+
1
];
int
ruv
,
guv
,
buv
;
uvToRGBuv
(
u
,
v
,
ruv
,
guv
,
buv
);
for
(
int
y
=
0
;
y
<
2
;
y
++
)
{
for
(
int
x
=
0
;
x
<
2
;
x
++
)
{
uchar
vy
=
y_rows
[
y
][
2
*
i
+
x
];
uchar
r
,
g
,
b
;
yRGBuvToRGB
(
vy
,
ruv
,
guv
,
buv
,
r
,
g
,
b
);
out_rows
[
y
][
3
*
(
2
*
i
+
x
)]
=
r
;
out_rows
[
y
][
3
*
(
2
*
i
+
x
)
+
1
]
=
g
;
out_rows
[
y
][
3
*
(
2
*
i
+
x
)
+
2
]
=
b
;
}
}
}
}
};
cv
::
gapi
::
GKernelPackage
fluidTestPackage
=
cv
::
gapi
::
kernels
<
FAddSimple
,
FAddCSimple
...
...
@@ -428,6 +498,7 @@ cv::gapi::GKernelPackage fluidTestPackage = cv::gapi::kernels
,
FBlur5x5_2lpi
,
FIdentity
,
FId7x7
,
FNV12toRGB
,
FPlusRow0
,
FSum2MatsAndScalar
,
FTestSplit3
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录