diff --git a/advanced-video-analytics/interactive_face_detection.py b/advanced-video-analytics/interactive_face_detection.py new file mode 100644 index 00000000..4e0e17fb --- /dev/null +++ b/advanced-video-analytics/interactive_face_detection.py @@ -0,0 +1,473 @@ +#!/usr/bin/env python +""" + Copyright (c) 2018 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +from __future__ import print_function +import sys +import os +from argparse import ArgumentParser +import cv2 +import time +import numpy as np +import math +import logging as log +from PIL import Image +from openvino.inference_engine import IENetwork, IEPlugin +CV_PI=3.1415926535897932384626433832795 + +def build_argparser(): + parser = ArgumentParser() + parser.add_argument("-m", "--model", help="Path to an .xml file with a trained model.", required=True, type=str) + parser.add_argument("-m_ag", "--ag_model", help="Path to an .xml file with a trained model.", default=None, type=str) + parser.add_argument("-m_hp", "--hp_model", help="Path to an .xml file with a trained model.", default=None, type=str) + parser.add_argument("-m_em", "--em_model", help="Path to an .xml file with a trained model.", default=None, type=str) + parser.add_argument("-m_lm", "--lm_model", help="Path to an .xml file with a trained model.", default=None, type=str) + parser.add_argument("-pc", "--perf_counts", help="Report performance counters", default=False, action="store_true") + parser.add_argument("-i", "--input", + help="Path to video file or image. 'cam' for capturing video stream from camera", required=True, + type=str) + parser.add_argument("-l", "--cpu_extension", + help="MKLDNN (CPU)-targeted custom layers.Absolute path to a shared library with the kernels " + "impl.", type=str, default=None) + parser.add_argument("-pp", "--plugin_dir", help="Path to a plugin folder", type=str, default=None) + parser.add_argument("-d", "--device", + help="Specify the target device to infer on; CPU, GPU, FPGA or MYRIAD is acceptable. Demo " + "will look for a suitable plugin for device specified (CPU by default)", default="CPU", + type=str) + parser.add_argument("-d_ag", "--device_ag", + help="Target device for Age/Gender Recognition network (CPU, GPU, FPGA, or MYRIAD). The demo will look for a suitable plugin for a specified device. (CPU by default)", default="CPU", + type=str) + parser.add_argument("-d_hp", "--device_hp", + help="Target device for Head Pose Estimation network (CPU, GPU, FPGA, or MYRIAD). The demo will look for a suitable plugin for a specified device. (CPU by default)", default="CPU", + type=str) + parser.add_argument("-d_em", "--device_em", + help="Target device for Emotions Recognition network (CPU, GPU, FPGA, or MYRIAD). The demo will look for a suitable plugin for a specified device.(CPU by default)", default="CPU", + type=str) + parser.add_argument("-d_lm", "--device_lm", + help="Target device for Facial Landmarks Estimation network (CPU, GPU, FPGA, or MYRIAD). The demo will look for a suitable plugin for device specified.(CPU by default)", default="CPU", + type=str) + + parser.add_argument("--labels", help="Labels mapping file", default=None, type=str) + parser.add_argument("-pt", "--prob_threshold", help="Probability threshold for detections filtering", + default=0.5, type=float) + parser.add_argument("-no_show", "--no_show", help="do not show processed video", + default=False, action="store_true") + parser.add_argument("-r", "--raw", help="raw_output_message", + default=False, action="store_true") + return parser + +emotions = ["neutral", "happy", "sad", "surprise", "anger"] + +def drawAxes(pitch,yaw,roll,cpoint,frame): + + pitch *= CV_PI/180.0 + yaw *= CV_PI/180.0 + roll *= CV_PI/180.0 + + yawMatrix = np.matrix([[math.cos(yaw), 0, -math.sin(yaw)], [0, 1, 0], [math.sin(yaw), 0, math.cos(yaw)]]) + pitchMatrix = np.matrix([[1, 0, 0],[0, math.cos(pitch), -math.sin(pitch)], [0, math.sin(pitch), math.cos(pitch)]]) + rollMatrix = np.matrix([[math.cos(roll), -math.sin(roll), 0],[math.sin(roll), math.cos(roll), 0], [0, 0, 1]]) + + #Rotational Matrix + R = yawMatrix * pitchMatrix * rollMatrix + rows=frame.shape[0] + cols=frame.shape[1] + + cameraMatrix=np.zeros((3,3), dtype=np.float32) + cameraMatrix[0][0]= 950.0 + cameraMatrix[0][2]= cols/2 + cameraMatrix[1][0]= 950.0 + cameraMatrix[1][1]= rows/2 + cameraMatrix[2][1]= 1 + + xAxis=np.zeros((3,1), dtype=np.float32) + xAxis[0]=50 + xAxis[1]=0 + xAxis[2]=0 + + yAxis=np.zeros((3,1), dtype=np.float32) + yAxis[0]=0 + yAxis[1]=-50 + yAxis[2]=0 + + zAxis=np.zeros((3,1), dtype=np.float32) + zAxis[0]=0 + zAxis[1]=0 + zAxis[2]=-50 + + zAxis1=np.zeros((3,1), dtype=np.float32) + zAxis1[0]=0 + zAxis1[1]=0 + zAxis1[2]=50 + + o=np.zeros((3,1), dtype=np.float32) + o[2]=cameraMatrix[0][0] + + xAxis=R*xAxis+o + yAxis=R*yAxis+o + zAxis=R*zAxis+o + zAxis1=R*zAxis1+o + + p2x=int((xAxis[0]/xAxis[2]*cameraMatrix[0][0])+cpoint[0]) + p2y=int((xAxis[1]/xAxis[2]*cameraMatrix[1][0])+cpoint[1]) + cv2.line(frame,(cpoint[0],cpoint[1]),(p2x,p2y),(0,0,255),2) + + p2x=int((yAxis[0]/yAxis[2]*cameraMatrix[0][0])+cpoint[0]) + p2y=int((yAxis[1]/yAxis[2]*cameraMatrix[1][0])+cpoint[1]) + cv2.line(frame,(cpoint[0],cpoint[1]),(p2x,p2y),(0,255,0),2) + + p1x=int((zAxis1[0]/zAxis1[2]*cameraMatrix[0][0])+cpoint[0]) + p1y=int((zAxis1[1]/zAxis1[2]*cameraMatrix[1][0])+cpoint[1]) + + p2x=int((zAxis[0]/zAxis[2]*cameraMatrix[0][0])+cpoint[0]) + p2y=int((zAxis[1]/zAxis[2]*cameraMatrix[1][0])+cpoint[1]) + + cv2.line(frame,(p1x,p1y),(p2x,p2y),(255,0,0),2) + cv2.circle(frame,(p2x,p2y),3,(255,0,0)) + +def load_model(feature,model_xml,device,plugin_dirs,input_key_length,output_key_length,cpu_extension): + + model_bin = os.path.splitext(model_xml)[0] + ".bin" + + log.info("Initializing plugin for {} device...".format(device)) + plugin = IEPlugin(device, plugin_dirs) + + log.info("Loading network files for {}".format(feature)) + if cpu_extension and 'CPU' in device: + plugin.add_cpu_extension(cpu_extension) + else: + plugin.set_config({"PERF_COUNT":"YES"}) + net = IENetwork(model=model_xml, weights=model_bin) + + if plugin.device == "CPU": + supported_layers = plugin.get_supported_layers(net) + not_supported_layers = [l for l in net.layers.keys() if l not in supported_layers] + if len(not_supported_layers) != 0: + log.error("Following layers are not supported by the plugin for specified device {}:\n {}". + format(plugin.device, ', '.join(not_supported_layers))) + log.error("Please try to specify cpu extensions library path in demo's command line parameters using -l " + "or --cpu_extension command line argument") + sys.exit(1) + + log.info("Checking {} network inputs".format(feature)) + assert len(net.inputs.keys()) == input_key_length, "Demo supports only single input topologies" + log.info("Checking {} network outputs".format(feature)) + assert len(net.outputs) == output_key_length, "Demo supports only single output topologies" + return plugin,net + + +def main(): + log.basicConfig(format="[ %(levelname)s ] %(message)s", level=log.INFO, stream=sys.stdout) + args = build_argparser().parse_args() + age_enabled = False + headPose_enabled = False + emotions_enabled = False + landmarks_enabled = False + + log.info("Reading IR...") + # Face detection + #log.info("Loading network files for Face Detection") + plugin,net=load_model("Face Detection",args.model,args.device.upper(),args.plugin_dir,1,1,args.cpu_extension) + input_blob = next(iter(net.inputs)) + out_blob = next(iter(net.outputs)) + exec_net = plugin.load(network=net, num_requests=2) + n, c, h, w = net.inputs[input_blob].shape + del net + + # age and gender + if args.model and args.ag_model: + age_enabled =True + #log.info("Loading network files for Age/Gender Recognition") + plugin,ag_net = load_model("Age/Gender Recognition",args.ag_model,args.device_ag.upper(),args.plugin_dir,1,2,args.cpu_extension) + age_input_blob=next(iter(ag_net.inputs)) + age_out_blob=next(iter(ag_net.outputs)) + age_exec_net=plugin.load(network=ag_net, num_requests=2) + ag_n, ag_c, ag_h, ag_w = ag_net.inputs[input_blob].shape + del ag_net + + # Head Pose + if args.model and args.hp_model: + headPose_enabled = True + #log.info("Loading network files for Head Pose Estimation") + plugin,hp_net=load_model("Head Pose Estimation",args.hp_model,args.device_hp,args.plugin_dir,1,3,args.cpu_extension) + hp_input_blob=next(iter(hp_net.inputs)) + hp_out_blob=next(iter(hp_net.outputs)) + hp_exec_net=plugin.load(network=hp_net, num_requests=2) + hp_n, hp_c, hp_h, hp_w = hp_net.inputs[input_blob].shape + del hp_net + + # Emotions + if args.model and args.em_model: + emotions_enabled = True + #log.info("Loading network files for Emotions Recognition") + plugin,em_net=load_model("Emotions Recognition",args.em_model,args.device_em.upper(),args.plugin_dir,1,1,args.cpu_extension) + em_input_blob=next(iter(em_net.inputs)) + em_out_blob=next(iter(em_net.outputs)) + em_exec_net=plugin.load(network=em_net, num_requests=2) + em_n, em_c, em_h, em_w = em_net.inputs[input_blob].shape + del em_net + + # Facial Landmarks + if args.model and args.lm_model: + landmarks_enabled = True + #log.info("Loading network files for Facial Landmarks Estimation") + plugin,lm_net=load_model("Facial Landmarks Estimation",args.lm_model,args.device_lm.upper(),args.plugin_dir,1,1,args.cpu_extension) + lm_input_blob=next(iter(lm_net.inputs)) + lm_out_blob=next(iter(lm_net.outputs)) + lm_exec_net=plugin.load(network=lm_net, num_requests=2) + lm_n, lm_c, lm_h, lm_w = lm_net.inputs[input_blob].shape + del lm_net + + total_start = time.time() + + if args.input == 'cam': + input_stream = 0 + else: + input_stream = args.input + assert os.path.isfile(args.input), "Specified input file doesn't exist" + if args.labels: + with open(args.labels, 'r') as f: + labels_map = [x.strip() for x in f] + else: + labels_map = None + + cap = cv2.VideoCapture(input_stream) + if not cap.isOpened(): + sys.exit(1) + cur_request_id = 0 + log.info("Starting inference ...") + log.info("To stop the demo execution press Esc button") + is_async_mode = True + render_time = 0 + framesCounter = 0 + decode_time = 0 + visual_time = 0 + + decode_prev_start = time.time() + ret, frame = cap.read() + decode_prev_finish = time.time() + decode_prev_time = decode_prev_finish - decode_prev_start + while cap.isOpened(): + analytics_time = 0 + decode_next_start = time.time() + ret, frame = cap.read() + decode_next_finish = time.time() + decode_next_time = decode_next_finish - decode_next_start + if not ret: + break + + framesCounter+=1 + initial_w = cap.get(3) + initial_h = cap.get(4) + + inf_start = time.time() + in_frame = cv2.resize(frame, (w, h)) + in_frame = in_frame.transpose((2, 0, 1)) # Change data layout from HWC to CHW + in_frame = in_frame.reshape((n, c, h, w)) + exec_net.start_async(request_id=cur_request_id, inputs={input_blob: in_frame}) + if exec_net.requests[cur_request_id].wait(-1) == 0: + inf_end = time.time() + det_time = inf_end - inf_start + + #analytics_start_time =time.time() + # Parse detection results of the current request + res = exec_net.requests[cur_request_id].outputs[out_blob] + for obj in res[0][0]: + # Draw only objects when probability more than specified threshold + if obj[2] > args.prob_threshold: + xmin = int(obj[3] * initial_w) + ymin = int(obj[4] * initial_h) + xmax = int(obj[5] * initial_w) + ymax = int(obj[6] * initial_h) + + #Crop the face rectangle for further processing + clippedRect = frame[ymin:ymax, xmin:xmax] + if (clippedRect.size)==0: + continue + + height = ymax - ymin + width = xmax -xmin + + #Age and Gender + age_inf_time=0 + if age_enabled: + age_inf_start = time.time() + clipped_face = cv2.resize(clippedRect, (ag_w, ag_h)) + clipped_face = clipped_face.transpose((2, 0, 1)) # Change data layout from HWC to CHW + clipped_face = clipped_face.reshape((ag_n, ag_c, ag_h, ag_w)) + ag_res = age_exec_net.start_async(request_id=0,inputs={'data': clipped_face}) + if age_exec_net.requests[cur_request_id].wait(-1) == 0: + age_inf_end = time.time() + age_inf_time=age_inf_end - age_inf_start + #Heapose + hp_inf_time=0 + if headPose_enabled: + hp_inf_start = time.time() + clipped_face_hp = cv2.resize(clippedRect, (hp_w, hp_h)) + clipped_face_hp = clipped_face_hp.transpose((2, 0, 1)) # Change data layout from HWC to CHW + clipped_face_hp = clipped_face_hp.reshape((hp_n, hp_c, hp_h, hp_w)) + hp_res = hp_exec_net.start_async(request_id=0,inputs={'data': clipped_face_hp}) + if hp_exec_net.requests[cur_request_id].wait(-1) == 0: + hp_inf_end = time.time() + hp_inf_time=hp_inf_end - hp_inf_start + #Emotion + em_inf_time=0 + if emotions_enabled: + em_inf_start = time.time() + clipped_face_em = cv2.resize(clippedRect, (em_w, em_h)) + clipped_face_em = clipped_face_em.transpose((2, 0, 1)) # Change data layout from HWC to CHW + clipped_face_em = clipped_face_em.reshape((em_n, em_c, em_h, em_w)) + em_res = em_exec_net.start_async(request_id=0,inputs={'data': clipped_face_em}) + if em_exec_net.requests[cur_request_id].wait(-1) == 0: + em_inf_end = time.time() + em_inf_time=em_inf_end - em_inf_start + + #Landmarks + lm_inf_time=0 + if landmarks_enabled: + lm_inf_start = time.time() + clipped_face_lm = cv2.resize(clippedRect, (lm_w, lm_h)) + clipped_face_lm = clipped_face_lm.transpose((2, 0, 1)) # Change data layout from HWC to CHW + clipped_face_lm = clipped_face_lm.reshape((lm_n, lm_c, lm_h, lm_w)) + lm_exec_net.start_async(request_id=0,inputs={'data': clipped_face_lm}) + if lm_exec_net.requests[cur_request_id].wait(-1) == 0: + lm_inf_end = time.time() + lm_inf_time=lm_inf_end - lm_inf_start + + analytics_time = age_inf_time + hp_inf_time + em_inf_time + lm_inf_time + + visual_start = time.time() + if args.no_show==False: + if age_enabled: + age = int((age_exec_net.requests[cur_request_id].outputs['age_conv3'][0][0][0][0])*100) + + if(((age_exec_net.requests[cur_request_id].outputs['prob'][0][0][0][0])) > 0.5): + gender = 'F' + cv2.putText(frame, str(gender) + ','+str(age), (xmin, ymin - 7), cv2.FONT_HERSHEY_COMPLEX, 0.6, (10,10,200), 1) + cv2.rectangle(frame, (xmin, ymin), (xmax, ymax), (10,10,200), 2) + else: + gender = 'M' + cv2.putText(frame, str(gender) + ','+str(age), (xmin, ymin - 7), cv2.FONT_HERSHEY_COMPLEX, 0.6, (10,10,200), 1) + cv2.rectangle(frame, (xmin, ymin), (xmax, ymax), (255, 10, 10), 2) + if args.raw: + print("Predicted gender, age = {},{}".format(gender, age) ) + else: + class_id = int(obj[1]) + # Draw box and label\class_id + color = (min(class_id * 12.5, 255), min(class_id * 7, 255), min(class_id * 5, 255)) + cv2.rectangle(frame, (xmin, ymin), (xmax, ymax), color, 2) + det_label = labels_map[class_id] if labels_map else str(class_id) + cv2.putText(frame, 'label' + ' ' + '#' + det_label + ': ' + str(obj[2]) ,(xmin, ymin - 7), \ + cv2.FONT_HERSHEY_COMPLEX, 0.6, (10,10,200), 1) + + if headPose_enabled: + pitch = ((hp_exec_net.requests[cur_request_id].outputs['angle_p_fc'][0][0])) + yaw = ((hp_exec_net.requests[cur_request_id].outputs['angle_y_fc'][0][0])) + roll = ((hp_exec_net.requests[cur_request_id].outputs['angle_r_fc'][0][0])) + cpoint=[int(xmin + (width/2)),int(ymin + (height/2))] + drawAxes(pitch,yaw,roll,cpoint,frame) + if args.raw: + print("Head pose results: yaw, pitch, roll = {}, {}, {}".format(yaw, pitch,roll)) + + if emotions_enabled: + emotion_values = em_exec_net.requests[cur_request_id].outputs['prob_emotion'] + emotion_type = emotion_values.argmax() + result = emotions[emotion_type] + cv2.putText(frame, ',' + result,(xmin + 40, ymin - 7), cv2.FONT_HERSHEY_COMPLEX, 0.6, (10,10,200), 1) + if args.raw: + print("Predicted emotion = {}".format(result)) + if landmarks_enabled: + if args.raw: + print("Normed Facial Landmarks coordinates (x, y):") + for i_lm in range(0,35): + normed_x= lm_exec_net.requests[0].outputs['align_fc3'][0][2*i_lm] + normed_y= lm_exec_net.requests[0].outputs['align_fc3'][0][(2*i_lm)+ 1] + x_lm = xmin + width * normed_x; + y_lm = ymin + height * normed_y; + cv2.circle(frame, (int(x_lm), int(y_lm)), 1+int(0.019 * width), (0,255,255), -1) + if args.raw: + print(normed_x, normed_y) + + render_time_message = "OpenCV cap/rendering time: {:.2f} ms".format(render_time * 1000) + inf_time_message = "Face Detection time: {:.2f} ms ({:.2f} fps)".format((det_time * 1000),1/(det_time)) + if (clippedRect.size)!= 0 and analytics_time: + Face_analytics_time_message = "Face Analytics Networks time: {:.2f} ms ({:.2f} fps)".format((analytics_time * 1000),1/(analytics_time)) + else: + Face_analytics_time_message = "Face Analytics Networks time: {:.2f} ms".format((analytics_time * 1000)) + + cv2.putText(frame, render_time_message, (15, 15), cv2.FONT_HERSHEY_COMPLEX, 0.5, (200, 10, 10), 1) + cv2.putText(frame, inf_time_message, (15, 30), cv2.FONT_HERSHEY_COMPLEX, 0.5, (200, 10, 10), 1) + if age_enabled or headPose_enabled or emotions_enabled or landmarks_enabled: + cv2.putText(frame, Face_analytics_time_message, (15,45), cv2.FONT_HERSHEY_COMPLEX, 0.5, (200, 10, 10), 1) + + # Rendering time + cv2.imshow("Detection Results", frame) + visual_end = time.time() + visual_time = visual_end - visual_start + + render_end = time.time() + render_time = decode_prev_time + decode_next_time + visual_time + elif args.raw: + if age_enabled: + age = int((age_exec_net.requests[cur_request_id].outputs['age_conv3'][0][0][0][0])*100) + if(((age_exec_net.requests[cur_request_id].outputs['prob'][0][0][0][0])) > 0.5): + gender = 'F' + else: + gender = 'M' + print("Predicted gender, age = {},{}".format(gender, age) ) + if emotions_enabled: + emotion_values = em_exec_net.requests[cur_request_id].outputs['prob_emotion'] + emotion_type = emotion_values.argmax() + result = emotions[emotion_type] + print("Predicted emotion = {}".format(result)) + if headPose_enabled: + pitch = ((hp_exec_net.requests[cur_request_id].outputs['angle_p_fc'][0][0])) + yaw = ((hp_exec_net.requests[cur_request_id].outputs['angle_y_fc'][0][0])) + roll = ((hp_exec_net.requests[cur_request_id].outputs['angle_r_fc'][0][0])) + print("Head pose results: yaw, pitch, roll = {}, {}, {}".format(yaw, pitch,roll)) + if landmarks_enabled: + print("Normed Facial Landmarks coordinates (x, y):") + for i_lm in range(0,35): + normed_x= lm_exec_net.requests[0].outputs['align_fc3'][0][2*i_lm] + normed_y= lm_exec_net.requests[0].outputs['align_fc3'][0][(2*i_lm)+ 1] + x_lm = xmin + width * normed_x; + y_lm = ymin + height * normed_y; + print(normed_x, normed_y) + + key = cv2.waitKey(1) + if key == 27: + break + total_finish = time.time() + total= total_finish - total_start + print("Total image throughput: ({:.2f} fps)".format(framesCounter*(1/total))) + # Showing performance results + if args.perf_counts: + perf_counts=exec_net.requests[0].get_perf_counts() + print("performance counts:\n") + total=0 + for layer, stats in perf_counts.items(): + total+=stats['real_time'] + print ("{:<40} {:<15} {:<10} {:<15} {:<8} {:<5} {:<5} {:<5} {:<10} {:<15}".format(layer, stats['status'], 'layerType:', stats['layer_type'], 'realTime:', stats['real_time'], 'cpu:', stats['cpu_time'],'execType:', stats['exec_type'] )) + print ("{:<20} {:<7} {:<20}".format('TotalTime:',total ,'microseconds')) + + cv2.destroyAllWindows() + log.info("Number of processed frames: {}".format(framesCounter)) + del exec_net + del plugin + log.info("Execution successful") + +if __name__ == '__main__': + sys.exit(main() or 0) diff --git a/advanced-video-analytics/security_barrier_camera.py b/advanced-video-analytics/security_barrier_camera.py new file mode 100644 index 00000000..1fbddb7f --- /dev/null +++ b/advanced-video-analytics/security_barrier_camera.py @@ -0,0 +1,268 @@ +#!/usr/bin/env python +""" + Copyright (c) 2018 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +from __future__ import print_function +import sys +import os +from argparse import ArgumentParser +import cv2 +import numpy as np +import time +import logging as log +from openvino.inference_engine import IENetwork, IEPlugin + + +def build_argparser(): + parser = ArgumentParser() + parser.add_argument("-m", "--model", help="Path to an .xml file with a trained model.", required=True, type=str) + parser.add_argument("-m_va", "--model_va", help="Path to an .xml file with a trained model.", type=str, default=None ) + parser.add_argument("-m_lpr", "--model_lpr", help="Path to an .xml file with a trained model.", default=None ,type=str ) + parser.add_argument("-i", "--input", + help="Path to video file or image. 'cam' for capturing video stream from camera", required=True, + type=str) + parser.add_argument("-l", "--cpu_extension", + help="MKLDNN (CPU)-targeted custom layers.Absolute path to a shared library with the kernels " + "impl.", type=str, default=None) + parser.add_argument("-pp", "--plugin_dir", help="Path to a plugin folder", type=str, default=None) + parser.add_argument("-d", "--device", + help="Specify the target device to infer on; CPU, GPU, FPGA or MYRIAD is acceptable. Demo " + "will look for a suitable plugin for device specified (CPU by default)", default="CPU", + type=str) + parser.add_argument("-d_va", "--device_va", + help="Specify the target device for Vehicle Attributes (CPU, GPU, FPGA, MYRIAD, or HETERO).(CPU by default)", default="CPU", + type=str) + parser.add_argument("-d_lpr", "--device_lpr", + help="Specify the target device for License Plate Recognition (CPU, GPU, FPGA, MYRIAD, or HETERO).(CPU by default)", default="CPU", + type=str) + parser.add_argument("--labels", help="Labels mapping file", default=None, type=str) + parser.add_argument("-pt", "--prob_threshold", help="Probability threshold for detections filtering", + default=0.5, type=float) + parser.add_argument("-ni", "--ni_required", help="n infer request message",default=1, type=int) + parser.add_argument("-pc", "--perf_counts", help="Report performance counters", default=False, action="store_true") + + return parser + + +colors = ["white", "gray", "yellow", "red", "green", "blue", "black"] +types = ["car", "van", "truck", "bus"] +items = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", + "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", + "U", "V", "W", "X", "Y", "Z"] +maxSequenceSizePerPlate = 88 + +def load_model(feature,model_xml,device,plugin_dirs,input_key_length,output_key_length,cpu_extension): + + model_bin = os.path.splitext(model_xml)[0] + ".bin" + + log.info("Initializing plugin for {} device...".format(device)) + plugin = IEPlugin(device, plugin_dirs) + + log.info("Loading network files for {}".format(feature)) + if cpu_extension and 'CPU' in device: + plugin.add_cpu_extension(cpu_extension) + else: + plugin.set_config({"PERF_COUNT":"YES"}) + + net = IENetwork(model=model_xml, weights=model_bin) + + if plugin.device == "CPU": + supported_layers = plugin.get_supported_layers(net) + not_supported_layers = [l for l in net.layers.keys() if l not in supported_layers] + if len(not_supported_layers) != 0: + log.error("Following layers are not supported by the plugin for specified device {}:\n {}". + format(plugin.device, ', '.join(not_supported_layers))) + log.error("Please try to specify cpu extensions library path in demo's command line parameters using -l " + "or --cpu_extension command line argument") + sys.exit(1) + + log.info("Checking {} network inputs".format(feature)) + assert len(net.inputs.keys()) == input_key_length, "Demo supports only single input topologies" + log.info("Checking {} network outputs".format(feature)) + assert len(net.outputs) == output_key_length, "Demo supports only single output topologies" + return plugin,net + + +def main(): + log.basicConfig(format="[ %(levelname)s ] %(message)s", level=log.INFO, stream=sys.stdout) + args = build_argparser().parse_args() + va_enabled=False + lpr_enabled=False + + #Vehicle Detection + plugin,net=load_model("Vehicle Detection",args.model,args.device,args.plugin_dir,1,1,args.cpu_extension) + input_blob = next(iter(net.inputs)) + out_blob = next(iter(net.outputs)) + log.info("Loading IR to the plugin...") + exec_net = plugin.load(network=net, num_requests=2) + n, c, h, w = net.inputs[input_blob].shape + del net + + #For Vehicle Attribute Detection + if args.model and args.model_va : + va_enabled=True + plugin,va_net=load_model("Vehicle Attribute Detection",args.model_va,args.device_va,args.plugin_dir,1,2,args.cpu_extension) + va_input_blob=next(iter(va_net.inputs)) + va_out_blob=next(iter(va_net.outputs)) + va_exec_net = plugin.load(network=va_net, num_requests=2) + n_va,c_va,h_va,w_va = va_net.inputs[va_input_blob].shape + del va_net + + #For License Plate Recognition + if args.model and args.model_lpr: + lpr_enabled=True + plugin,lpr_net=load_model("License Plate Recognition",args.model_lpr,args.device_lpr,args.plugin_dir,2,1,args.cpu_extension) + lpr_input_data_blob=next(iter(lpr_net.inputs)) + lpr_seqBlob=next(iter(lpr_net.inputs)) + lpr_out_blob = next(iter(lpr_net.outputs)) + lpr_seqBlob=[[0.0]] + for i in range(1,maxSequenceSizePerPlate): + lpr_seqBlob[0].append(1.0) + lpr_exec_net=plugin.load(network=lpr_net, num_requests=2) + n_lpr,c_lpr,h_lpr,w_lpr =lpr_net.inputs['data'].shape + del lpr_net + + + if args.input == 'cam': + input_stream = 0 + else: + input_stream = args.input + assert os.path.isfile(args.input), "Specified input file doesn't exist" + if args.labels: + with open(args.labels, 'r') as f: + labels_map = [x.strip() for x in f] + else: + labels_map = None + + log.info("Starting inference ...") + log.info("To stop the demo execution press Esc button") + render_time = 0 + lpr_det_time=0 + va_det_time=0 + framecount=0 + + while True: + img=cv2.imread(input_stream) + initial_w = img.shape[1] + initial_h = img.shape[0] + framecount+=1 + inf_start = time.time() + + in_frame = cv2.resize(img, (w, h)) + in_frame = in_frame.transpose((2, 0, 1)) # Change data layout from HWC to CHW + in_frame = in_frame.reshape((n, c, h, w)) + exec_net.start_async(request_id=0, inputs={input_blob: in_frame}) + infer_status = exec_net.requests[0].wait() + if infer_status == 0: + inf_end = time.time() + det_time = inf_end - inf_start + + # Parse detection results of the current request + res = exec_net.requests[0].outputs[out_blob] + + for obj in res[0][0]: + # Draw only objects when probability more than specified threshold + if obj[2] > args.prob_threshold: + xmin = int(obj[3] * initial_w) + ymin = int(obj[4] * initial_h) + xmax = int(obj[5] * initial_w) + ymax = int(obj[6] * initial_h) + class_id = int(obj[1]) + + # Draw box and label\class_id + color = (min(class_id * 12.5, 255), min(class_id * 7, 255), min(class_id * 5, 255)) + cv2.rectangle(img, (xmin, ymin), (xmax, ymax), (0,255,0), 2) + clippedRect=img[ymin:ymax, xmin:xmax] + det_label = labels_map[class_id] if labels_map else str(class_id) + # For vehicle attribute recognition + if det_label == '1' and va_enabled: + va_inf_start = time.time() + in_frame = cv2.resize(clippedRect, (w_va, h_va)) + in_frame = in_frame.transpose((2, 0, 1)) # Change data layout from HWC to CHW + in_frame = in_frame.reshape((n_va, c_va, h_va, w_va)) + va_exec_net.start_async(request_id=0, inputs={va_input_blob: in_frame}) + va_infer_status= va_exec_net.requests[0].wait() + va_inf_end = time.time() + va_det_time=va_inf_end-va_inf_start + colorsValues= va_exec_net.requests[0].outputs['color'] + typesValues= va_exec_net.requests[0].outputs['type'] + color_id=colorsValues.argmax() + type_id=typesValues.argmax() + cv2.putText(img, colors[color_id] , (xmin+2, ymin +15),cv2.FONT_HERSHEY_COMPLEX, 0.6, (255,0,0), 1, cv2.LINE_AA) + cv2.putText(img, types[type_id] , (xmin+2, ymin+30),cv2.FONT_HERSHEY_COMPLEX, 0.6, (255,0,0), 1, cv2.LINE_AA) + #For lpr recognition + elif det_label == '2' and lpr_enabled: + lpr_inf_start = time.time() + in_frame=cv2.resize(clippedRect,(w_lpr,h_lpr)) + in_frame = in_frame.transpose((2, 0, 1)) # Change data layout from HWC to CHW + in_frame = in_frame.reshape((n_lpr, c_lpr, h_lpr, w_lpr)) + lpr_exec_net.start_async(request_id=0, inputs={'data': in_frame, 'seq_ind': (lpr_seqBlob[0][1])}) + status=lpr_exec_net.requests[0].wait(-1) + lpr_inf_end = time.time() + lpr_det_time = lpr_inf_end - lpr_inf_start + lpr_res=lpr_exec_net.requests[0].outputs[lpr_out_blob] + result="" + for i in range(0,lpr_res.size): + if lpr_res[0][i] != -1: + result+=items[int(lpr_res[0][i])] + else: + cv2.putText(img, result , (xmin, ymin +50),cv2.FONT_HERSHEY_COMPLEX, 0.6, (0,0,255), 1, cv2.LINE_AA) + break + + #Inference Statistics + inf_time_message = "Time for processing 1 stream (nireq ={}): {:.3f} ms ({} fps)".format(args.ni_required,(det_time * 1000),int(1/det_time)) + render_time_message = "Rendering time ({}): {:.3f} ms".format(args.device,render_time * 1000) + vehicle_detection_time="Vehicle detection time ({}) : {:.3f} ms ({} fps)".format(args.device,(det_time*1000),int(1/(det_time)/framecount)) + if va_det_time : + vehicle_attrib_time_message="Vehicle Attribs time({}) : {:.3f} ms ({} fps)".format(args.device_va,(va_det_time*1000),int(1/(va_det_time)/framecount)) + cv2.putText(img, vehicle_attrib_time_message, (0, 60), cv2.FONT_HERSHEY_COMPLEX, 0.5, (200, 10, 10), 1) + if lpr_det_time : + lpr_time_message="Lpr recognition time({}) : {:.2f} ms ({} fps)".format(args.device_lpr,(lpr_det_time*1000),int(1/(lpr_det_time)/framecount)) + cv2.putText(img, lpr_time_message, (0, 80), cv2.FONT_HERSHEY_COMPLEX, 0.5, (200, 10, 10), 1) + cv2.putText(img, inf_time_message, (0, 20), cv2.FONT_HERSHEY_COMPLEX, 0.5, (200, 10, 10), 1,cv2.LINE_AA) + cv2.putText(img, vehicle_detection_time, (0, 40), cv2.FONT_HERSHEY_COMPLEX, 0.5, (200, 10, 10), 1,cv2.LINE_AA) + + cv2.imshow("Detection Results", img) + + + key = cv2.waitKey(0) + if key == 27: + break + if args.perf_counts: + perf_counts=exec_net.requests[0].get_perf_counts() + print("performance counts:\n") + total=0 + for layer, stats in perf_counts.items(): + total+=stats['real_time'] + print ("{:<40} {:<15} {:<10} {:<15} {:<8} {:<5} {:<5} {:<5} {:<10} {:<15}".format(layer, stats['status'], 'layerType:', stats['layer_type'], 'realTime:', stats['real_time'], 'cpu:', stats['cpu_time'],'execType:', stats['exec_type'] )) + print ("{:<20} {:<7} {:<20}".format('TotalTime:',total ,'microseconds')) + log.info("Execution successful") + + del exec_net + del plugin + cv2.destroyAllWindows() +if __name__ == '__main__': + sys.exit(main() or 0) diff --git a/hardware-heterogeneity/classification_sample.py b/hardware-heterogeneity/classification_sample.py new file mode 100644 index 00000000..b9052b50 --- /dev/null +++ b/hardware-heterogeneity/classification_sample.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python +""" + Copyright (c) 2018 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" +from __future__ import print_function +import sys +import os +from argparse import ArgumentParser +import cv2 +import numpy as np +import logging as log +from time import time +from openvino.inference_engine import IENetwork, IEPlugin + + +def build_argparser(): + parser = ArgumentParser() + parser.add_argument("-m", "--model", help="Path to an .xml file with a trained model.", required=True, type=str) + parser.add_argument("-i", "--input", help="Path to a folder with images or path to an image files", required=True, + type=str, nargs="+") + parser.add_argument("-l", "--cpu_extension", + help="MKLDNN (CPU)-targeted custom layers.Absolute path to a shared library with the kernels " + "impl.", type=str, default=None) + parser.add_argument("-pp", "--plugin_dir", help="Path to a plugin folder", type=str, default=None) + parser.add_argument("-d", "--device", + help="Specify the target device to infer on; CPU, GPU, FPGA or MYRIAD is acceptable. Sample " + "will look for a suitable plugin for device specified (CPU by default)", default="CPU", + type=str) + parser.add_argument("--labels", help="Labels mapping file", default=None, type=str) + parser.add_argument("-nt", "--number_top", help="Number of top results", default=10, type=int) + parser.add_argument("-ni", "--number_iter", help="Number of inference iterations", default=1, type=int) + parser.add_argument("-pc", "--perf_counts", help="Report performance counters", default=False, action="store_true") + + return parser + + +def main(): + log.basicConfig(format="[ %(levelname)s ] %(message)s", level=log.INFO, stream=sys.stdout) + args = build_argparser().parse_args() + model_xml = args.model + model_bin = os.path.splitext(model_xml)[0] + ".bin" + + + # Plugin initialization for specified device and load extensions library if specified + plugin = IEPlugin(device=args.device, plugin_dirs=args.plugin_dir) + if args.cpu_extension and 'CPU' in args.device: + plugin.add_cpu_extension(args.cpu_extension) + else: + plugin.set_config({"PERF_COUNT":"YES"}) + # Read IR + log.info("Loading network files:\n\t{}\n\t{}".format(model_xml, model_bin)) + net = IENetwork(model=model_xml, weights=model_bin) + + if plugin.device == "CPU": + supported_layers = plugin.get_supported_layers(net) + not_supported_layers = [l for l in net.layers.keys() if l not in supported_layers] + if len(not_supported_layers) != 0: + log.error("Following layers are not supported by the plugin for specified device {}:\n {}". + format(plugin.device, ', '.join(not_supported_layers))) + log.error("Please try to specify cpu extensions library path in sample's command line parameters using -l " + "or --cpu_extension command line argument") + sys.exit(1) + + assert len(net.inputs.keys()) == 1, "Sample supports only single input topologies" + assert len(net.outputs) == 1, "Sample supports only single output topologies" + + log.info("Preparing input blobs") + input_blob = next(iter(net.inputs)) + out_blob = next(iter(net.outputs)) + net.batch_size = len(args.input) + + # Read and pre-process input images + n, c, h, w = net.inputs[input_blob].shape + images = np.ndarray(shape=(n, c, h, w)) + for i in range(n): + image = cv2.imread(args.input[i]) + if image.shape[:-1] != (h, w): + log.warning("Image {} is resized from {} to {}".format(args.input[i], image.shape[:-1], (h, w))) + image = cv2.resize(image, (w, h)) + image = image.transpose((2, 0, 1)) # Change data layout from HWC to CHW + images[i] = image + log.info("Batch size is {}".format(n)) + + # Loading model to the plugin + log.info("Loading model to the plugin") + exec_net = plugin.load(network=net,num_requests=2) + + del net + # Start sync inference + log.info("Starting inference ({} iterations)".format(args.number_iter)) + infer_time = [] + for i in range(args.number_iter): + t0 = time() + res = exec_net.infer(inputs={input_blob: images}) + infer_time.append((time()-t0)*1000) + # Processing output blob + log.info("Processing output blob") + res = res[out_blob] + log.info("Top {} results: ".format(args.number_top)) + if args.labels: + with open(args.labels, 'r') as f: + labels_map = [x.split(sep=' ', maxsplit=0)[-1].strip() for x in f] + else: + labels_map = None + for i, probs in enumerate(res): + probs = np.squeeze(probs) + top_ind = np.argsort(probs)[-args.number_top:][::-1] + for id in top_ind: + det_label = labels_map[id] if labels_map else "#{}".format(id) + + print("{:<5}{:.7f} label {}".format(id,probs[id], det_label)) + print("\n") + total_inference=np.sum(np.asarray(infer_time)) + log.info("Average running time of one iteration: {:.2f} ms".format(np.average(np.asarray(infer_time)))) + log.info("total running time of inference: {:.2f} ms" .format(total_inference)) + log.info("Throughput: {:.2f} FPS".format((1000*args.number_iter*n)/total_inference)) + print("\n") + + #printing performance counts + + if args.perf_counts: + perf_counts=exec_net.requests[0].get_perf_counts() + print("performance counts:\n") + total=0 + for layer, stats in perf_counts.items(): + total+=stats['real_time'] + print ("{:<40} {:<15} {:<10} {:<15} {:<8} {:<5} {:<5} {:<5} {:<10} {:<15}".format(layer, stats['status'], 'layerType:', stats['layer_type'], 'realTime:', stats['real_time'], 'cpu:', stats['cpu_time'],'execType:', stats['exec_type'] )) + print ("{:<20} {:<7} {:<20}".format('TotalTime:',total ,'microseconds')) + log.info("Execution successful") + + + del exec_net + del plugin + + +if __name__ == '__main__': + sys.exit(main() or 0) diff --git a/object-detection/ROIviewer.py b/object-detection/ROIviewer.py new file mode 100644 index 00000000..afa3e180 --- /dev/null +++ b/object-detection/ROIviewer.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python +""" + Copyright (c) 2018 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +import sys +import os +from argparse import ArgumentParser +import cv2 +import logging as log +import struct +import collections + + + +def build_argparser(): + parser = ArgumentParser() + parser.add_argument("-i", "--input", + help="Path to video file or image. 'cam' for capturing video stream from camera", required=True, + type=str) + parser.add_argument("-l", "--labels", help="Labels mapping file", required=True, type=str) + parser.add_argument("--ROIfile",help="Path to ROI file.",default="ROIs.txt",type=str) + parser.add_argument("-b", help="Batch size", default=0, type=int) + + return parser + +class ROI_data_type: + framenum="" + labelnum="" + confidence="" + xmin="" + ymin="" + xmax="" + ymax="" + +def main(): + log.basicConfig(format="[ %(levelname)s ] %(message)s", level=log.INFO, stream=sys.stdout) + args = build_argparser().parse_args() + batch=args.b + ROIs = collections.deque() + assert os.path.isfile(args.ROIfile), "Specified ROIs.txt file doesn't exist" + + fin=open("ROIs.txt",'r') + for l in fin: + R=ROI_data_type() + batchnum,R.framenum,R.labelnum,R.confidence,R.xmin,R.ymin,R.xmax,R.ymax=l.split() + if int(batchnum)==batch: + ROIs.append(R) + + if args.input == 'cam': + input_stream = 0 + else: + input_stream = args.input + assert os.path.isfile(args.input), "Specified input file doesn't exist" + + print("opening", args.input," batchnum ",args.b,"\n") + + cap = cv2.VideoCapture(input_stream) + if not cap.isOpened(): + print("could not open input video file") + framenum=0 + if len(ROIs)>1: + R=ROIs[0] + else: + print("empty ROI file"); + if args.labels: + with open(args.labels, 'r') as f: + labels_map = [x.strip() for x in f] + else: + labels_map = None + + while True: + ret, frame = cap.read() + if not ret: + break + ncols=cap.get(3) + nrows=cap.get(4) + while int(R.framenum)1: + ROIs.popleft() + R=ROIs[0]; + else: + break + while int(R.framenum)==framenum: + xmin = int(float(R.xmin) * float(ncols)) + ymin = int(float(R.ymin) * float(nrows)) + xmax = int(float(R.xmax) * float(ncols)) + ymax = int(float(R.ymax) * float(nrows)) + + class_id=int(float(R.labelnum)+1) + cv2.rectangle(frame, (xmin, ymin), (xmax, ymax), (0, 255, 0),4,16,0) + + if len(labels_map)==0: + templabel=int(float(R.labelnum))+":"+int(R.confidence*100.0) + print(templabel) + else: + templabel=str(labels_map[int(float(R.labelnum))])+":"+str(int(float(R.confidence)*100.0)) + + cv2.rectangle(frame, (xmin, ymin+32), (xmax, ymin), (155, 155, 155),-1,0) + cv2.putText(frame, templabel, (xmin, ymin+24), cv2.FONT_HERSHEY_COMPLEX, 1.1, (0, 0, 0),3) + + if len(ROIs)>1: + ROIs.popleft() + R=ROIs[0] + else: + break + + cv2.imshow("Detection Results", frame) + if cv2.waitKey(30)>=0: + break + if len(ROIs)<=1: + break + framenum+=1 + +main() diff --git a/object-detection/tutorial1.py b/object-detection/tutorial1.py new file mode 100644 index 00000000..e4c20d89 --- /dev/null +++ b/object-detection/tutorial1.py @@ -0,0 +1,223 @@ +#!/usr/bin/env python +""" + Copyright (c) 2018 Intel Corporation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +from __future__ import print_function +import sys +import os +from argparse import ArgumentParser +import cv2 +import time +import logging as log +from openvino.inference_engine import IENetwork, IEPlugin +from enum import Enum +import collections + + + +class output_mode_type(Enum): + CLASSIFICATION_MODE=1 + SSD_MODE=2 + + +def build_argparser(): + parser = ArgumentParser() + parser.add_argument("-m", "--model", help="Path to an .xml file with a trained model.", required=True, type=str) + parser.add_argument("-i", "--input", + help="Path to video file or image. 'cam' for capturing video stream from camera", required=True, + type=str) + parser.add_argument("-l", "--cpu_extension", + help="MKLDNN (CPU)-targeted custom layers.Absolute path to a shared library with the kernels " + "impl.", type=str, default=None) + parser.add_argument("-pp", "--plugin_dir", help="Path to a plugin folder", type=str, default=None) + parser.add_argument("-d", "--device", + help="Specify the target device to infer on; CPU, GPU, FPGA or MYRIAD is acceptable. Demo " + "will look for a suitable plugin for device specified (CPU by default)", default="CPU", + type=str) + parser.add_argument("--labels", help="Labels mapping file", default=None, type=str) + parser.add_argument("-pt", "--prob_threshold", help="Probability threshold for detections filtering", + default=0.5, type=float) + parser.add_argument("-fr", help="maximum frames to process", default=256, type=int) + parser.add_argument("-b", help="Batch size", default=1, type=int) + + return parser + + +def main(): + log.basicConfig(format="[ %(levelname)s ] %(message)s", level=log.INFO, stream=sys.stdout) + args = build_argparser().parse_args() + model_xml = args.model + model_bin = os.path.splitext(model_xml)[0] + ".bin" + + preprocess_times = collections.deque() + infer_times = collections.deque() + postprocess_times = collections.deque() + + ROIfile=open("ROIs.txt","w"); # output stored here, view with ROIviewer + + # Plugin initialization for specified device and load extensions library if specified + log.info("Initializing plugin for {} device...".format(args.device)) + plugin = IEPlugin(device=args.device, plugin_dirs=args.plugin_dir) + if args.cpu_extension and 'CPU' in args.device: + plugin.add_cpu_extension(args.cpu_extension) + + + # Read IR + log.info("Reading IR...") + net = IENetwork(model=model_xml, weights=model_bin) + + if plugin.device == "CPU": + supported_layers = plugin.get_supported_layers(net) + not_supported_layers = [l for l in net.layers.keys() if l not in supported_layers] + if len(not_supported_layers) != 0: + log.error("Following layers are not supported by the plugin for specified device {}:\n {}". + format(plugin.device, ', '.join(not_supported_layers))) + log.error("Please try to specify cpu extensions library path in demo's command line parameters using -l " + "or --cpu_extension command line argument") + sys.exit(1) + + #Set Batch Size + batchSize = args.b + frameLimit = args.fr + assert len(net.inputs.keys()) == 1, "Demo supports only single input topologies" + assert len(net.outputs) == 1, "Demo supports only single output topologies" + input_blob = next(iter(net.inputs)) + out_blob = next(iter(net.outputs)) + log.info("Loading IR to the plugin...") + exec_net = plugin.load(network=net, num_requests=2) + + # Read and pre-process input image + n, c, h, w = net.inputs[input_blob].shape + output_dims=net.outputs[out_blob].shape + infer_width=w; + infer_height=h; + num_channels=c; + channel_size=infer_width*infer_height + full_image_size=channel_size*num_channels + + print("inputdims=",w,h,c,n) + print("outputdims=",output_dims[3],output_dims[2],output_dims[1],output_dims[0]) + if int(output_dims[3])>1 : + print("SSD Mode") + output_mode=output_mode_type.SSD_MODE + else: + print("Single Classification Mode") + output_mode=CLASSIFICATION_MODE + output_data_size=int(output_dims[2])*int(output_dims[1])*int(output_dims[0]) + del net + if args.input == 'cam': + input_stream = 0 + else: + input_stream = args.input + assert os.path.isfile(args.input), "Specified input file doesn't exist" + if args.labels: + with open(args.labels, 'r') as f: + labels_map = [x.strip() for x in f] + else: + labels_map = None + + cap = cv2.VideoCapture(input_stream) + + cur_request_id = 0 + next_request_id = 1 + + log.info("Starting inference in async mode...") + is_async_mode = True + render_time = 0 + + framenum = 0 + process_more_frames=True + frames_in_output=batchSize + + while process_more_frames: + time1 = time.time() + for mb in range(0 , batchSize): + ret, frame = cap.read() + if not ret or (framenum >= frameLimit): + process_more_frames=False + frames_in_output=mb + break + + # convert image to blob + # Fill input tensor with planes. First b channel, then g and r channels + in_frame = cv2.resize(frame, (w, h)) + in_frame = in_frame.transpose((2, 0, 1)) # Change data layout from HWC to CHW + in_frame = in_frame.reshape((n, c, h, w)) + + time2 = time.time() + diffPreProcess = time2 - time1 + if process_more_frames: + preprocess_times.append(diffPreProcess*1000) + + # Main sync point: + # in the truly Async mode we start the NEXT infer request, while waiting for the CURRENT to complete + # in the regular mode we start the CURRENT request and immediately wait for it's completion + inf_start = time.time() + if is_async_mode: + exec_net.start_async(request_id=next_request_id, inputs={input_blob: in_frame}) + else: + exec_net.start_async(request_id=cur_request_id, inputs={input_blob: in_frame}) + if exec_net.requests[cur_request_id].wait(-1) == 0: + inf_end = time.time() + det_time = inf_end - inf_start + infer_times.append(det_time*1000) + time1 = time.time() + + # Parse detection results of the current request + res = exec_net.requests[cur_request_id].outputs[out_blob] + for obj in res[0][0]: + # Write into ROIs.txt only objects when probability more than specified threshold + if obj[2] > args.prob_threshold: + confidence=obj[2] + locallabel = obj[1] - 1 + print(str(0),str(framenum),str(locallabel),str(confidence),str(obj[3]),str(obj[4]),str(obj[5]),str(obj[6]), file=ROIfile) + + + sys.stdout.write("\rframenum:"+str(framenum)) + sys.stdout.flush() + render_start = time.time() + framenum = framenum+1 + time2 = time.time() + diffPostProcess = time2 - time1 + postprocess_times.append(diffPostProcess*1000) + + if is_async_mode: + cur_request_id, next_request_id = next_request_id, cur_request_id + + + print("\n") + preprocesstime=0 + inferencetime=0 + postprocesstime=0 + + for obj in preprocess_times: + preprocesstime+=obj + for obj in infer_times: + inferencetime+=obj + for obj in postprocess_times: + postprocesstime+=obj + + + print("Preprocess: ",preprocesstime/(len(preprocess_times)*batchSize),"\tms/frame") + print("Inference: ",inferencetime/(len(infer_times)*batchSize),"\tms/frame") + print("Postprocess:" ,postprocesstime/(len(postprocess_times)*batchSize),"\tms/frame") + + del exec_net + del plugin + + +if __name__ == '__main__': + sys.exit(main() or 0)