Skip to content

Commit 633740d

Browse files
revert mask_rcnn_demo
1 parent d321d0b commit 633740d

File tree

2 files changed

+129
-120
lines changed

2 files changed

+129
-120
lines changed

demos/mask_rcnn_demo/cpp/main.cpp

Lines changed: 126 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (C) 2018-2022 Intel Corporation
1+
// Copyright (C) 2018-2019 Intel Corporation
22
// SPDX-License-Identifier: Apache-2.0
33
//
44

@@ -7,28 +7,26 @@
77
* @file mask_rcnn_demo/main.cpp
88
* @example mask_rcnn_demo/main.cpp
99
*/
10-
#include <algorithm>
11-
#include <iomanip>
10+
#include <gflags/gflags.h>
1211
#include <iostream>
1312
#include <memory>
1413
#include <map>
14+
#include <algorithm>
1515
#include <string>
1616
#include <vector>
17+
#include <iomanip>
1718

18-
#include "openvino/openvino.hpp"
19+
#include <inference_engine.hpp>
1920

20-
#include "gflags/gflags.h"
21-
#include "utils/args_helper.hpp"
22-
#include "utils/ocv_common.hpp"
23-
#include "utils/performance_metrics.hpp"
24-
#include "utils/slog.hpp"
21+
#include <utils/args_helper.hpp>
22+
#include <utils/ocv_common.hpp>
23+
#include <utils/performance_metrics.hpp>
24+
#include <utils/slog.hpp>
2525

2626
#include "mask_rcnn_demo.h"
2727

28-
using namespace ov::preprocess;
29-
30-
bool ParseAndCheckCommandLine(int argc, char* argv[]) {
31-
// Parsing and validation of input args
28+
bool ParseAndCheckCommandLine(int argc, char *argv[]) {
29+
// ---------------------------Parsing and validation of input args--------------------------------------
3230
gflags::ParseCommandLineNonHelpFlags(&argc, &argv, true);
3331
if (FLAGS_h) {
3432
showUsage();
@@ -47,77 +45,84 @@ bool ParseAndCheckCommandLine(int argc, char* argv[]) {
4745
return true;
4846
}
4947

50-
int main(int argc, char* argv[]) {
48+
int main(int argc, char *argv[]) {
5149
try {
5250
PerformanceMetrics metrics;
5351

54-
// Parsing and validation of input args
52+
// ------------------------------ Parsing and validation of input args ---------------------------------
5553
if (!ParseAndCheckCommandLine(argc, argv)) {
5654
return 0;
5755
}
5856

59-
// This vector stores paths to the processed images
57+
/** This vector stores paths to the processed images **/
6058
std::vector<std::string> imagePaths;
6159
parseInputFilesArguments(imagePaths);
62-
if (imagePaths.empty())
63-
throw std::logic_error("No suitable images were found");
60+
if (imagePaths.empty()) throw std::logic_error("No suitable images were found");
61+
// -----------------------------------------------------------------------------------------------------
62+
63+
// ---------------------Load inference engine------------------------------------------------
64+
slog::info << *InferenceEngine::GetInferenceEngineVersion() << slog::endl;
65+
InferenceEngine::Core ie;
6466

65-
// Load inference engine
66-
slog::info << ov::get_openvino_version() << slog::endl;
67-
ov::Core core;
67+
if (!FLAGS_l.empty()) {
68+
// CPU(MKLDNN) extensions are loaded as a shared library and passed as a pointer to base extension
69+
auto extension_ptr = std::make_shared<InferenceEngine::Extension>(FLAGS_l);
70+
ie.AddExtension(extension_ptr, "CPU");
71+
}
72+
if (!FLAGS_c.empty()) {
73+
// clDNN Extensions are loaded from an .xml description and OpenCL kernel files
74+
ie.SetConfig({{InferenceEngine::PluginConfigParams::KEY_CONFIG_FILE, FLAGS_c}}, "CPU");
75+
}
6876

69-
// Load network (Generated xml/bin files)
77+
// -----------------------------------------------------------------------------------------------------
7078

71-
// Read network model
72-
slog::info << "Reading model: " << FLAGS_m << slog::endl;
73-
std::shared_ptr<ov::Model> model = core.read_model(FLAGS_m);
74-
logBasicModelInfo(model);
79+
// --------------------Load network (Generated xml/bin files)-------------------------------------------
7580

76-
// Prepare input blobs
81+
/** Read network model **/
82+
auto network = ie.ReadNetwork(FLAGS_m);
7783

78-
// Taking information about all topology inputs
79-
ov::OutputVector inputs = model->inputs();
80-
ov::OutputVector outputs = model->outputs();
84+
// add DetectionOutput layer as output so we can get detected boxes and their probabilities
85+
network.addOutput(FLAGS_detection_output_name.c_str(), 0);
86+
// -----------------------------------------------------------------------------------------------------
8187

82-
if(inputs.size() != 2 || outputs.size() != 2)
83-
throw std::logic_error("Expected network with 2 inputs and 2 outputs");
88+
// -----------------------------Prepare input blobs-----------------------------------------------------
8489

85-
size_t modelBatchSize = 0;
86-
size_t modelInputHeight = 0;
87-
size_t modelInputWidth = 0;
90+
/** Taking information about all topology inputs **/
91+
InferenceEngine::InputsDataMap inputInfo(network.getInputsInfo());
8892

89-
const ov::Layout layout_nchw{ "NCHW" };
93+
std::string imageInputName;
9094

91-
// network dimensions for image input
92-
auto it = std::find_if(inputs.begin(), inputs.end(), [](const ov::Output<ov::Node>& input) {return input.get_shape().size() == 4;});
93-
if (it != inputs.end()) {
94-
// ov::set_batch() should know input layout
95-
model->get_parameters()[it->get_index()]->set_layout("NCHW");
96-
modelBatchSize = it->get_shape()[ov::layout::batch_idx(layout_nchw)];
97-
modelInputHeight = it->get_shape()[ov::layout::height_idx(layout_nchw)];
98-
modelInputWidth = it->get_shape()[ov::layout::width_idx(layout_nchw)];
99-
} else {
100-
throw std::logic_error("Couldn't find model image input");
95+
for (const auto & inputInfoItem : inputInfo) {
96+
if (inputInfoItem.second->getTensorDesc().getDims().size() == 4) { // first input contains images
97+
imageInputName = inputInfoItem.first;
98+
inputInfoItem.second->setPrecision(InferenceEngine::Precision::U8);
99+
} else if (inputInfoItem.second->getTensorDesc().getDims().size() == 2) { // second input contains image info
100+
inputInfoItem.second->setPrecision(InferenceEngine::Precision::FP32);
101+
} else {
102+
throw std::logic_error("Unsupported input shape with size = " + std::to_string(inputInfoItem.second->getTensorDesc().getDims().size()));
103+
}
101104
}
102105

103-
// Collect images
106+
/** network dimensions for image input **/
107+
const InferenceEngine::TensorDesc& inputDesc = inputInfo[imageInputName]->getTensorDesc();
108+
IE_ASSERT(inputDesc.getDims().size() == 4);
109+
size_t netBatchSize = getTensorBatch(inputDesc);
110+
size_t netInputHeight = getTensorHeight(inputDesc);
111+
size_t netInputWidth = getTensorWidth(inputDesc);
112+
113+
/** Collect images **/
104114
std::vector<cv::Mat> images;
105115

106-
if (modelBatchSize > imagePaths.size()) {
107-
slog::warn << "Model batch size is greater than number of images (" << imagePaths.size() <<
116+
if (netBatchSize > imagePaths.size()) {
117+
slog::warn << "Network batch size is greater than number of images (" << imagePaths.size() <<
108118
"), some input files will be duplicated" << slog::endl;
109-
} else if (modelBatchSize < imagePaths.size()) {
110-
modelBatchSize = imagePaths.size();
111-
slog::warn << "Model batch size is less than number of images (" << imagePaths.size() <<
112-
"), model will be reshaped" << slog::endl;
119+
} else if (netBatchSize < imagePaths.size()) {
120+
slog::warn << "Network batch size is less than number of images (" << imagePaths.size() <<
121+
"), some input files will be ignored" << slog::endl;
113122
}
114123

115-
// set batch size
116-
ov::set_batch(model, modelBatchSize);
117-
slog::info << "\tBatch size is set to " << modelBatchSize << slog::endl;
118-
119124
auto startTime = std::chrono::steady_clock::now();
120-
for (size_t i = 0, inputIndex = 0; i < modelBatchSize; i++, inputIndex++) {
125+
for (size_t i = 0, inputIndex = 0; i < netBatchSize; i++, inputIndex++) {
121126
if (inputIndex >= imagePaths.size()) {
122127
inputIndex = 0;
123128
}
@@ -131,70 +136,82 @@ int main(int argc, char* argv[]) {
131136

132137
images.push_back(image);
133138
}
134-
if (images.empty())
135-
throw std::logic_error("Valid input images were not found!");
139+
if (images.empty()) throw std::logic_error("Valid input images were not found!");
140+
141+
// -----------------------------------------------------------------------------------------------------
142+
143+
// ---------------------------Prepare output blobs------------------------------------------------------
144+
InferenceEngine::OutputsDataMap outputInfo(network.getOutputsInfo());
145+
for (auto & item : outputInfo) {
146+
item.second->setPrecision(InferenceEngine::Precision::FP32);
147+
}
148+
149+
// -----------------------------------------------------------------------------------------------------
136150

137-
// Load model to the device
138-
ov::CompiledModel compiled_model = core.compile_model(model, FLAGS_d);
139-
logCompiledModelInfo(compiled_model, FLAGS_m, FLAGS_d);
151+
// -------------------------Load model to the device----------------------------------------------------
152+
auto executableNetwork = ie.LoadNetwork(network, FLAGS_d);
153+
logExecNetworkInfo(executableNetwork, FLAGS_m, FLAGS_d);
154+
slog::info << "\tBatch size is set to " << netBatchSize << slog::endl;
140155

141-
// Create Infer Request
142-
ov::InferRequest infer_request = compiled_model.create_infer_request();
156+
// -------------------------Create Infer Request--------------------------------------------------------
157+
auto infer_request = executableNetwork.CreateInferRequest();
143158

144-
// Set input data
145-
// Iterate over all the input blobs
146-
for (size_t idx = 0; idx < inputs.size(); idx++) {
147-
ov::Tensor tensor = infer_request.get_input_tensor(idx);
148-
ov::Shape shape = tensor.get_shape();
159+
// -----------------------------------------------------------------------------------------------------
149160

150-
if (shape.size() == 4) {
161+
// -------------------------------Set input data--------------------------------------------------------
162+
/** Iterate over all the input blobs **/
163+
for (const auto & inputInfoItem : inputInfo) {
164+
InferenceEngine::Blob::Ptr input = infer_request.GetBlob(inputInfoItem.first);
165+
166+
/** Fill first input tensor with images. First b channel, then g and r channels **/
167+
if (inputInfoItem.second->getTensorDesc().getDims().size() == 4) {
168+
/** Iterate over all input images **/
151169
for (size_t image_id = 0; image_id < images.size(); ++image_id)
152-
matToTensor(images[image_id], tensor, image_id);
170+
matToBlob(images[image_id], input, image_id);
153171
}
154172

155-
if (shape.size() == 2) {
156-
float* data = tensor.data<float>();
157-
data[0] = static_cast<float>(modelInputHeight); // height
158-
data[1] = static_cast<float>(modelInputWidth); // width
173+
/** Fill second input tensor with image info **/
174+
if (inputInfoItem.second->getTensorDesc().getDims().size() == 2) {
175+
InferenceEngine::LockedMemory<void> inputMapped =
176+
InferenceEngine::as<InferenceEngine::MemoryBlob>(input)->wmap();
177+
auto data = inputMapped.as<float *>();
178+
data[0] = static_cast<float>(netInputHeight); // height
179+
data[1] = static_cast<float>(netInputWidth); // width
159180
data[2] = 1;
160181
}
161182
}
162183

163-
// Do inference
164-
infer_request.infer();
184+
// -----------------------------------------------------------------------------------------------------
165185

166-
// Postprocess output blobs
167-
float* do_data = nullptr;
168-
float* masks_data = nullptr;
169186

170-
size_t BOX_DESCRIPTION_SIZE = 0;
187+
// ----------------------------Do inference-------------------------------------------------------------
188+
infer_request.Infer();
189+
// -----------------------------------------------------------------------------------------------------
171190

172-
size_t BOXES = 0;
173-
size_t C = 0;
174-
size_t H = 0;
175-
size_t W = 0;
191+
// ---------------------------Postprocess output blobs--------------------------------------------------
192+
const auto do_blob = infer_request.GetBlob(FLAGS_detection_output_name.c_str());
193+
InferenceEngine::LockedMemory<const void> doBlobMapped =
194+
InferenceEngine::as<InferenceEngine::MemoryBlob>(do_blob)->rmap();
195+
const auto do_data = doBlobMapped.as<float*>();
176196

177-
for (size_t idx = 0; idx < outputs.size(); idx++) {
178-
ov::Tensor tensor = infer_request.get_output_tensor(idx);
179-
ov::Shape shape = tensor.get_shape();
180-
size_t dims = shape.size();
181-
if (dims == 2) {
182-
do_data = tensor.data<float>();
183-
// amount of elements in each detected box description (batch, label, prob, x1, y1, x2, y2)
184-
BOX_DESCRIPTION_SIZE = shape[1];
185-
}
186-
if (dims == 4) {
187-
masks_data = tensor.data<float>();
188-
BOXES = shape[ov::layout::batch_idx(layout_nchw)];
189-
C = shape[ov::layout::channels_idx(layout_nchw)];
190-
H = shape[ov::layout::height_idx(layout_nchw)];
191-
W = shape[ov::layout::width_idx(layout_nchw)];
192-
}
193-
}
197+
const auto masks_blob = infer_request.GetBlob(FLAGS_masks_name.c_str());
198+
InferenceEngine::LockedMemory<const void> masksBlobMapped =
199+
InferenceEngine::as<InferenceEngine::MemoryBlob>(masks_blob)->rmap();
200+
const auto masks_data = masksBlobMapped.as<float*>();
194201

195202
const float PROBABILITY_THRESHOLD = 0.2f;
196-
// threshold used to determine whether mask pixel corresponds to object or to background
197-
const float MASK_THRESHOLD = 0.5f;
203+
const float MASK_THRESHOLD = 0.5f; // threshold used to determine whether mask pixel corresponds to object or to background
204+
// amount of elements in each detected box description (batch, label, prob, x1, y1, x2, y2)
205+
IE_ASSERT(do_blob->getTensorDesc().getDims().size() == 2);
206+
size_t BOX_DESCRIPTION_SIZE = do_blob->getTensorDesc().getDims().back();
207+
208+
const InferenceEngine::TensorDesc& masksDesc = masks_blob->getTensorDesc();
209+
IE_ASSERT(masksDesc.getDims().size() == 4);
210+
size_t BOXES = getTensorBatch(masksDesc);
211+
size_t C = getTensorChannels(masksDesc);
212+
size_t H = getTensorHeight(masksDesc);
213+
size_t W = getTensorWidth(masksDesc);
214+
198215

199216
size_t box_stride = W * H * C;
200217

@@ -205,28 +222,22 @@ int main(int argc, char* argv[]) {
205222
output_images.push_back(img.clone());
206223
}
207224

208-
// Iterating over all boxes
225+
/** Iterating over all boxes **/
209226
for (size_t box = 0; box < BOXES; ++box) {
210227
float* box_info = do_data + box * BOX_DESCRIPTION_SIZE;
211228
auto batch = static_cast<int>(box_info[0]);
212-
213229
if (batch < 0)
214230
break;
215-
if (batch >= static_cast<int>(modelBatchSize))
231+
if (batch >= static_cast<int>(netBatchSize))
216232
throw std::logic_error("Invalid batch ID within detection output box");
217-
218233
float prob = box_info[2];
219-
220234
float x1 = std::min(std::max(0.0f, box_info[3] * images[batch].cols), static_cast<float>(images[batch].cols));
221235
float y1 = std::min(std::max(0.0f, box_info[4] * images[batch].rows), static_cast<float>(images[batch].rows));
222236
float x2 = std::min(std::max(0.0f, box_info[5] * images[batch].cols), static_cast<float>(images[batch].cols));
223237
float y2 = std::min(std::max(0.0f, box_info[6] * images[batch].rows), static_cast<float>(images[batch].rows));
224-
225238
int box_width = static_cast<int>(x2 - x1);
226239
int box_height = static_cast<int>(y2 - y1);
227-
228-
auto class_id = static_cast<size_t>(box_info[1] + 1e-6);
229-
240+
auto class_id = static_cast<size_t>(box_info[1] + 1e-6f);
230241
if (prob > PROBABILITY_THRESHOLD && box_width > 0 && box_height > 0) {
231242
size_t color_index = class_color.emplace(class_id, class_color.size()).first->second;
232243
auto& color = CITYSCAPES_COLORS[color_index % arraySize(CITYSCAPES_COLORS)];
@@ -246,13 +257,11 @@ int main(int argc, char* argv[]) {
246257
cv::Scalar(color.blue(), color.green(), color.red()));
247258
roi_input_img.copyTo(uchar_resized_mask, resized_mask_mat <= MASK_THRESHOLD);
248259

249-
cv::addWeighted(uchar_resized_mask, alpha, roi_input_img, 1.0 - alpha, 0.0f, roi_input_img);
260+
cv::addWeighted(uchar_resized_mask, alpha, roi_input_img, 1.0f - alpha, 0.0f, roi_input_img);
250261
cv::rectangle(output_images[batch], roi, cv::Scalar(0, 0, 1), 1);
251262
}
252263
}
253-
254264
metrics.update(startTime);
255-
256265
for (size_t i = 0; i < output_images.size(); i++) {
257266
std::string imgName = "out" + std::to_string(i) + ".png";
258267
cv::imwrite(imgName, output_images[i]);

demos/mask_rcnn_demo/cpp/mask_rcnn_demo.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
// Copyright (C) 2018-2022 Intel Corporation
1+
// Copyright (C) 2018-2019 Intel Corporation
22
// SPDX-License-Identifier: Apache-2.0
33
//
44

55
#pragma once
66

7-
#include <iostream>
87
#include <string>
98
#include <vector>
10-
#include "gflags/gflags.h"
9+
#include <gflags/gflags.h>
10+
#include <iostream>
1111

1212
static const char help_message[] = "Print a usage message.";
1313
static const char image_message[] = "Required. Path to a .bmp image.";

0 commit comments

Comments
 (0)