Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Opencv
提交
e71758cf
O
Opencv
项目概览
Greenplum
/
Opencv
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
e71758cf
编写于
12月 12, 2018
作者:
D
Dmitry Kurtaev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Operate with shapes in ONNX models
上级
f1dc26d7
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
128 addition
and
2 deletion
+128
-2
modules/dnn/src/onnx/onnx_importer.cpp
modules/dnn/src/onnx/onnx_importer.cpp
+124
-2
modules/dnn/test/test_onnx_importer.cpp
modules/dnn/test/test_onnx_importer.cpp
+4
-0
未找到文件。
modules/dnn/src/onnx/onnx_importer.cpp
浏览文件 @
e71758cf
...
@@ -6,6 +6,7 @@
...
@@ -6,6 +6,7 @@
// Third party copyrights are property of their respective owners.
// Third party copyrights are property of their respective owners.
#include "../precomp.hpp"
#include "../precomp.hpp"
#include <opencv2/dnn/shape_utils.hpp>
#ifdef HAVE_PROTOBUF
#ifdef HAVE_PROTOBUF
...
@@ -134,9 +135,38 @@ Mat getMatFromTensor(opencv_onnx::TensorProto& tensor_proto)
...
@@ -134,9 +135,38 @@ Mat getMatFromTensor(opencv_onnx::TensorProto& tensor_proto)
else
else
CV_Error
(
Error
::
StsUnsupportedFormat
,
"Unsupported data type: "
+
CV_Error
(
Error
::
StsUnsupportedFormat
,
"Unsupported data type: "
+
opencv_onnx
::
TensorProto_DataType_Name
(
datatype
));
opencv_onnx
::
TensorProto_DataType_Name
(
datatype
));
if
(
tensor_proto
.
dims_size
()
==
0
)
blob
.
dims
=
1
;
// To force 1-dimensional cv::Mat for scalars.
return
blob
;
return
blob
;
}
}
void
runLayer
(
Ptr
<
Layer
>
layer
,
const
std
::
vector
<
Mat
>&
inputs
,
std
::
vector
<
Mat
>&
outputs
)
{
std
::
vector
<
MatShape
>
inpShapes
(
inputs
.
size
());
int
ddepth
=
CV_32F
;
for
(
size_t
i
=
0
;
i
<
inputs
.
size
();
++
i
)
{
inpShapes
[
i
]
=
shape
(
inputs
[
i
]);
if
(
i
>
0
&&
ddepth
!=
inputs
[
i
].
depth
())
CV_Error
(
Error
::
StsNotImplemented
,
"Mixed input data types."
);
ddepth
=
inputs
[
i
].
depth
();
}
std
::
vector
<
MatShape
>
outShapes
,
internalShapes
;
layer
->
getMemoryShapes
(
inpShapes
,
0
,
outShapes
,
internalShapes
);
std
::
vector
<
Mat
>
internals
(
internalShapes
.
size
());
outputs
.
resize
(
outShapes
.
size
());
for
(
size_t
i
=
0
;
i
<
outShapes
.
size
();
++
i
)
outputs
[
i
].
create
(
outShapes
[
i
],
ddepth
);
for
(
size_t
i
=
0
;
i
<
internalShapes
.
size
();
++
i
)
internals
[
i
].
create
(
internalShapes
[
i
],
ddepth
);
layer
->
finalize
(
inputs
,
outputs
);
layer
->
forward
(
inputs
,
outputs
,
internals
);
}
std
::
map
<
std
::
string
,
Mat
>
ONNXImporter
::
getGraphTensors
(
std
::
map
<
std
::
string
,
Mat
>
ONNXImporter
::
getGraphTensors
(
const
opencv_onnx
::
GraphProto
&
graph_proto
)
const
opencv_onnx
::
GraphProto
&
graph_proto
)
{
{
...
@@ -292,6 +322,26 @@ void ONNXImporter::populateNet(Net dstNet)
...
@@ -292,6 +322,26 @@ void ONNXImporter::populateNet(Net dstNet)
CV_Assert
(
model_proto
.
has_graph
());
CV_Assert
(
model_proto
.
has_graph
());
opencv_onnx
::
GraphProto
graph_proto
=
model_proto
.
graph
();
opencv_onnx
::
GraphProto
graph_proto
=
model_proto
.
graph
();
std
::
map
<
std
::
string
,
Mat
>
constBlobs
=
getGraphTensors
(
graph_proto
);
std
::
map
<
std
::
string
,
Mat
>
constBlobs
=
getGraphTensors
(
graph_proto
);
// List of internal blobs shapes.
std
::
map
<
std
::
string
,
MatShape
>
outShapes
;
// Add all the inputs shapes. It includes as constant blobs as network's inputs shapes.
for
(
int
i
=
0
;
i
<
graph_proto
.
input_size
();
++
i
)
{
opencv_onnx
::
ValueInfoProto
valueInfoProto
=
graph_proto
.
input
(
i
);
CV_Assert
(
valueInfoProto
.
has_type
());
opencv_onnx
::
TypeProto
typeProto
=
valueInfoProto
.
type
();
CV_Assert
(
typeProto
.
has_tensor_type
());
opencv_onnx
::
TypeProto
::
Tensor
tensor
=
typeProto
.
tensor_type
();
CV_Assert
(
tensor
.
has_shape
());
opencv_onnx
::
TensorShapeProto
tensorShape
=
tensor
.
shape
();
MatShape
inpShape
(
tensorShape
.
dim_size
());
for
(
int
j
=
0
;
j
<
inpShape
.
size
();
++
j
)
{
inpShape
[
j
]
=
tensorShape
.
dim
(
j
).
dim_value
();
}
outShapes
[
valueInfoProto
.
name
()]
=
inpShape
;
}
std
::
string
framework_name
;
std
::
string
framework_name
;
if
(
model_proto
.
has_producer_name
())
{
if
(
model_proto
.
has_producer_name
())
{
...
@@ -301,6 +351,7 @@ void ONNXImporter::populateNet(Net dstNet)
...
@@ -301,6 +351,7 @@ void ONNXImporter::populateNet(Net dstNet)
// create map with network inputs (without const blobs)
// create map with network inputs (without const blobs)
std
::
map
<
std
::
string
,
LayerInfo
>
layer_id
;
std
::
map
<
std
::
string
,
LayerInfo
>
layer_id
;
std
::
map
<
std
::
string
,
LayerInfo
>::
iterator
layerId
;
std
::
map
<
std
::
string
,
LayerInfo
>::
iterator
layerId
;
std
::
map
<
std
::
string
,
MatShape
>::
iterator
shapeIt
;
// fill map: push layer name, layer id and output id
// fill map: push layer name, layer id and output id
std
::
vector
<
String
>
netInputs
;
std
::
vector
<
String
>
netInputs
;
for
(
int
j
=
0
;
j
<
graph_proto
.
input_size
();
j
++
)
for
(
int
j
=
0
;
j
<
graph_proto
.
input_size
();
j
++
)
...
@@ -317,9 +368,9 @@ void ONNXImporter::populateNet(Net dstNet)
...
@@ -317,9 +368,9 @@ void ONNXImporter::populateNet(Net dstNet)
LayerParams
layerParams
;
LayerParams
layerParams
;
opencv_onnx
::
NodeProto
node_proto
;
opencv_onnx
::
NodeProto
node_proto
;
for
(
int
i
=
0
;
i
<
layersSize
;
i
++
)
for
(
int
li
=
0
;
li
<
layersSize
;
l
i
++
)
{
{
node_proto
=
graph_proto
.
node
(
i
);
node_proto
=
graph_proto
.
node
(
l
i
);
layerParams
=
getLayerParams
(
node_proto
);
layerParams
=
getLayerParams
(
node_proto
);
CV_Assert
(
node_proto
.
output_size
()
>=
1
);
CV_Assert
(
node_proto
.
output_size
()
>=
1
);
layerParams
.
name
=
node_proto
.
output
(
0
);
layerParams
.
name
=
node_proto
.
output
(
0
);
...
@@ -598,6 +649,65 @@ void ONNXImporter::populateNet(Net dstNet)
...
@@ -598,6 +649,65 @@ void ONNXImporter::populateNet(Net dstNet)
{
{
layerParams
.
type
=
"Padding"
;
layerParams
.
type
=
"Padding"
;
}
}
else
if
(
layer_type
==
"Shape"
)
{
CV_Assert
(
node_proto
.
input_size
()
==
1
);
shapeIt
=
outShapes
.
find
(
node_proto
.
input
(
0
));
CV_Assert
(
shapeIt
!=
outShapes
.
end
());
MatShape
inpShape
=
shapeIt
->
second
;
Mat
shapeMat
(
inpShape
.
size
(),
1
,
CV_32S
);
for
(
int
j
=
0
;
j
<
inpShape
.
size
();
++
j
)
shapeMat
.
at
<
int
>
(
j
)
=
inpShape
[
j
];
shapeMat
.
dims
=
1
;
constBlobs
.
insert
(
std
::
make_pair
(
layerParams
.
name
,
shapeMat
));
continue
;
}
else
if
(
layer_type
==
"Gather"
)
{
CV_Assert
(
node_proto
.
input_size
()
==
2
);
CV_Assert
(
layerParams
.
has
(
"axis"
));
Mat
input
=
getBlob
(
node_proto
,
constBlobs
,
0
);
Mat
indexMat
=
getBlob
(
node_proto
,
constBlobs
,
1
);
CV_Assert_N
(
indexMat
.
type
()
==
CV_32S
,
indexMat
.
total
()
==
1
);
int
index
=
indexMat
.
at
<
int
>
(
0
);
int
axis
=
layerParams
.
get
<
int
>
(
"axis"
);
std
::
vector
<
cv
::
Range
>
ranges
(
input
.
dims
,
Range
::
all
());
ranges
[
axis
]
=
Range
(
index
,
index
+
1
);
Mat
out
=
input
(
ranges
);
constBlobs
.
insert
(
std
::
make_pair
(
layerParams
.
name
,
out
));
continue
;
}
else
if
(
layer_type
==
"Concat"
)
{
bool
hasVariableInps
=
false
;
for
(
int
i
=
0
;
i
<
node_proto
.
input_size
();
++
i
)
{
if
(
layer_id
.
find
(
node_proto
.
input
(
i
))
!=
layer_id
.
end
())
{
hasVariableInps
=
true
;
break
;
}
}
if
(
!
hasVariableInps
)
{
std
::
vector
<
Mat
>
inputs
(
node_proto
.
input_size
()),
concatenated
;
for
(
size_t
i
=
0
;
i
<
inputs
.
size
();
++
i
)
{
inputs
[
i
]
=
getBlob
(
node_proto
,
constBlobs
,
i
);
}
Ptr
<
Layer
>
concat
=
ConcatLayer
::
create
(
layerParams
);
runLayer
(
concat
,
inputs
,
concatenated
);
CV_Assert
(
concatenated
.
size
()
==
1
);
constBlobs
.
insert
(
std
::
make_pair
(
layerParams
.
name
,
concatenated
[
0
]));
continue
;
}
}
else
else
{
{
for
(
int
j
=
0
;
j
<
node_proto
.
input_size
();
j
++
)
{
for
(
int
j
=
0
;
j
<
node_proto
.
input_size
();
j
++
)
{
...
@@ -609,12 +719,24 @@ void ONNXImporter::populateNet(Net dstNet)
...
@@ -609,12 +719,24 @@ void ONNXImporter::populateNet(Net dstNet)
int
id
=
dstNet
.
addLayer
(
layerParams
.
name
,
layerParams
.
type
,
layerParams
);
int
id
=
dstNet
.
addLayer
(
layerParams
.
name
,
layerParams
.
type
,
layerParams
);
layer_id
.
insert
(
std
::
make_pair
(
layerParams
.
name
,
LayerInfo
(
id
,
0
)));
layer_id
.
insert
(
std
::
make_pair
(
layerParams
.
name
,
LayerInfo
(
id
,
0
)));
std
::
vector
<
MatShape
>
layerInpShapes
,
layerOutShapes
,
layerInternalShapes
;
for
(
int
j
=
0
;
j
<
node_proto
.
input_size
();
j
++
)
{
for
(
int
j
=
0
;
j
<
node_proto
.
input_size
();
j
++
)
{
layerId
=
layer_id
.
find
(
node_proto
.
input
(
j
));
layerId
=
layer_id
.
find
(
node_proto
.
input
(
j
));
if
(
layerId
!=
layer_id
.
end
())
{
if
(
layerId
!=
layer_id
.
end
())
{
dstNet
.
connect
(
layerId
->
second
.
layerId
,
layerId
->
second
.
outputId
,
id
,
j
);
dstNet
.
connect
(
layerId
->
second
.
layerId
,
layerId
->
second
.
outputId
,
id
,
j
);
// Collect input shapes.
shapeIt
=
outShapes
.
find
(
node_proto
.
input
(
j
));
CV_Assert
(
shapeIt
!=
outShapes
.
end
());
layerInpShapes
.
push_back
(
shapeIt
->
second
);
}
}
}
}
// Compute shape of output blob for this layer.
Ptr
<
Layer
>
layer
=
dstNet
.
getLayer
(
id
);
layer
->
getMemoryShapes
(
layerInpShapes
,
0
,
layerOutShapes
,
layerInternalShapes
);
CV_Assert
(
!
layerOutShapes
.
empty
());
outShapes
[
layerParams
.
name
]
=
layerOutShapes
[
0
];
}
}
}
}
...
...
modules/dnn/test/test_onnx_importer.cpp
浏览文件 @
e71758cf
...
@@ -162,6 +162,10 @@ TEST_P(Test_ONNX_layers, MultyInputs)
...
@@ -162,6 +162,10 @@ TEST_P(Test_ONNX_layers, MultyInputs)
normAssert
(
ref
,
out
,
""
,
default_l1
,
default_lInf
);
normAssert
(
ref
,
out
,
""
,
default_l1
,
default_lInf
);
}
}
TEST_P
(
Test_ONNX_layers
,
DynamicReshape
)
{
testONNXModels
(
"dynamic_reshape"
);
}
INSTANTIATE_TEST_CASE_P
(
/*nothing*/
,
Test_ONNX_layers
,
dnnBackendsAndTargets
());
INSTANTIATE_TEST_CASE_P
(
/*nothing*/
,
Test_ONNX_layers
,
dnnBackendsAndTargets
());
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录