From 26e426adb1cc8ffb03069494494ddd15b708d4a1 Mon Sep 17 00:00:00 2001 From: Dmitry Kurtaev Date: Tue, 30 Apr 2019 15:33:32 +0300 Subject: [PATCH] StridedSlice from TensorFlow --- modules/dnn/include/opencv2/dnn/dnn.hpp | 1 + modules/dnn/src/tensorflow/tf_importer.cpp | 37 ++++++++++++++++++++++ modules/dnn/test/test_onnx_importer.cpp | 2 +- modules/dnn/test/test_tf_importer.cpp | 1 + samples/dnn/tf_text_graph_faster_rcnn.py | 8 ++++- 5 files changed, 47 insertions(+), 2 deletions(-) diff --git a/modules/dnn/include/opencv2/dnn/dnn.hpp b/modules/dnn/include/opencv2/dnn/dnn.hpp index a8ee534034..8a653295de 100644 --- a/modules/dnn/include/opencv2/dnn/dnn.hpp +++ b/modules/dnn/include/opencv2/dnn/dnn.hpp @@ -820,6 +820,7 @@ CV__DNN_EXPERIMENTAL_NS_BEGIN * * `*.t7` | `*.net` (Torch, http://torch.ch/) * * `*.weights` (Darknet, https://pjreddie.com/darknet/) * * `*.bin` (DLDT, https://software.intel.com/openvino-toolkit) + * * `*.onnx` (ONNX, https://onnx.ai/) * @param[in] config Text file contains network configuration. It could be a * file with the following extensions: * * `*.prototxt` (Caffe, http://caffe.berkeleyvision.org/) diff --git a/modules/dnn/src/tensorflow/tf_importer.cpp b/modules/dnn/src/tensorflow/tf_importer.cpp index 058dfe0403..f7a515c0a3 100644 --- a/modules/dnn/src/tensorflow/tf_importer.cpp +++ b/modules/dnn/src/tensorflow/tf_importer.cpp @@ -1423,6 +1423,43 @@ void TFImporter::populateNet(Net dstNet) connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); } + else if (type == "StridedSlice") + { + CV_Assert(layer.input_size() == 4); + Mat begins = getTensorContent(getConstBlob(layer, value_id, 1)); + Mat ends = getTensorContent(getConstBlob(layer, value_id, 2)); + Mat strides = getTensorContent(getConstBlob(layer, value_id, 3)); + CV_CheckTypeEQ(begins.type(), CV_32SC1, ""); + CV_CheckTypeEQ(ends.type(), CV_32SC1, ""); + CV_CheckTypeEQ(strides.type(), CV_32SC1, ""); + const int num = begins.total(); + CV_Assert_N(num == ends.total(), num == strides.total()); + + int end_mask = getLayerAttr(layer, "end_mask").i(); + for (int i = 0; i < num; ++i) + { + if (end_mask & (1 << i)) + ends.at(i) = -1; + if (strides.at(i) != 1) + CV_Error(Error::StsNotImplemented, + format("StridedSlice with stride %d", strides.at(i))); + } + if (begins.total() == 4 && getDataLayout(name, data_layouts) == DATA_LAYOUT_NHWC) + { + // Swap NHWC parameters' order to NCHW. + std::swap(begins.at(2), begins.at(3)); + std::swap(begins.at(1), begins.at(2)); + std::swap(ends.at(2), ends.at(3)); + std::swap(ends.at(1), ends.at(2)); + } + layerParams.set("begin", DictValue::arrayInt((int*)begins.data, begins.total())); + layerParams.set("end", DictValue::arrayInt((int*)ends.data, ends.total())); + + int id = dstNet.addLayer(name, "Slice", layerParams); + layer_id[name] = id; + + connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); + } else if (type == "Mul") { bool haveConst = false; diff --git a/modules/dnn/test/test_onnx_importer.cpp b/modules/dnn/test/test_onnx_importer.cpp index eb306283bb..e66012c304 100644 --- a/modules/dnn/test/test_onnx_importer.cpp +++ b/modules/dnn/test/test_onnx_importer.cpp @@ -248,7 +248,7 @@ TEST_P(Test_ONNX_layers, Reshape) TEST_P(Test_ONNX_layers, Softmax) { testONNXModels("softmax"); - testONNXModels("log_softmax"); + testONNXModels("log_softmax", npy, 0, 0, false, false); } INSTANTIATE_TEST_CASE_P(/*nothing*/, Test_ONNX_layers, dnnBackendsAndTargets()); diff --git a/modules/dnn/test/test_tf_importer.cpp b/modules/dnn/test/test_tf_importer.cpp index 2c7ae44783..1a70e8f471 100644 --- a/modules/dnn/test/test_tf_importer.cpp +++ b/modules/dnn/test/test_tf_importer.cpp @@ -663,6 +663,7 @@ TEST_P(Test_TensorFlow_layers, slice) (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16)) throw SkipTestException(""); runTensorFlowNet("slice_4d"); + runTensorFlowNet("strided_slice"); } TEST_P(Test_TensorFlow_layers, softmax) diff --git a/samples/dnn/tf_text_graph_faster_rcnn.py b/samples/dnn/tf_text_graph_faster_rcnn.py index e1dfba9fee..8a88c7328a 100644 --- a/samples/dnn/tf_text_graph_faster_rcnn.py +++ b/samples/dnn/tf_text_graph_faster_rcnn.py @@ -31,7 +31,13 @@ def createFasterRCNNGraph(modelPath, configPath, outputPath): aspect_ratios = [float(ar) for ar in grid_anchor_generator['aspect_ratios']] width_stride = float(grid_anchor_generator['width_stride'][0]) height_stride = float(grid_anchor_generator['height_stride'][0]) - features_stride = float(config['feature_extractor'][0]['first_stage_features_stride'][0]) + + feature_extractor = config['feature_extractor'][0] + if 'type' in feature_extractor and feature_extractor['type'][0] == 'faster_rcnn_nas': + features_stride = 16.0 + else: + features_stride = float(feature_extractor['first_stage_features_stride'][0]) + first_stage_nms_iou_threshold = float(config['first_stage_nms_iou_threshold'][0]) first_stage_max_proposals = int(config['first_stage_max_proposals'][0])