@@ -39,7 +39,7 @@ class ONNXImporter
3939 struct LayerInfo {
4040 int layerId;
4141 int outputId;
42- LayerInfo (int _layerId, int _outputId) : layerId(_layerId), outputId(_outputId) {}
42+ LayerInfo (int _layerId = 0 , int _outputId = 0 ) : layerId(_layerId), outputId(_outputId) {}
4343 };
4444
4545 std::map<std::string, Mat> getGraphTensors (
@@ -300,6 +300,15 @@ void ONNXImporter::addLayer(Net& dstNet, LayerParams& layerParams,
300300 }
301301}
302302
303+ static void addConstant (const std::string& name,
304+ const Mat& blob,
305+ std::map<std::string, Mat>& constBlobs,
306+ std::map<std::string, MatShape>& outShapes)
307+ {
308+ constBlobs.insert (std::make_pair (name, blob));
309+ outShapes.insert (std::make_pair (name, shape (blob)));
310+ }
311+
303312void ONNXImporter::populateNet (Net dstNet)
304313{
305314 CV_Assert (model_proto.has_graph ());
@@ -533,6 +542,23 @@ void ONNXImporter::populateNet(Net dstNet)
533542 if (inp_size == 5 ) {
534543 CV_Assert (constBlobs.find (node_proto.input (4 )) != constBlobs.end ());
535544 Mat step_blob = getBlob (node_proto, constBlobs, 4 );
545+
546+ // Very strange application for Slice op with tensor reversing.
547+ // We just workaround it for 2d constants.
548+ if (constBlobs.find (node_proto.input (0 )) != constBlobs.end () &&
549+ axis == 0 &&
550+ start_blob.at <int >(0 ) == -1 && step_blob.at <int >(0 ) == -1 &&
551+ end_blob.at <int >(0 ) == std::numeric_limits<int32_t >::min ())
552+ {
553+ Mat inp = getBlob (node_proto, constBlobs, 0 );
554+ if (inp.dims == 2 )
555+ {
556+ Mat flipped;
557+ flip (inp, flipped, 0 );
558+ addConstant (layerParams.name , flipped, constBlobs, outShapes);
559+ continue ;
560+ }
561+ }
536562 CV_CheckEQ (countNonZero (step_blob != 1 ), 0 , " Slice layer only supports steps = 1" );
537563 }
538564 }
@@ -547,8 +573,7 @@ void ONNXImporter::populateNet(Net dstNet)
547573 inputs.push_back (inp);
548574 runLayer (layerParams, inputs, sliced);
549575 CV_Assert (sliced.size () == 1 );
550- constBlobs.insert (std::make_pair (layerParams.name , sliced[0 ]));
551- outShapes[layerParams.name ] = shape (sliced[0 ]);
576+ addConstant (layerParams.name , sliced[0 ], constBlobs, outShapes);
552577 continue ;
553578 }
554579 }
@@ -585,7 +610,7 @@ void ONNXImporter::populateNet(Net dstNet)
585610 Mat blob_1 = getBlob (node_proto, constBlobs, 1 );
586611 CV_Assert (blob_0.size == blob_1.size );
587612 Mat output = isSub ? (blob_0 - blob_1) : (blob_0 + blob_1);
588- constBlobs. insert ( std::make_pair ( layerParams.name , output) );
613+ addConstant ( layerParams.name , output, constBlobs, outShapes );
589614 continue ;
590615 }
591616 else if (is_const_0 || is_const_1)
@@ -670,7 +695,7 @@ void ONNXImporter::populateNet(Net dstNet)
670695 {
671696 CV_Assert (node_proto.input_size () == 0 );
672697 CV_Assert (layerParams.blobs .size () == 1 );
673- constBlobs. insert ( std::make_pair ( layerParams.name , layerParams.blobs [0 ]) );
698+ addConstant ( layerParams.name , layerParams.blobs [0 ], constBlobs, outShapes );
674699 continue ;
675700 }
676701 else if (layer_type == " LSTM" )
@@ -965,7 +990,7 @@ void ONNXImporter::populateNet(Net dstNet)
965990
966991 out = out.reshape (1 , inp0.dims , inp0.size );
967992 out.dims = inp0.dims ; // to workaround dims == 1
968- constBlobs. insert ( std::make_pair ( layerParams.name , out) );
993+ addConstant ( layerParams.name , out, constBlobs, outShapes );
969994 continue ;
970995 }
971996 }
@@ -1033,7 +1058,7 @@ void ONNXImporter::populateNet(Net dstNet)
10331058 std::vector<Mat> inputs (1 , getBlob (node_proto, constBlobs, 0 )), transposed;
10341059 runLayer (layerParams, inputs, transposed);
10351060 CV_Assert (transposed.size () == 1 );
1036- constBlobs. insert ( std::make_pair ( layerParams.name , transposed[0 ]) );
1061+ addConstant ( layerParams.name , transposed[0 ], constBlobs, outShapes );
10371062 continue ;
10381063 }
10391064 }
@@ -1069,8 +1094,7 @@ void ONNXImporter::populateNet(Net dstNet)
10691094 Mat inp = getBlob (node_proto, constBlobs, 0 );
10701095 Mat out = inp.reshape (1 , outShape);
10711096 out.dims = outShape.size (); // to workaround dims == 1
1072- constBlobs.insert (std::make_pair (layerParams.name , out));
1073- outShapes[layerParams.name ] = shape (out);
1097+ addConstant (layerParams.name , out, constBlobs, outShapes);
10741098 continue ;
10751099 }
10761100 }
@@ -1085,7 +1109,7 @@ void ONNXImporter::populateNet(Net dstNet)
10851109 std::vector<int > out_size (&input.size [0 ], &input.size [0 ] + axis);
10861110 out_size.push_back (input.total (axis));
10871111 Mat output = input.reshape (1 , out_size);
1088- constBlobs. insert ( std::make_pair ( layerParams.name , output) );
1112+ addConstant ( layerParams.name , output, constBlobs, outShapes );
10891113 continue ;
10901114 }
10911115 }
@@ -1108,7 +1132,7 @@ void ONNXImporter::populateNet(Net dstNet)
11081132 }
11091133
11101134 Mat out = input.reshape (0 , dims);
1111- constBlobs. insert ( std::make_pair ( layerParams.name , out) );
1135+ addConstant ( layerParams.name , out, constBlobs, outShapes );
11121136 continue ;
11131137 }
11141138
@@ -1210,7 +1234,7 @@ void ONNXImporter::populateNet(Net dstNet)
12101234 if (layer_id.find (node_proto.input (0 )) == layer_id.end ()) {
12111235 std::vector<Mat> inputs (1 , getBlob (node_proto, constBlobs, 0 )), outputs;
12121236 runLayer (layerParams, inputs, outputs);
1213- constBlobs. insert ( std::make_pair ( layerParams.name , outputs[0 ]) );
1237+ addConstant ( layerParams.name , outputs[0 ], constBlobs, outShapes );
12141238 continue ;
12151239 }
12161240 }
@@ -1224,7 +1248,7 @@ void ONNXImporter::populateNet(Net dstNet)
12241248 if (layer_id.find (node_proto.input (0 )) == layer_id.end ()) {
12251249 Mat input = getBlob (node_proto, constBlobs, 0 );
12261250 Mat out = input.reshape (0 , dim);
1227- constBlobs. insert ( std::make_pair ( layerParams.name , out) );
1251+ addConstant ( layerParams.name , out, constBlobs, outShapes );
12281252 continue ;
12291253 }
12301254 replaceLayerParam (layerParams, " shape" , " dim" );
@@ -1233,6 +1257,17 @@ void ONNXImporter::populateNet(Net dstNet)
12331257 else if (layer_type == " Pad" )
12341258 {
12351259 layerParams.type = " Padding" ;
1260+ if (node_proto.input_size () == 3 )
1261+ {
1262+ // Paddings are in order begin0, begin1, .. beginN, end0, end1, ..., endN.
1263+ // We need to shuffle it to begin0, end0, begin1, end1, ...
1264+ Mat paddings = getBlob (node_proto, constBlobs, 1 ).reshape (1 , 2 );
1265+ paddings = paddings.t ();
1266+ layerParams.set (" paddings" , DictValue::arrayInt (paddings.ptr <int >(), paddings.total ()));
1267+
1268+ Mat value = getBlob (node_proto, constBlobs, 2 );
1269+ layerParams.set (" value" , value.at <float >(0 ));
1270+ }
12361271 }
12371272 else if (layer_type == " Shape" )
12381273 {
@@ -1246,7 +1281,7 @@ void ONNXImporter::populateNet(Net dstNet)
12461281 shapeMat.at <int >(j) = inpShape[j];
12471282 shapeMat.dims = 1 ;
12481283
1249- constBlobs. insert ( std::make_pair ( layerParams.name , shapeMat) );
1284+ addConstant ( layerParams.name , shapeMat, constBlobs, outShapes );
12501285 continue ;
12511286 }
12521287 else if (layer_type == " Cast" )
@@ -1268,29 +1303,32 @@ void ONNXImporter::populateNet(Net dstNet)
12681303 default : type = blob.type ();
12691304 }
12701305 blob.convertTo (blob, type);
1271- constBlobs. insert ( std::make_pair ( layerParams.name , blob) );
1306+ addConstant ( layerParams.name , blob, constBlobs, outShapes );
12721307 continue ;
12731308 }
12741309 else
12751310 layerParams.type = " Identity" ;
12761311 }
12771312 else if (layer_type == " ConstantOfShape" || layer_type == " ConstantFill" )
12781313 {
1314+ int depth = CV_32F;
12791315 float fill_value;
12801316 if (!layerParams.blobs .empty ())
12811317 {
12821318 CV_Assert (!layerParams.has (" value" ));
1283- fill_value = layerParams.blobs [0 ].at <float >(0 , 0 );
1319+ depth = layerParams.blobs [0 ].depth ();
1320+ Mat floats;
1321+ layerParams.blobs [0 ].convertTo (floats, CV_32F);
1322+ fill_value = floats.at <float >(0 , 0 );
12841323 }
12851324 else
12861325 fill_value = layerParams.get (" value" , 0 );
12871326
12881327 MatShape inpShape = getBlob (node_proto, constBlobs, 0 );
12891328 for (int i = 0 ; i < inpShape.size (); i++)
12901329 CV_CheckGT (inpShape[i], 0 , " " );
1291- Mat tensor (inpShape.size (), &inpShape[0 ], CV_32F, Scalar (fill_value));
1292- constBlobs.insert (std::make_pair (layerParams.name , tensor));
1293- outShapes[node_proto.output (0 )] = shape (tensor);
1330+ Mat tensor (inpShape.size (), &inpShape[0 ], depth, Scalar (fill_value));
1331+ addConstant (layerParams.name , tensor, constBlobs, outShapes);
12941332 continue ;
12951333 }
12961334 else if (layer_type == " Gather" )
@@ -1320,7 +1358,7 @@ void ONNXImporter::populateNet(Net dstNet)
13201358 out = input.reshape (1 , 1 ).colRange (index, index + 1 );
13211359 out.dims = dims;
13221360 }
1323- constBlobs. insert ( std::make_pair ( layerParams.name , out) );
1361+ addConstant ( layerParams.name , out, constBlobs, outShapes );
13241362 continue ;
13251363 }
13261364 else if (layer_type == " Concat" )
@@ -1345,7 +1383,7 @@ void ONNXImporter::populateNet(Net dstNet)
13451383 runLayer (layerParams, inputs, concatenated);
13461384
13471385 CV_Assert (concatenated.size () == 1 );
1348- constBlobs. insert ( std::make_pair ( layerParams.name , concatenated[0 ]) );
1386+ addConstant ( layerParams.name , concatenated[0 ], constBlobs, outShapes );
13491387 continue ;
13501388 }
13511389 }
0 commit comments