118 lines
6.1 KiB
C++
118 lines
6.1 KiB
C++
// Copyright (C) 2018 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
#include <iomanip>
|
|
#include <vector>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <cstdlib>
|
|
|
|
#include <opencv2/opencv.hpp>
|
|
#include <inference_engine.hpp>
|
|
#include <samples/common.hpp>
|
|
|
|
using namespace InferenceEngine;
|
|
|
|
int main(int argc, char *argv[]) {
|
|
try {
|
|
// ------------------------------ Parsing and validation of input args ---------------------------------
|
|
if (argc != 4) {
|
|
std::cout << "Usage : ./hello_autoresize_classification <path_to_model> <path_to_image> <device_name>"
|
|
<< std::endl;
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
const std::string input_model{argv[1]};
|
|
const std::string input_image_path{argv[2]};
|
|
const std::string device_name{argv[3]};
|
|
// -----------------------------------------------------------------------------------------------------
|
|
|
|
// --------------------------- 1. Load Plugin for inference engine -------------------------------------
|
|
InferencePlugin plugin = PluginDispatcher({"../../../lib/intel64", ""}).getPluginByDevice(device_name);
|
|
// -----------------------------------------------------------------------------------------------------
|
|
|
|
// --------------------------- 2. Read IR Generated by ModelOptimizer (.xml and .bin files) ------------
|
|
int batchSize = 1;
|
|
CNNNetReader network_reader;
|
|
network_reader.ReadNetwork(input_model);
|
|
network_reader.ReadWeights(input_model.substr(0, input_model.size() - 4) + ".bin");
|
|
network_reader.getNetwork().setBatchSize(batchSize);
|
|
CNNNetwork network = network_reader.getNetwork();
|
|
// -----------------------------------------------------------------------------------------------------
|
|
|
|
// --------------------------- 3. Configure input & output ---------------------------------------------
|
|
// --------------------------- Prepare input blobs -----------------------------------------------------
|
|
InputInfo::Ptr input_info = network.getInputsInfo().begin()->second;
|
|
std::string input_name = network.getInputsInfo().begin()->first;
|
|
|
|
/* Mark input as resizable by setting of a resize algorithm.
|
|
* In this case we will be able to set an input blob of any shape to an infer request.
|
|
* Resize and layout conversions are executed automatically during inference */
|
|
input_info->getPreProcess().setResizeAlgorithm(RESIZE_BILINEAR);
|
|
input_info->setLayout(Layout::NHWC);
|
|
input_info->setPrecision(Precision::U8);
|
|
|
|
// --------------------------- Prepare output blobs ----------------------------------------------------
|
|
DataPtr output_info = network.getOutputsInfo().begin()->second;
|
|
std::string output_name = network.getOutputsInfo().begin()->first;
|
|
|
|
output_info->setPrecision(Precision::FP32);
|
|
// -----------------------------------------------------------------------------------------------------
|
|
|
|
// --------------------------- 4. Loading model to the plugin ------------------------------------------
|
|
ExecutableNetwork executable_network = plugin.LoadNetwork(network, {});
|
|
// -----------------------------------------------------------------------------------------------------
|
|
|
|
// --------------------------- 5. Create infer request -------------------------------------------------
|
|
InferRequest infer_request = executable_network.CreateInferRequest();
|
|
// -----------------------------------------------------------------------------------------------------
|
|
|
|
// --------------------------- 6. Prepare input --------------------------------------------------------
|
|
/* Read input image to a blob and set it to an infer request without resize and layout conversions. */
|
|
cv::Mat image = cv::imread(input_image_path);
|
|
Blob::Ptr imgBlob = wrapMat2Blob(image); // just wrap Mat data by Blob::Ptr without allocating of new memory
|
|
infer_request.SetBlob(input_name, imgBlob); // infer_request accepts input blob of any size
|
|
// -----------------------------------------------------------------------------------------------------
|
|
|
|
// --------------------------- 7. Do inference --------------------------------------------------------
|
|
typedef std::chrono::high_resolution_clock Time;
|
|
typedef std::chrono::duration<double, std::ratio<1, 1000>> ms;
|
|
|
|
double total = 0.0;
|
|
|
|
/* Running the request synchronously */
|
|
auto t0 = Time::now();
|
|
infer_request.Infer(); // input pre-processing is invoked on this step with resize and layout conversion
|
|
auto t1 = Time::now();
|
|
ms d = std::chrono::duration_cast<ms>(t1 - t0);
|
|
total += d.count();
|
|
// -----------------------------------------------------------------------------------------------------
|
|
|
|
// --------------------------- 8. Process output ------------------------------------------------------
|
|
Blob::Ptr output = infer_request.GetBlob(output_name);
|
|
auto output_data = output->buffer().as<PrecisionTrait<Precision::FP32>::value_type*>();
|
|
|
|
std::vector<unsigned> results;
|
|
/* This is to sort output probabilities and put it to results vector */
|
|
TopResults(10, *output, results);
|
|
|
|
std::cout << std::endl << "Top 10 results:" << std::endl << std::endl;
|
|
for (size_t id = 0; id < 10; ++id) {
|
|
std::cout.precision(7);
|
|
auto result = output_data[results[id]];
|
|
std::cout << std::left << std::fixed << result << " label #" << results[id] << std::endl;
|
|
}
|
|
// -----------------------------------------------------------------------------------------------------
|
|
|
|
std::cout << std::endl << "total inference time: " << total << std::endl;
|
|
std::cout << std::endl << "Throughput: " << 1000 * batchSize / total << " FPS" << std::endl;
|
|
std::cout << std::endl;
|
|
} catch (const std::exception & ex) {
|
|
std::cerr << ex.what() << std::endl;
|
|
return EXIT_FAILURE;
|
|
}
|
|
return EXIT_SUCCESS;
|
|
}
|