Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenCV
opencv
提交
ed941365
O
opencv
项目概览
OpenCV
/
opencv
上一次同步 9 个月
通知
992
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 搜索 >>
提交
ed941365
编写于
2月 06, 2018
作者:
D
Dmitry Kurtaev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
OpenCV face detection network using Inference Engine backend
上级
398ebbac
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
150 addition
and
45 deletion
+150
-45
cmake/OpenCVDetectInferenceEngine.cmake
cmake/OpenCVDetectInferenceEngine.cmake
+3
-0
modules/dnn/perf/perf_net.cpp
modules/dnn/perf/perf_net.cpp
+10
-0
modules/dnn/src/dnn.cpp
modules/dnn/src/dnn.cpp
+74
-10
modules/dnn/src/layers/batch_norm_layer.cpp
modules/dnn/src/layers/batch_norm_layer.cpp
+4
-6
modules/dnn/src/layers/prior_box_layer.cpp
modules/dnn/src/layers/prior_box_layer.cpp
+1
-1
modules/dnn/src/op_inf_engine.cpp
modules/dnn/src/op_inf_engine.cpp
+45
-26
modules/dnn/test/test_backends.cpp
modules/dnn/test/test_backends.cpp
+12
-0
modules/dnn/test/test_tf_importer.cpp
modules/dnn/test/test_tf_importer.cpp
+1
-2
未找到文件。
cmake/OpenCVDetectInferenceEngine.cmake
浏览文件 @
ed941365
...
...
@@ -20,6 +20,9 @@ if(NOT INF_ENGINE_ROOT_DIR OR NOT EXISTS "${INF_ENGINE_ROOT_DIR}/inference_engin
if
(
DEFINED ENV{INTEL_CVSDK_DIR}
)
list
(
APPEND ie_root_paths
"$ENV{INTEL_CVSDK_DIR}"
)
endif
()
if
(
DEFINED INTEL_CVSDK_DIR
)
list
(
APPEND ie_root_paths
"
${
INTEL_CVSDK_DIR
}
"
)
endif
()
if
(
WITH_INF_ENGINE AND NOT ie_root_paths
)
list
(
APPEND ie_root_paths
"/opt/intel/deeplearning_deploymenttoolkit/deployment_tools"
)
...
...
modules/dnn/perf/perf_net.cpp
浏览文件 @
ed941365
...
...
@@ -150,6 +150,7 @@ PERF_TEST_P_(DNNTestNetwork, SSD)
PERF_TEST_P_
(
DNNTestNetwork
,
OpenFace
)
{
if
(
backend
==
DNN_BACKEND_HALIDE
)
throw
SkipTestException
(
""
);
processNet
(
"dnn/openface_nn4.small2.v1.t7"
,
""
,
""
,
Mat
(
cv
::
Size
(
96
,
96
),
CV_32FC3
),
""
,
"torch"
);
}
...
...
@@ -197,6 +198,15 @@ PERF_TEST_P_(DNNTestNetwork, OpenPose_pose_mpi_faster_4_stages)
Mat
(
cv
::
Size
(
368
,
368
),
CV_32FC3
),
""
,
"caffe"
);
}
PERF_TEST_P_
(
DNNTestNetwork
,
opencv_face_detector
)
{
if
(
backend
==
DNN_BACKEND_HALIDE
||
backend
==
DNN_BACKEND_DEFAULT
&&
target
==
DNN_TARGET_OPENCL
)
throw
SkipTestException
(
""
);
processNet
(
"dnn/opencv_face_detector.caffemodel"
,
"dnn/opencv_face_detector.prototxt"
,
""
,
Mat
(
cv
::
Size
(
300
,
300
),
CV_32FC3
),
""
,
"caffe"
);
}
const
tuple
<
DNNBackend
,
DNNTarget
>
testCases
[]
=
{
#ifdef HAVE_HALIDE
tuple
<
DNNBackend
,
DNNTarget
>
(
DNN_BACKEND_HALIDE
,
DNN_TARGET_CPU
),
...
...
modules/dnn/src/dnn.cpp
浏览文件 @
ed941365
...
...
@@ -1077,35 +1077,72 @@ struct Net::Impl
}
}
#ifdef HAVE_INF_ENGINE
// Before launching Inference Engine graph we need to specify output blobs.
// This function requests output blobs based on inputs references of
// layers from default backend or layers from different graphs.
void
addInfEngineNetOutputs
(
LayerData
&
ld
)
{
Ptr
<
InfEngineBackendNet
>
layerNet
;
if
(
ld
.
backendNodes
.
find
(
preferableBackend
)
!=
ld
.
backendNodes
.
end
())
{
Ptr
<
BackendNode
>
node
=
ld
.
backendNodes
[
preferableBackend
];
if
(
!
node
.
empty
())
{
Ptr
<
InfEngineBackendNode
>
ieNode
=
node
.
dynamicCast
<
InfEngineBackendNode
>
();
CV_Assert
(
!
ieNode
.
empty
(),
!
ieNode
->
net
.
empty
());
layerNet
=
ieNode
->
net
;
}
}
// For an every input reference we check that it belongs to one of
// the Inference Engine backend graphs. Request an output blob if it is.
// Do nothing if layer's input is from the same graph.
for
(
int
i
=
0
;
i
<
ld
.
inputBlobsId
.
size
();
++
i
)
{
LayerData
&
inpLd
=
layers
[
ld
.
inputBlobsId
[
i
].
lid
];
Ptr
<
BackendNode
>
inpNode
=
inpLd
.
backendNodes
[
preferableBackend
];
if
(
!
inpNode
.
empty
())
{
Ptr
<
InfEngineBackendNode
>
ieInpNode
=
inpNode
.
dynamicCast
<
InfEngineBackendNode
>
();
CV_Assert
(
!
ieInpNode
.
empty
(),
!
ieInpNode
->
net
.
empty
());
if
(
layerNet
!=
ieInpNode
->
net
)
{
// layerNet is empty or nodes are from different graphs.
ieInpNode
->
net
->
addOutput
(
inpLd
.
name
);
}
}
}
}
#endif // HAVE_INF_ENGINE
void
initInfEngineBackend
()
{
// Build Inference Engine networks from sets of layers that support this
// backend.
If an internal layer isn't supported we'll use default
//
implementation of it but build a new network after it
.
// backend.
Split a whole model on several Inference Engine networks if
//
some of layers is not implemented
.
CV_TRACE_FUNCTION
();
CV_Assert
(
preferableBackend
==
DNN_BACKEND_INFERENCE_ENGINE
,
haveInfEngine
());
#ifdef HAVE_INF_ENGINE
MapIdToLayerData
::
iterator
it
;
Ptr
<
InfEngineBackendNet
>
net
;
// Set of all input and output blobs wrappers for current network.
std
::
map
<
int
,
Ptr
<
BackendWrapper
>
>
netBlobsWrappers
;
for
(
it
=
layers
.
begin
();
it
!=
layers
.
end
();
++
it
)
{
LayerData
&
ld
=
it
->
second
;
ld
.
skip
=
true
;
ld
.
skip
=
true
;
// Initially skip all Inference Engine supported layers.
Ptr
<
Layer
>
layer
=
ld
.
layerInstance
;
if
(
!
layer
->
supportBackend
(
preferableBackend
))
{
for
(
int
i
=
0
;
i
<
ld
.
outputBlobsWrappers
.
size
();
++
i
)
{
auto
dataPtr
=
infEngineDataNode
(
ld
.
outputBlobsWrappers
[
i
]);
dataPtr
->
name
=
ld
.
name
;
}
addInfEngineNetOutputs
(
ld
);
ld
.
skip
=
false
;
net
=
Ptr
<
InfEngineBackendNet
>
();
netBlobsWrappers
.
clear
();
continue
;
}
// C
heck what all inputs are from the same network or from default backend
.
// C
reate a new network if one of inputs from different Inference Engine graph
.
for
(
int
i
=
0
;
i
<
ld
.
inputBlobsId
.
size
();
++
i
)
{
LayerData
&
inpLd
=
layers
[
ld
.
inputBlobsId
[
i
].
lid
];
...
...
@@ -1113,10 +1150,36 @@ struct Net::Impl
if
(
!
inpNode
.
empty
())
{
Ptr
<
InfEngineBackendNode
>
ieInpNode
=
inpNode
.
dynamicCast
<
InfEngineBackendNode
>
();
CV_Assert
(
!
ieInpNode
.
empty
(),
net
.
empty
()
||
net
==
ieInpNode
->
net
);
CV_Assert
(
!
ieInpNode
.
empty
(),
!
ieInpNode
->
net
.
empty
());
if
(
ieInpNode
->
net
!=
net
)
{
net
=
Ptr
<
InfEngineBackendNet
>
();
netBlobsWrappers
.
clear
();
break
;
}
}
}
// The same blobs wrappers cannot be shared between two Inference Engine
// networks because of explicit references between layers and blobs.
// So we need to rewrap all the external blobs.
for
(
int
i
=
0
;
i
<
ld
.
inputBlobsId
.
size
();
++
i
)
{
int
lid
=
ld
.
inputBlobsId
[
i
].
lid
;
LayerData
&
inpLd
=
layers
[
lid
];
auto
it
=
netBlobsWrappers
.
find
(
lid
);
if
(
it
==
netBlobsWrappers
.
end
())
{
ld
.
inputBlobsWrappers
[
i
]
=
wrap
(
*
ld
.
inputBlobs
[
i
]);
auto
dataPtr
=
infEngineDataNode
(
ld
.
inputBlobsWrappers
[
i
]);
dataPtr
->
name
=
inpLd
.
name
;
netBlobsWrappers
[
lid
]
=
ld
.
inputBlobsWrappers
[
i
];
}
else
ld
.
inputBlobsWrappers
[
i
]
=
it
->
second
;
}
netBlobsWrappers
[
ld
.
id
]
=
ld
.
outputBlobsWrappers
[
0
];
bool
fused
=
false
;
Ptr
<
BackendNode
>
node
;
if
(
!
net
.
empty
())
...
...
@@ -1153,6 +1216,7 @@ struct Net::Impl
if
(
!
fused
)
net
->
addLayer
(
ieNode
->
layer
);
addInfEngineNetOutputs
(
ld
);
}
// Initialize all networks.
...
...
modules/dnn/src/layers/batch_norm_layer.cpp
浏览文件 @
ed941365
...
...
@@ -277,14 +277,12 @@ public:
#ifdef HAVE_INF_ENGINE
InferenceEngine
::
LayerParams
lp
;
lp
.
name
=
name
;
lp
.
type
=
"
BatchNormalization
"
;
lp
.
type
=
"
ScaleShift
"
;
lp
.
precision
=
InferenceEngine
::
Precision
::
FP32
;
std
::
shared_ptr
<
InferenceEngine
::
BatchNormalizationLayer
>
ieLayer
(
new
InferenceEngine
::
BatchNormalization
Layer
(
lp
));
std
::
shared_ptr
<
InferenceEngine
::
ScaleShiftLayer
>
ieLayer
(
new
InferenceEngine
::
ScaleShift
Layer
(
lp
));
size_t
numChannels
=
weights_
.
total
();
ieLayer
->
epsilon
=
epsilon
;
ieLayer
->
_weights
=
wrapToInfEngineBlob
(
blobs
[
1
],
{
numChannels
});
ieLayer
->
_biases
=
wrapToInfEngineBlob
(
blobs
[
0
],
{
numChannels
});
ieLayer
->
_weights
=
wrapToInfEngineBlob
(
weights_
);
ieLayer
->
_biases
=
wrapToInfEngineBlob
(
bias_
);
return
Ptr
<
BackendNode
>
(
new
InfEngineBackendNode
(
ieLayer
));
#endif // HAVE_INF_ENGINE
...
...
modules/dnn/src/layers/prior_box_layer.cpp
浏览文件 @
ed941365
...
...
@@ -550,7 +550,7 @@ public:
for
(
int
i
=
1
;
i
<
_variance
.
size
();
++
i
)
ieLayer
->
params
[
"variance"
]
+=
format
(
",%f"
,
_variance
[
i
]);
ieLayer
->
params
[
"step"
]
=
"0"
;
ieLayer
->
params
[
"step"
]
=
_stepX
==
_stepY
?
format
(
"%f"
,
_stepX
)
:
"0"
;
ieLayer
->
params
[
"step_h"
]
=
_stepY
;
ieLayer
->
params
[
"step_w"
]
=
_stepX
;
...
...
modules/dnn/src/op_inf_engine.cpp
浏览文件 @
ed941365
...
...
@@ -116,31 +116,6 @@ InferenceEngine::Precision InfEngineBackendNet::getPrecision() noexcept
// Assume that outputs of network is unconnected blobs.
void
InfEngineBackendNet
::
getOutputsInfo
(
InferenceEngine
::
OutputsDataMap
&
outputs_
)
noexcept
{
if
(
outputs
.
empty
())
{
for
(
const
auto
&
l
:
layers
)
{
// Add all outputs.
for
(
const
InferenceEngine
::
DataPtr
&
out
:
l
->
outData
)
{
// TODO: Replace to uniquness assertion.
if
(
outputs
.
find
(
out
->
name
)
==
outputs
.
end
())
outputs
[
out
->
name
]
=
out
;
}
// Remove internally connected outputs.
for
(
const
InferenceEngine
::
DataWeakPtr
&
inp
:
l
->
insData
)
{
outputs
.
erase
(
InferenceEngine
::
DataPtr
(
inp
)
->
name
);
}
}
CV_Assert
(
layers
.
empty
()
||
!
outputs
.
empty
());
}
outBlobs
.
clear
();
for
(
const
auto
&
it
:
outputs
)
{
CV_Assert
(
allBlobs
.
find
(
it
.
first
)
!=
allBlobs
.
end
());
outBlobs
[
it
.
first
]
=
allBlobs
[
it
.
first
];
}
outputs_
=
outputs
;
}
...
...
@@ -216,7 +191,18 @@ InferenceEngine::StatusCode
InfEngineBackendNet
::
addOutput
(
const
std
::
string
&
layerName
,
size_t
outputIndex
,
InferenceEngine
::
ResponseDesc
*
resp
)
noexcept
{
CV_Error
(
Error
::
StsNotImplemented
,
""
);
for
(
const
auto
&
l
:
layers
)
{
for
(
const
InferenceEngine
::
DataPtr
&
out
:
l
->
outData
)
{
if
(
out
->
name
==
layerName
)
{
outputs
[
out
->
name
]
=
out
;
return
InferenceEngine
::
StatusCode
::
OK
;
}
}
}
CV_Error
(
Error
::
StsObjectNotFound
,
"Cannot find a layer "
+
layerName
);
return
InferenceEngine
::
StatusCode
::
OK
;
}
...
...
@@ -254,6 +240,39 @@ size_t InfEngineBackendNet::getBatchSize() const noexcept
void
InfEngineBackendNet
::
initEngine
()
{
CV_Assert
(
!
isInitialized
());
// Add all unconnected blobs to output blobs.
InferenceEngine
::
OutputsDataMap
unconnectedOuts
;
for
(
const
auto
&
l
:
layers
)
{
// Add all outputs.
for
(
const
InferenceEngine
::
DataPtr
&
out
:
l
->
outData
)
{
// TODO: Replace to uniquness assertion.
if
(
unconnectedOuts
.
find
(
out
->
name
)
==
unconnectedOuts
.
end
())
unconnectedOuts
[
out
->
name
]
=
out
;
}
// Remove internally connected outputs.
for
(
const
InferenceEngine
::
DataWeakPtr
&
inp
:
l
->
insData
)
{
unconnectedOuts
.
erase
(
InferenceEngine
::
DataPtr
(
inp
)
->
name
);
}
}
CV_Assert
(
layers
.
empty
()
||
!
unconnectedOuts
.
empty
());
for
(
auto
it
=
unconnectedOuts
.
begin
();
it
!=
unconnectedOuts
.
end
();
++
it
)
{
outputs
[
it
->
first
]
=
it
->
second
;
}
// Set up output blobs.
outBlobs
.
clear
();
for
(
const
auto
&
it
:
outputs
)
{
CV_Assert
(
allBlobs
.
find
(
it
.
first
)
!=
allBlobs
.
end
());
outBlobs
[
it
.
first
]
=
allBlobs
[
it
.
first
];
}
engine
=
InferenceEngine
::
InferenceEnginePluginPtr
(
"libMKLDNNPlugin.so"
);
InferenceEngine
::
ResponseDesc
resp
;
InferenceEngine
::
StatusCode
status
=
engine
->
LoadNetwork
(
*
this
,
&
resp
);
...
...
modules/dnn/test/test_backends.cpp
浏览文件 @
ed941365
...
...
@@ -206,9 +206,21 @@ TEST_P(DNNTestNetwork, OpenPose_pose_mpi_faster_4_stages)
TEST_P
(
DNNTestNetwork
,
OpenFace
)
{
if
(
backend
==
DNN_BACKEND_HALIDE
)
throw
SkipTestException
(
""
);
processNet
(
"dnn/openface_nn4.small2.v1.t7"
,
""
,
Size
(
96
,
96
),
""
,
"torch"
);
}
TEST_P
(
DNNTestNetwork
,
opencv_face_detector
)
{
if
(
backend
==
DNN_BACKEND_HALIDE
||
backend
==
DNN_BACKEND_DEFAULT
&&
target
==
DNN_TARGET_OPENCL
)
throw
SkipTestException
(
""
);
Mat
img
=
imread
(
findDataFile
(
"gpu/lbpcascade/er.png"
,
false
));
Mat
inp
=
blobFromImage
(
img
,
1.0
,
Size
(),
Scalar
(
104.0
,
177.0
,
123.0
),
false
,
false
);
processNet
(
"dnn/opencv_face_detector.caffemodel"
,
"dnn/opencv_face_detector.prototxt"
,
inp
,
"detection_out"
,
"caffe"
);
}
const
tuple
<
DNNBackend
,
DNNTarget
>
testCases
[]
=
{
#ifdef HAVE_HALIDE
tuple
<
DNNBackend
,
DNNTarget
>
(
DNN_BACKEND_HALIDE
,
DNN_TARGET_CPU
),
...
...
modules/dnn/test/test_tf_importer.cpp
浏览文件 @
ed941365
...
...
@@ -279,9 +279,8 @@ TEST(Test_TensorFlow, Inception_v2_SSD)
normAssert
(
detections
,
ref
);
}
OCL_TEST
(
Test_TensorFlow
,
MobileNet_SSD
)
OCL_TEST
(
Test_TensorFlow
,
DISABLED_
MobileNet_SSD
)
{
throw
SkipTestException
(
"TODO: test is failed"
);
std
::
string
netPath
=
findDataFile
(
"dnn/ssd_mobilenet_v1_coco.pb"
,
false
);
std
::
string
netConfig
=
findDataFile
(
"dnn/ssd_mobilenet_v1_coco.pbtxt"
,
false
);
std
::
string
imgPath
=
findDataFile
(
"dnn/street.png"
,
false
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录