summaryrefslogtreecommitdiff
path: root/inference-engine/samples/hello_request_classification/main.cpp
blob: 0137851ed16af5adbe30becdac340641fa4a3f26 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// 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>

using namespace InferenceEngine;

int main(int argc, char *argv[]) {
    try {
        // ------------------------------ Parsing and validation of input args ---------------------------------
        if (argc != 4) {
            std::cout << "Usage : ./hello_request_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) ------------
        CNNNetReader network_reader;
        network_reader.ReadNetwork(input_model);
        network_reader.ReadWeights(input_model.substr(0, input_model.size() - 4) + ".bin");
        network_reader.getNetwork().setBatchSize(1);
        CNNNetwork network = network_reader.getNetwork();
        // -----------------------------------------------------------------------------------------------------

        // --------------------------- 3. Configure input & output ---------------------------------------------

        // --------------------------- Prepare input blobs -----------------------------------------------------
        /** Taking information about all topology inputs **/
        InputsDataMap input_info(network.getInputsInfo());
        /** Iterating over all input info**/
        for (auto &item : input_info) {
            InputInfo::Ptr input_data = item.second;
            input_data->setPrecision(Precision::U8);
            input_data->setLayout(Layout::NCHW);
        }

        // ------------------------------ Prepare output blobs -------------------------------------------------
        /** Taking information about all topology outputs **/
        OutputsDataMap output_info(network.getOutputsInfo());
        /** Iterating over all output info**/
        for (auto &item : output_info) {
            DataPtr output_data = item.second;
            if (!output_data) {
                throw std::runtime_error("Output data pointer is invalid");
            }
            output_data->setPrecision(Precision::FP32);
        }
        // -----------------------------------------------------------------------------------------------------

        // --------------------------- 4. Loading model to the plugin ------------------------------------------
        ExecutableNetwork executable_network = plugin.LoadNetwork(network, {});
        // -----------------------------------------------------------------------------------------------------

        // --------------------------- 5. Create infer request -------------------------------------------------
        InferRequest async_infer_request = executable_network.CreateInferRequest();
        // -----------------------------------------------------------------------------------------------------

        // --------------------------- 6. Prepare input --------------------------------------------------------
        for (auto &item : input_info) {
            cv::Mat image = cv::imread(input_image_path);

            auto input_name = item.first;
            InputInfo::Ptr input_data = item.second;

            /** Getting input blob **/
            Blob::Ptr input = async_infer_request.GetBlob(input_name);
            auto input_buffer = input->buffer().as<PrecisionTrait<Precision::U8>::value_type *>();

            /** Fill input tensor with planes. First b channel, then g and r channels **/
            if (image.empty()) throw std::logic_error("Invalid image at path: " + input_image_path);

            /* Resize and copy data from the image to the input blob */
            cv::resize(image, image, cv::Size(input_data->getTensorDesc().getDims()[3], input_data->getTensorDesc().getDims()[2]));
            auto dims = input->getTensorDesc().getDims();
            size_t channels_number = dims[1];
            size_t image_size = dims[3] * dims[2];
            for (size_t pid = 0; pid < image_size; ++pid) {
                for (size_t ch = 0; ch < channels_number; ++ch) {
                    input_buffer[ch * image_size + pid] = image.at<cv::Vec3b>(pid)[ch];
                }
            }
        }
        // -----------------------------------------------------------------------------------------------------

        // --------------------------- 7. Do inference ---------------------------------------------------------
        const int max_number_of_iterations = 10;
        int iterations = max_number_of_iterations;
        /** Set callback function for calling on completion of async request **/
        async_infer_request.SetCompletionCallback(
                [&] {
                    std::cout << "Completed " << max_number_of_iterations - iterations + 1 << " async request"
                              << std::endl;
                    if (--iterations) {
                        /** Start async request (max_number_of_iterations - 1) more times **/
                        async_infer_request.StartAsync();
                    }
                });
        /** Start async request for the first time **/
        async_infer_request.StartAsync();
        /** Wait all repetition of async requests **/
        for (int i = 0; i < max_number_of_iterations; i++) {
            async_infer_request.Wait(IInferRequest::WaitMode::RESULT_READY);
        }
        // -----------------------------------------------------------------------------------------------------

        // --------------------------- 8. Process output -------------------------------------------------------
        for (auto &item : output_info) {
            auto output_name = item.first;
            Blob::Ptr output = async_infer_request.GetBlob(output_name);
            auto output_buffer = 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_buffer[results[id]];
                std::cout << std::left << std::fixed << result << " label #" << results[id] << std::endl;
            }
        }
        // -----------------------------------------------------------------------------------------------------
    } catch (const std::exception & ex) {
        std::cerr << ex.what() << std::endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}