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)