diff --git a/modules/dnn/src/darknet/darknet_io.cpp b/modules/dnn/src/darknet/darknet_io.cpp index e3c978a8c0..4915538ff7 100644 --- a/modules/dnn/src/darknet/darknet_io.cpp +++ b/modules/dnn/src/darknet/darknet_io.cpp @@ -558,6 +558,29 @@ namespace cv { fused_layer_names.push_back(last_layer); } + void setSAM(int from) + { + cv::dnn::LayerParams eltwise_param; + eltwise_param.name = "SAM-name"; + eltwise_param.type = "Eltwise"; + + eltwise_param.set("operation", "prod"); + eltwise_param.set("output_channels_mode", "same"); + + darknet::LayerParameter lp; + std::string layer_name = cv::format("sam_%d", layer_id); + lp.layer_name = layer_name; + lp.layer_type = eltwise_param.type; + lp.layerParams = eltwise_param; + lp.bottom_indexes.push_back(last_layer); + lp.bottom_indexes.push_back(fused_layer_names.at(from)); + last_layer = layer_name; + net->layers.push_back(lp); + + layer_id++; + fused_layer_names.push_back(last_layer); + } + void setUpsample(int scaleFactor) { cv::dnn::LayerParams param; @@ -837,6 +860,14 @@ namespace cv { from = from < 0 ? from + layers_counter : from; setParams.setScaleChannels(from); } + else if (layer_type == "sam") + { + std::string bottom_layer = getParam(layer_params, "from", ""); + CV_Assert(!bottom_layer.empty()); + int from = std::atoi(bottom_layer.c_str()); + from = from < 0 ? from + layers_counter : from; + setParams.setSAM(from); + } else if (layer_type == "upsample") { int scaleFactor = getParam(layer_params, "stride", 1); diff --git a/modules/dnn/test/test_darknet_importer.cpp b/modules/dnn/test/test_darknet_importer.cpp index 00638f83c5..8a633fa566 100644 --- a/modules/dnn/test/test_darknet_importer.cpp +++ b/modules/dnn/test/test_darknet_importer.cpp @@ -770,6 +770,11 @@ TEST_P(Test_Darknet_layers, relu) testDarknetLayer("relu"); } +TEST_P(Test_Darknet_layers, sam) +{ + testDarknetLayer("sam", true); +} + INSTANTIATE_TEST_CASE_P(/**/, Test_Darknet_layers, dnnBackendsAndTargets()); }} // namespace