Skip to content

Commit 107582c

Browse files
committed
Merge pull request opencv#9996 from dkurt:dnn_multiple_inputs
2 parents 5d369af + 20a2dc6 commit 107582c

File tree

4 files changed

+97
-4
lines changed

4 files changed

+97
-4
lines changed

modules/dnn/src/caffe/caffe_importer.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,12 @@ class CaffeImporter : public Importer
327327

328328
if (type == "Input")
329329
{
330-
addedBlobs.push_back(BlobNote(name, 0, netInputs.size()));
331-
netInputs.push_back(name);
330+
for (int outNum = 0; outNum < layer.top_size(); outNum++)
331+
{
332+
addOutput(layer, 0, outNum);
333+
addedBlobs.back().outNum = netInputs.size();
334+
netInputs.push_back(addedBlobs.back().name);
335+
}
332336
continue;
333337
}
334338

modules/dnn/src/dnn.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,16 @@ struct DataLayer : public Layer
279279
outNames.assign(names.begin(), names.end());
280280
}
281281

282+
bool getMemoryShapes(const std::vector<MatShape> &inputs,
283+
const int requiredOutputs,
284+
std::vector<MatShape> &outputs,
285+
std::vector<MatShape> &internals) const
286+
{
287+
CV_Assert(inputs.size() == requiredOutputs);
288+
outputs.assign(inputs.begin(), inputs.end());
289+
return false;
290+
}
291+
282292
private:
283293
std::vector<String> outNames;
284294
};
@@ -1385,7 +1395,7 @@ struct Net::Impl
13851395
layers[ld.inputBlobsId[i].lid].getLayerInstance()->name.c_str(),
13861396
inp_i_data->getLayerInstance()->name.c_str()));
13871397

1388-
if(inp_i_data->skipFlags[DNN_BACKEND_DEFAULT])
1398+
if(inp_i_data->skipFlags[DNN_BACKEND_DEFAULT] || inp_i_data->consumers.size() != 1)
13891399
break;
13901400
realinputs[i] = pin;
13911401
}
@@ -1407,6 +1417,14 @@ struct Net::Impl
14071417
Mat& curr_output = inp_i_data->outputBlobs[pin.oid];
14081418
CV_Assert(output_slice.isContinuous() && output_slice.size == curr_output.size);
14091419
curr_output = output_slice;
1420+
1421+
pin = ld.inputBlobsId[i];
1422+
inp_i_data = &layers[pin.lid];
1423+
for (int j = 0; j < inp_i_data->consumers.size(); ++j)
1424+
{
1425+
LayerPin consumer = inp_i_data->consumers[j];
1426+
layers[consumer.lid].inputBlobs[consumer.oid] = &curr_output;
1427+
}
14101428
}
14111429
ld.skipFlags[DNN_BACKEND_DEFAULT] = true;
14121430
printf_(("\toptimized out Concat layer %s\n", concatLayer->name.c_str()));
@@ -1438,7 +1456,9 @@ struct Net::Impl
14381456
blobManager.setPreferableTarget(preferableTarget);
14391457
blobManager.setPreferableBackend(preferableBackend);
14401458
backendWrappers.clear();
1441-
blobManager.addReference(LayerPin(0, 0));
1459+
// Fake references to input blobs.
1460+
for (int i = 0; i < layers[0].outputBlobs.size(); ++i)
1461+
blobManager.addReference(LayerPin(0, i));
14421462
for (it = layers.begin(); it != layers.end(); ++it)
14431463
{
14441464
const LayerData& ld = it->second;

modules/dnn/test/test_caffe_importer.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,4 +313,31 @@ TEST(Reproducibility_DenseNet_121, Accuracy)
313313
normAssert(out, ref);
314314
}
315315

316+
TEST(Test_Caffe, multiple_inputs)
317+
{
318+
const string proto = findDataFile("dnn/layers/net_input.prototxt", false);
319+
Net net = readNetFromCaffe(proto);
320+
321+
Mat first_image(10, 11, CV_32FC3);
322+
Mat second_image(10, 11, CV_32FC3);
323+
randu(first_image, -1, 1);
324+
randu(second_image, -1, 1);
325+
326+
first_image = blobFromImage(first_image);
327+
second_image = blobFromImage(second_image);
328+
329+
Mat first_image_blue_green = slice(first_image, Range::all(), Range(0, 2), Range::all(), Range::all());
330+
Mat first_image_red = slice(first_image, Range::all(), Range(2, 3), Range::all(), Range::all());
331+
Mat second_image_blue_green = slice(second_image, Range::all(), Range(0, 2), Range::all(), Range::all());
332+
Mat second_image_red = slice(second_image, Range::all(), Range(2, 3), Range::all(), Range::all());
333+
334+
net.setInput(first_image_blue_green, "old_style_input_blue_green");
335+
net.setInput(first_image_red, "different_name_for_red");
336+
net.setInput(second_image_blue_green, "input_layer_blue_green");
337+
net.setInput(second_image_red, "old_style_input_red");
338+
Mat out = net.forward();
339+
340+
normAssert(out, first_image + second_image);
341+
}
342+
316343
}

modules/dnn/test/test_layers.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,48 @@ OCL_TEST(Layer_Test_Concat, Accuracy)
274274
testLayerUsingCaffeModels("layer_concat", DNN_TARGET_OPENCL);
275275
}
276276

277+
TEST(Layer_Test_Fused_Concat, Accuracy)
278+
{
279+
// Test case
280+
// input
281+
// |
282+
// v
283+
// some_layer
284+
// | |
285+
// v v
286+
// concat
287+
Net net;
288+
int interLayer;
289+
{
290+
LayerParams lp;
291+
lp.type = "AbsVal";
292+
lp.name = "someLayer";
293+
interLayer = net.addLayerToPrev(lp.name, lp.type, lp);
294+
}
295+
{
296+
LayerParams lp;
297+
lp.set("axis", 1);
298+
lp.type = "Concat";
299+
lp.name = "testConcat";
300+
int id = net.addLayer(lp.name, lp.type, lp);
301+
net.connect(interLayer, 0, id, 0);
302+
net.connect(interLayer, 0, id, 1);
303+
}
304+
int shape[] = {1, 2, 3, 4};
305+
Mat input(4, shape, CV_32F);
306+
randu(input, 0.0f, 1.0f); // [0, 1] to make AbsVal an identity transformation.
307+
308+
net.setInput(input);
309+
Mat out = net.forward();
310+
311+
normAssert(slice(out, Range::all(), Range(0, 2), Range::all(), Range::all()), input);
312+
normAssert(slice(out, Range::all(), Range(2, 4), Range::all(), Range::all()), input);
313+
314+
//
315+
316+
testLayerUsingCaffeModels("layer_concat_optim", DNN_TARGET_CPU, true, false);
317+
}
318+
277319
TEST(Layer_Test_Eltwise, Accuracy)
278320
{
279321
testLayerUsingCaffeModels("layer_eltwise");

0 commit comments

Comments
 (0)