From 027aee8ad4bdcde076c40ce61e305ff96111b513 Mon Sep 17 00:00:00 2001 From: Dhanwanth1803 <147172285+Dhanwanth1803@users.noreply.github.com> Date: Fri, 22 Dec 2023 17:25:01 +0530 Subject: [PATCH] Merge pull request #24384 from Dhanwanth1803:feat-crop Fixes #22747. Support [crop] configuration for DarkNet #24384 Request for comments. This is my first PR. **Merge with extra**: https://github.com/opencv/opencv_extra/pull/1112 resolves https://github.com/opencv/opencv/issues/22747 - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake --- modules/dnn/src/darknet/darknet_io.cpp | 63 ++++++++++++++++++++-- modules/dnn/test/test_darknet_importer.cpp | 5 ++ 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/modules/dnn/src/darknet/darknet_io.cpp b/modules/dnn/src/darknet/darknet_io.cpp index a8d9ce542b..a3c7b37a73 100644 --- a/modules/dnn/src/darknet/darknet_io.cpp +++ b/modules/dnn/src/darknet/darknet_io.cpp @@ -309,6 +309,48 @@ namespace cv { fused_layer_names.push_back(last_layer); } + void setCrop(int crop_height, int crop_width, int inp_height, int inp_width, bool noadjust) + { + cv::dnn::LayerParams crop_param; + crop_param.name = "CropLayer-name"; + std::vector begin = {0, 0, (inp_height - crop_height) / 2, (inp_width - crop_width) / 2}; + std::vector sizes = {-1, -1, crop_height, crop_width}; + crop_param.set("begin", DictValue::arrayInt(&begin[0], begin.size())); + crop_param.set("size", DictValue::arrayInt(&sizes[0], sizes.size())); + crop_param.type = "Slice"; + + darknet::LayerParameter lp; + std::string layer_name = cv::format("crop_%d", layer_id); + lp.layer_name = layer_name; + lp.layer_type = crop_param.type; + lp.layerParams = crop_param; + lp.bottom_indexes.push_back(last_layer); + last_layer = layer_name; + net->layers.push_back(lp); + layer_id++; + + if (!noadjust) + { + cv::dnn::LayerParams params; + params.set("bias_term", true); + params.blobs = { + Mat(1, 1, CV_32F, Scalar(2)), + Mat(1, 1, CV_32F, Scalar(-1)) + }; + + darknet::LayerParameter lp; + std::string layer_name = cv::format("adjust_crop_%d", layer_id); + lp.layer_name = layer_name; + lp.layer_type = "Scale"; + lp.layerParams = params; + lp.bottom_indexes.push_back(last_layer); + last_layer = layer_name; + net->layers.push_back(lp); + layer_id++; + } + fused_layer_names.push_back(last_layer); + } + void setSoftmax() { cv::dnn::LayerParams softmax_param; @@ -685,8 +727,8 @@ namespace cv { MatShape tensor_shape(3); tensor_shape[0] = net->channels; - tensor_shape[1] = net->width; - tensor_shape[2] = net->height; + tensor_shape[1] = net->height; + tensor_shape[2] = net->width; net->out_channels_vec.resize(net->layers_cfg.size()); layers_counter = -1; @@ -763,6 +805,19 @@ namespace cv { tensor_shape[1] = 1; tensor_shape[2] = 1; } + else if (layer_type == "crop") + { + int crop_height = getParam(layer_params, "crop_height", 0); + int crop_width = getParam(layer_params, "crop_width", 0); + bool noadjust = getParam(layer_params, "noadjust", false); + CV_CheckGT(crop_height, 0, ""); + CV_CheckGT(crop_width, 0, ""); + + setParams.setCrop(crop_height, crop_width, tensor_shape[1], tensor_shape[2], noadjust); + + tensor_shape[1] = crop_height; + tensor_shape[2] = crop_width; + } else if (layer_type == "softmax") { int groups = getParam(layer_params, "groups", 1); @@ -937,8 +992,8 @@ namespace cv { MatShape tensor_shape(3); tensor_shape[0] = net->channels; - tensor_shape[1] = net->width; - tensor_shape[2] = net->height; + tensor_shape[1] = net->height; + tensor_shape[2] = net->width; int cv_layers_counter = -1; int darknet_layers_counter = -1; diff --git a/modules/dnn/test/test_darknet_importer.cpp b/modules/dnn/test/test_darknet_importer.cpp index 24f1056bb8..40c07977f8 100644 --- a/modules/dnn/test/test_darknet_importer.cpp +++ b/modules/dnn/test/test_darknet_importer.cpp @@ -1049,6 +1049,11 @@ TEST_P(Test_Darknet_layers, avgpool_softmax) testDarknetLayer("avgpool_softmax"); } +TEST_P(Test_Darknet_layers, crop) +{ + testDarknetLayer("crop"); +} + TEST_P(Test_Darknet_layers, region) { #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)