Repository: opencv
Issue: ONNX: Scalar values initialise with dimensions cause extra false dimensions
Labels: bug,category: dnn,category: dnn (onnx)

### System Information

OpenCV version: 4.7.0
Operating System / Platform: Ubuntu 20.04
Compiler & compiler version: GCC 7.5.0
Python version: 3.8

### Detailed description

OpenCV initialises **scalar** constants with dimension [1]. NN layer create extra dimensions when processing this **scalar** constant with dimensions one. And that lead to bug/assertions in layer proceeding layers in the NN. Here is a particular bug caused by it


```console
Node [Concat@ai.onnx]:(onnx_node!/transform/Concat_1) parse error: OpenCV(4.7.0-dev) opencv/modules/dnn/src/layers/concat_layer.cpp:110: error: (-215:Assertion failed) curShape.size() == outputs[0].size() in function 'getMemoryShapes'
```

See ONNX graph below. Highlighted area below does not contain any shapes since all of them are just scalar values. Pay attention that only after `unsqueeze` do shape start appearing. This how shapes should appear in OpenCV `onnx_importer` class. However, OpenCV assignees shapes to node right from the beginning `ReduceMax`, `ReduceMin` node(see log below). And and later on in the graph these diminution start increasing and do not match those in ONNX graph and cause bugs



<img width="724" alt="Screenshot 2023-05-31 at 20 48 03" src="https://github.com/opencv/opencv/assets/44877829/585876b9-7a2f-41a4-b275-b954a4db0deb">



```console 
DEBUG:0@11.765] global system.cpp:2842 setFPDenormalsIgnoreHint core: update FP mxcsr flags = 0x00009fe3
[DEBUG:0@11.765] global onnx_importer.cpp:269 ONNXImporter DNN/ONNX: processing ONNX model from file: models/resnet50_fpn.onnx
[ INFO:0@11.858] global onnx_importer.cpp:835 populateNet DNN/ONNX: loading ONNX v6 model produced by 'pytorch':2.0.0. Number of nodes = 2187, initializers = 189, inputs = 2, outputs = 6
[ INFO:0@11.858] global onnx_importer.cpp:728 parseOperatorSet DNN/ONNX: ONNX opset version = 11
[DEBUG:0@12.103] global onnx_importer.cpp:842 populateNet DNN/ONNX: graph simplified to 2184 nodes
[DEBUG:0@12.119] global onnx_importer.cpp:882 populateNet DNN/ONNX: input[0 as 'input_0'] shape=[ 3 608 608 ]
[DEBUG:0@12.119] global onnx_importer.cpp:882 populateNet DNN/ONNX: input[1 as 'input_1'] shape=[ 3 608 608 ]
[DEBUG:0@12.120] global onnx_importer.cpp:340 dumpValueInfoProto DNN/ONNX: output[0] dim[0] = <Concatoutput_dim_0> (dynamic)
[DEBUG:0@12.120] global onnx_importer.cpp:349 dumpValueInfoProto DNN/ONNX: output[0 as 'output'] shape=[ 0 4 ]
[DEBUG:0@12.120] global onnx_importer.cpp:340 dumpValueInfoProto DNN/ONNX: output[1] dim[0] = <Gather3295_dim_0> (dynamic)
[DEBUG:0@12.120] global onnx_importer.cpp:349 dumpValueInfoProto DNN/ONNX: output[1 as '3295'] shape=[ 0 ]
[DEBUG:0@12.120] global onnx_importer.cpp:340 dumpValueInfoProto DNN/ONNX: output[2] dim[0] = <Gather3295_dim_0> (dynamic)
[DEBUG:0@12.120] global onnx_importer.cpp:349 dumpValueInfoProto DNN/ONNX: output[2 as '3294'] shape=[ 0 ]
[DEBUG:0@12.120] global onnx_importer.cpp:340 dumpValueInfoProto DNN/ONNX: output[3] dim[0] = <Concat3462_dim_0> (dynamic)
[DEBUG:0@12.120] global onnx_importer.cpp:349 dumpValueInfoProto DNN/ONNX: output[3 as '3462'] shape=[ 0 4 ]
[DEBUG:0@12.120] global onnx_importer.cpp:340 dumpValueInfoProto DNN/ONNX: output[4] dim[0] = <Gather3420_dim_0> (dynamic)
[DEBUG:0@12.120] global onnx_importer.cpp:349 dumpValueInfoProto DNN/ONNX: output[4 as '3420'] shape=[ 0 ]
[DEBUG:0@12.120] global onnx_importer.cpp:340 dumpValueInfoProto DNN/ONNX: output[5] dim[0] = <Gather3420_dim_0> (dynamic)
[DEBUG:0@12.120] global onnx_importer.cpp:349 dumpValueInfoProto DNN/ONNX: output[5 as '3419'] shape=[ 0 ]
[ INFO:0@12.120] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 0 inputs and 1 outputs: [Constant]:(onnx_node!/Constant) from domain='ai.onnx'
[DEBUG:0@12.120] global onnx_importer.cpp:692 addConstant DNN/ONNX: add constant '/Constant_output_0' shape=[ 1 ]: [1]
[ INFO:0@12.120] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 0 inputs and 1 outputs: [Constant]:(onnx_node!/Constant_1) from domain='ai.onnx'
[DEBUG:0@12.120] global onnx_importer.cpp:692 addConstant DNN/ONNX: add constant '/Constant_1_output_0' shape=[ 1 ]: [2]
[ INFO:0@12.120] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 0 inputs and 1 outputs: [Constant]:(onnx_node!/transform/Constant) from domain='ai.onnx'
[DEBUG:0@12.120] global onnx_importer.cpp:692 addConstant DNN/ONNX: add constant '/transform/Constant_output_0' shape=[ 3 1 1 ]: [0.48500001, 0.456, 0.40599999]
[ INFO:0@12.120] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 2 inputs and 1 outputs: [Sub]:(onnx_node!/transform/Sub) from domain='ai.onnx'
[ INFO:0@12.120] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 0 inputs and 1 outputs: [Constant]:(onnx_node!/transform/Constant_1) from domain='ai.onnx'
[DEBUG:0@12.120] global onnx_importer.cpp:692 addConstant DNN/ONNX: add constant '/transform/Constant_1_output_0' shape=[ 3 1 1 ]: [0.229, 0.22400001, 0.22499999]
[ INFO:0@12.120] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 2 inputs and 1 outputs: [Div]:(onnx_node!/transform/Div) from domain='ai.onnx'
[ INFO:0@12.120] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 0 inputs and 1 outputs: [Constant]:(onnx_node!/transform/Constant_2) from domain='ai.onnx'
[DEBUG:0@12.120] global onnx_importer.cpp:692 addConstant DNN/ONNX: add constant '/transform/Constant_2_output_0' shape=[ 1 ]: [0]
[ INFO:0@12.120] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 0 inputs and 1 outputs: [Constant]:(onnx_node!/transform/Constant_3) from domain='ai.onnx'
[DEBUG:0@12.120] global onnx_importer.cpp:692 addConstant DNN/ONNX: add constant '/transform/Constant_3_output_0' shape=[ 2 1 ]: [608, 608]
[ INFO:0@12.120] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 1 inputs and 1 outputs: [ReduceMin]:(onnx_node!/transform/ReduceMin) from domain='ai.onnx'
[ INFO:0@12.120] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 1 inputs and 1 outputs: [Cast]:(onnx_node!/transform/Cast) from domain='ai.onnx'
[ INFO:0@12.121] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 1 inputs and 1 outputs: [ReduceMax]:(onnx_node!/transform/ReduceMax) from domain='ai.onnx'
[ INFO:0@12.121] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 1 inputs and 1 outputs: [Cast]:(onnx_node!/transform/Cast_1) from domain='ai.onnx'
[ INFO:0@12.121] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 1 inputs and 1 outputs: [Reciprocal]:(onnx_node!/transform/Reciprocal) from domain='ai.onnx'
[ INFO:0@12.121] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 0 inputs and 1 outputs: [Constant]:(onnx_node!/transform/Constant_4) from domain='ai.onnx'
[DEBUG:0@12.121] global onnx_importer.cpp:692 addConstant DNN/ONNX: add constant '/transform/Constant_4_output_0' shape=[ 1 ]: [800]
[ INFO:0@12.121] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 2 inputs and 1 outputs: [Mul]:(onnx_node!/transform/Mul) from domain='ai.onnx'
[ INFO:0@12.121] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 1 inputs and 1 outputs: [Reciprocal]:(onnx_node!/transform/Reciprocal_1) from domain='ai.onnx'
[ INFO:0@12.121] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 0 inputs and 1 outputs: [Constant]:(onnx_node!/transform/Constant_5) from domain='ai.onnx'
[DEBUG:0@12.121] global onnx_importer.cpp:692 addConstant DNN/ONNX: add constant '/transform/Constant_5_output_0' shape=[ 1 ]: [1333]
[ INFO:0@12.121] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 2 inputs and 1 outputs: [Mul]:(onnx_node!/transform/Mul_1) from domain='ai.onnx'
[ INFO:0@12.121] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 2 inputs and 1 outputs: [Min]:(onnx_node!/transform/Min) from domain='ai.onnx'
[ INFO:0@12.121] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 1 inputs and 1 outputs: [Unsqueeze]:(onnx_node!/transform/Unsqueeze) from domain='ai.onnx'
[ INFO:0@12.121] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 1 inputs and 1 outputs: [Cast]:(onnx_node!/transform/Cast_2) from domain='ai.onnx'
[ INFO:0@12.121] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 0 inputs and 1 outputs: [Constant]:(onnx_node!/transform/Constant_6) from domain='ai.onnx'
[DEBUG:0@12.121] global onnx_importer.cpp:692 addConstant DNN/ONNX: add constant '/transform/Constant_6_output_0' shape=[ 1 ]: [608]
[ INFO:0@12.121] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 2 inputs and 1 outputs: [Mul]:(onnx_node!/transform/Mul_2) from domain='ai.onnx'
[ INFO:0@12.121] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 1 inputs and 1 outputs: [Cast]:(onnx_node!/transform/Cast_3) from domain='ai.onnx'
[ INFO:0@12.121] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 1 inputs and 1 outputs: [Floor]:(onnx_node!/transform/Floor) from domain='ai.onnx'
[ INFO:0@12.122] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 0 inputs and 1 outputs: [Constant]:(onnx_node!/transform/Constant_7) from domain='ai.onnx'
[DEBUG:0@12.122] global onnx_importer.cpp:692 addConstant DNN/ONNX: add constant '/transform/Constant_7_output_0' shape=[ 1 ]: [3]
[ INFO:0@12.122] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 0 inputs and 1 outputs: [Constant]:(onnx_node!/transform/Constant_8) from domain='ai.onnx'
[DEBUG:0@12.122] global onnx_importer.cpp:692 addConstant DNN/ONNX: add constant '/transform/Constant_8_output_0' shape=[ 1 ]: [608]
[ INFO:0@12.122] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 2 inputs and 1 outputs: [Mul]:(onnx_node!/transform/Mul_3) from domain='ai.onnx'
[ INFO:0@12.122] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 1 inputs and 1 outputs: [Cast]:(onnx_node!/transform/Cast_4) from domain='ai.onnx'
[ INFO:0@12.122] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 1 inputs and 1 outputs: [Floor]:(onnx_node!/transform/Floor_1) from domain='ai.onnx'
[ INFO:0@12.122] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 1 inputs and 1 outputs: [Unsqueeze]:(onnx_node!/transform/Unsqueeze_1) from domain='ai.onnx'
[ INFO:0@12.122] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 1 inputs and 1 outputs: [Unsqueeze]:(onnx_node!/transform/Unsqueeze_2) from domain='ai.onnx'
[ INFO:0@12.122] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 2 inputs and 1 outputs: [Concat]:(onnx_node!/transform/Concat) from domain='ai.onnx'
[ INFO:0@12.122] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 1 inputs and 1 outputs: [Shape]:(onnx_node!/transform/Shape) from domain='ai.onnx'
[DEBUG:0@12.122] global onnx_importer.cpp:692 addConstant DNN/ONNX: add constant '/transform/Shape_output_0' shape=[ 4 ]: [1, 3, 608, 608]
[ INFO:0@12.122] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 0 inputs and 1 outputs: [Constant]:(onnx_node!/transform/Constant_9) from domain='ai.onnx'
[DEBUG:0@12.122] global onnx_importer.cpp:692 addConstant DNN/ONNX: add constant '/transform/Constant_9_output_0' shape=[ 1 1 ]: [0]
[ INFO:0@12.122] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 0 inputs and 1 outputs: [Constant]:(onnx_node!/transform/Constant_10) from domain='ai.onnx'
[DEBUG:0@12.122] global onnx_importer.cpp:692 addConstant DNN/ONNX: add constant '/transform/Constant_10_output_0' shape=[ 1 1 ]: [0]
[ INFO:0@12.122] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 0 inputs and 1 outputs: [Constant]:(onnx_node!/transform/Constant_11) from domain='ai.onnx'
[DEBUG:0@12.122] global onnx_importer.cpp:692 addConstant DNN/ONNX: add constant '/transform/Constant_11_output_0' shape=[ 1 1 ]: [2]
[ INFO:0@12.122] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 4 inputs and 1 outputs: [Slice]:(onnx_node!/transform/Slice) from domain='ai.onnx'
[DEBUG:0@12.123] global onnx_importer.cpp:692 addConstant DNN/ONNX: add constant '/transform/Slice_output_0' shape=[ 2 1 ]: [1, 3]
[ INFO:0@12.123] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 1 inputs and 1 outputs: [Cast]:(onnx_node!/transform/Cast_5) from domain='ai.onnx'
[ INFO:0@12.123] global onnx_importer.cpp:1006 handleNode DNN/ONNX: processing node with 2 inputs and 1 outputs: [Concat]:(onnx_node!/transform/Concat_1) from domain='ai.onnx'
OpenCV(4.7.0-dev) Error: Assertion failed (curShape.size() == outputs[0].size()) in getMemoryShapes, file /home/abduragim/projects/opencv_proj/opencv/modules/dnn/src/layers/concat_layer.cpp, line 110
[ERROR:0@12.123] global onnx_importer.cpp:1064 handleNode DNN/ONNX: ERROR during processing node with 2 inputs and 1 outputs: [Concat]:(onnx_node!/transform/Concat_1) from domain='ai.onnx'
[ INFO:0@12.123] global onnx_importer.cpp:1068 handleNode     Input[0] = '/transform/Slice_output_0'
[ INFO:0@12.123] global onnx_importer.cpp:1068 handleNode     Input[1] = '/transform/Cast_5_output_0'
[ INFO:0@12.123] global onnx_importer.cpp:1072 handleNode     Output[0] = '/transform/Concat_1_output_0'
OpenCV(4.7.0-dev) Error: Unspecified error (> Node [Concat@ai.onnx]:(onnx_node!/transform/Concat_1) parse error: OpenCV(4.7.0-dev) opencv/modules/dnn/src/layers/concat_layer.cpp:110: error: (-215:Assertion failed) curShape.size() == outputs[0].size() in function 'getMemoryShapes'
```

### Steps to reproduce

```python
     import os
     import cv2
     import onnx
     import torch
     import onnxruntime as ort
     import torchvision.models as models
     from onnx import shape_inference


    original_model = models.detection.fasterrcnn_resnet50_fpn(pretrained=True).eval()

    # define the directory for further converted model save
    onnx_model_path = "models"

    # define the name of further converted model
    onnx_model_name = "resnet50_fpn.onnx"

    # create directory for further converted model
    os.makedirs(onnx_model_path, exist_ok=True)

    # get full path to the converted model
    full_model_path = os.path.join(onnx_model_path, onnx_model_name)

    # generate model input to build the graph
    generated_input = [
        torch.randn(3, 608, 608),
        torch.randn(3, 608, 608),
    ]

    print("\t\t ---> FORWARDING TORCH MODEL <---")
    with torch.no_grad():
        output_torch = original_model(generated_input)


    print("\t\t ---> EXPORTING <---")
    # model export into ONNX format
    torch.onnx.export(
        original_model,
        generated_input,
        full_model_path,
        verbose=False,
        # input_names=["input"],
        input_names=[f"input_{i}" for i,j in enumerate(generated_input)],
        output_names=["output"],
        opset_version=11
    )

    print("\t\t ---> READING ONNX FILE IN ONNX <---")
    onnx_model = onnx.load(full_model_path)
    onnx.checker.check_model(onnx_model)

    print("\t\t ---> PARSE TO SHAPES <---")
    onnx_model = shape_inference.infer_shapes(onnx_model)
    onnx.save(onnx_model, full_model_path)

    print("\t\t ---> READING ONNX in OPENCV FILE <---")
    opencv_net = cv2.dnn.readNetFromONNX(full_model_path)
```





### Issue submission checklist

- [X] I report the issue, it's not a question
- [X] I checked the problem with documentation, FAQ, open issues, forum.opencv.org, Stack Overflow, etc and have not found any solution
- [X] I updated to the latest OpenCV version and the issue is still there
- [X] There is reproducer code and related data files (videos, images, onnx, etc)