diff --git a/modules/dnn/src/layers/tile_layer.cpp b/modules/dnn/src/layers/tile_layer.cpp index 1357b9e89e..b78eacf35f 100644 --- a/modules/dnn/src/layers/tile_layer.cpp +++ b/modules/dnn/src/layers/tile_layer.cpp @@ -80,8 +80,10 @@ public: { tmp = tmp.reshape(0, dims); tmp = cv::repeat(tmp, 1, rep_i); - dims *= out_shape[i]; } + // accumulate for every axis so a repeated non-leading axis tiles + // per-axis blocks instead of repeating the whole flattened tensor + dims *= out_shape[i]; } tmp = tmp.reshape(0, out_shape); diff --git a/modules/dnn/src/onnx/onnx_importer.cpp b/modules/dnn/src/onnx/onnx_importer.cpp index 11fde4278a..867f7d7181 100644 --- a/modules/dnn/src/onnx/onnx_importer.cpp +++ b/modules/dnn/src/onnx/onnx_importer.cpp @@ -3132,13 +3132,14 @@ void ONNXImporter::parseTile(LayerParams& layerParams, const opencv_onnx::NodePr // input2 in tile-1: axis, 1d tensor of shape [1] Mat input2_blob = getBlob(node_proto, 2); CV_CheckEQ(input2_blob.total(), 1ull, "ONNX/Tile: axis must be a 0D tensor or 1D tensor of shape [1]."); - int axis = input2_blob.at(0); + int axis = normalize_axis(input2_blob.at(0), input0_dims); repeats_vec[axis] = tiles; } else { // input1 in tile>1: repeats CV_CheckEQ(input1_blob.dims, 2, "ONNX/Tile: repeats must be a 1D tensor."); // 1D tensor is represented as a 2D Mat + CV_CheckEQ((int)input1_blob.total(), input0_dims, "ONNX/Tile: repeats length must match the input rank."); for (int i = 0; i < input1_blob.total(); i++) repeats_vec[i] = input1_blob.at(i); } diff --git a/modules/dnn/test/test_onnx_importer.cpp b/modules/dnn/test/test_onnx_importer.cpp index 86363f37b3..1868cb3708 100644 --- a/modules/dnn/test/test_onnx_importer.cpp +++ b/modules/dnn/test/test_onnx_importer.cpp @@ -3039,6 +3039,9 @@ TEST_P(Test_ONNX_nets, YOLOv5n) TEST_P(Test_ONNX_layers, Tile) { testONNXModels("tile", pb); + // tile-1 (opset 1) form with a negative axis; the parser must normalize it + // against the input rank instead of indexing the repeats buffer directly. + testONNXModels("tile_neg_axis"); } TEST_P(Test_ONNX_layers, Gelu)