3 Copyright (C) 2018-2019 Intel Corporation
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
9 http://www.apache.org/licenses/LICENSE-2.0
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
17 from __future__ import print_function
20 from argparse import ArgumentParser, SUPPRESS
25 from openvino.inference_engine import IENetwork, IEPlugin
28 def build_argparser():
29 parser = ArgumentParser(add_help=False)
30 args = parser.add_argument_group('Options')
31 args.add_argument('-h', '--help', action='help', default=SUPPRESS, help='Show this help message and exit.')
32 args.add_argument("-m", "--model", help="Required. Path to an .xml file with a trained model.", required=True,
34 args.add_argument("-i", "--input", help="Required. Path to a folder with images or path to an image files",
37 args.add_argument("-l", "--cpu_extension",
38 help="Optional. Required for CPU custom layers. "
39 "MKLDNN (CPU)-targeted custom layers. Absolute path to a shared library with the"
40 " kernels implementations.", type=str, default=None)
41 args.add_argument("-pp", "--plugin_dir", help="Optional. Path to a plugin folder", type=str, default=None)
42 args.add_argument("-d", "--device",
43 help="Optional. Specify the target device to infer on; CPU, GPU, FPGA, HDDL, MYRIAD or HETERO: is "
44 "acceptable. The sample will look for a suitable plugin for device specified. Default "
46 default="CPU", type=str)
47 args.add_argument("--labels", help="Optional. Path to a labels mapping file", default=None, type=str)
48 args.add_argument("-nt", "--number_top", help="Optional. Number of top results", default=10, type=int)
49 args.add_argument("-ni", "--number_iter", help="Optional. Number of inference iterations", default=1, type=int)
50 args.add_argument("-pc", "--perf_counts", help="Optional. Report performance counters", default=False,
57 log.basicConfig(format="[ %(levelname)s ] %(message)s", level=log.INFO, stream=sys.stdout)
58 args = build_argparser().parse_args()
59 model_xml = args.model
60 model_bin = os.path.splitext(model_xml)[0] + ".bin"
62 # Plugin initialization for specified device and load extensions library if specified
63 plugin = IEPlugin(device=args.device, plugin_dirs=args.plugin_dir)
64 if args.cpu_extension and 'CPU' in args.device:
65 plugin.add_cpu_extension(args.cpu_extension)
67 log.info("Loading network files:\n\t{}\n\t{}".format(model_xml, model_bin))
68 net = IENetwork(model=model_xml, weights=model_bin)
70 if plugin.device == "CPU":
71 supported_layers = plugin.get_supported_layers(net)
72 not_supported_layers = [l for l in net.layers.keys() if l not in supported_layers]
73 if len(not_supported_layers) != 0:
74 log.error("Following layers are not supported by the plugin for specified device {}:\n {}".
75 format(plugin.device, ', '.join(not_supported_layers)))
76 log.error("Please try to specify cpu extensions library path in sample's command line parameters using -l "
77 "or --cpu_extension command line argument")
80 assert len(net.inputs.keys()) == 1, "Sample supports only single input topologies"
81 assert len(net.outputs) == 1, "Sample supports only single output topologies"
83 log.info("Preparing input blobs")
84 input_blob = next(iter(net.inputs))
85 out_blob = next(iter(net.outputs))
86 net.batch_size = len(args.input)
88 # Read and pre-process input images
89 n, c, h, w = net.inputs[input_blob].shape
90 images = np.ndarray(shape=(n, c, h, w))
92 image = cv2.imread(args.input[i])
93 if image.shape[:-1] != (h, w):
94 log.warning("Image {} is resized from {} to {}".format(args.input[i], image.shape[:-1], (h, w)))
95 image = cv2.resize(image, (w, h))
96 image = image.transpose((2, 0, 1)) # Change data layout from HWC to CHW
98 log.info("Batch size is {}".format(n))
100 # Loading model to the plugin
101 log.info("Loading model to the plugin")
102 exec_net = plugin.load(network=net)
104 # Start sync inference
105 log.info("Starting inference ({} iterations)".format(args.number_iter))
107 for i in range(args.number_iter):
109 res = exec_net.infer(inputs={input_blob: images})
110 infer_time.append((time() - t0) * 1000)
111 log.info("Average running time of one iteration: {} ms".format(np.average(np.asarray(infer_time))))
113 perf_counts = exec_net.requests[0].get_perf_counts()
114 log.info("Performance counters:")
115 print("{:<70} {:<15} {:<15} {:<15} {:<10}".format('name', 'layer_type', 'exet_type', 'status', 'real_time, us'))
116 for layer, stats in perf_counts.items():
117 print("{:<70} {:<15} {:<15} {:<15} {:<10}".format(layer, stats['layer_type'], stats['exec_type'],
118 stats['status'], stats['real_time']))
120 # Processing output blob
121 log.info("Processing output blob")
123 log.info("Top {} results: ".format(args.number_top))
125 with open(args.labels, 'r') as f:
126 labels_map = [x.split(sep=' ', maxsplit=1)[-1].strip() for x in f]
129 classid_str = "classid"
130 probability_str = "probability"
131 for i, probs in enumerate(res):
132 probs = np.squeeze(probs)
133 top_ind = np.argsort(probs)[-args.number_top:][::-1]
134 print("Image {}\n".format(args.input[i]))
135 print(classid_str, probability_str)
136 print("{} {}".format('-' * len(classid_str), '-' * len(probability_str)))
138 det_label = labels_map[id] if labels_map else "{}".format(id)
139 label_length = len(det_label)
140 space_num_before = (len(classid_str) - label_length) // 2
141 space_num_after = len(classid_str) - (space_num_before + label_length) + 2
142 space_num_before_prob = (len(probability_str) - len(str(probs[id]))) // 2
143 print("{}{}{}{}{:.7f}".format(' ' * space_num_before, det_label,
144 ' ' * space_num_after, ' ' * space_num_before_prob,
149 if __name__ == '__main__':
150 sys.exit(main() or 0)