def print_usage(): """Prints usage information for the program. :return: None """ labels = SsdMobileNetProcessor.get_classification_labels() print('\nusage: ') print('python3 run_video.py [help][resize_window=<width>x<height>]') print('') print('options:') print(' help - prints this message') print(' resize_window - resizes the GUI window to specified dimensions') print(' must be formated similar to resize_window=1280x720') print(' Default isto not resize, use size of video frames.') print(' init_min_score - set the minimum score for a box to be recognized') print(' must be a number between 0 and 100 inclusive.') print(' Default is: ' + str(DEFAULT_INIT_MIN_SCORE)) print(' exclude_classes - comma separated list of object class IDs to exclude from following:') index = 0 for oneLabel in labels: print(" class ID " + str(index) + ": " + oneLabel) index += 1 print(' must be a number between 0 and ' + str(len(labels)-1) + ' inclusive.') print(' Default is to exclude none.') print('') print('Example: ') print('python3 run_video.py resize_window=1920x1080 init_min_score=50 exclude_classes=5,11')
def handle_keys(raw_key: int, obj_detector_proc: SsdMobileNetProcessor): """Handles key presses by adjusting global thresholds etc. :param raw_key: is the return value from cv2.waitkey :param obj_detector_proc: the object detector in use. :return: False if program should end, or True if should continue """ global min_score_percent ascii_code = raw_key & 0xFF if ((ascii_code == ord('q')) or (ascii_code == ord('Q'))): return False elif (ascii_code == ord('B')): min_score_percent = obj_detector_proc.get_box_probability_threshold( ) * 100.0 + 5 if (min_score_percent > 100.0): min_score_percent = 100.0 obj_detector_proc.set_box_probability_threshold(min_score_percent / 100.0) print('New minimum box percentage: ' + str(min_score_percent) + '%') elif (ascii_code == ord('b')): min_score_percent = obj_detector_proc.get_box_probability_threshold( ) * 100.0 - 5 if (min_score_percent < 0.0): min_score_percent = 0.0 obj_detector_proc.set_box_probability_threshold(min_score_percent / 100.0) print('New minimum box percentage: ' + str(min_score_percent) + '%') return True
def main(): """Main function for the program. Everything starts here. :return: None """ global resize_output, resize_output_width, resize_output_height, \ obj_detector_proc, resize_output, resize_output_width, resize_output_height, video_proc, \ last_num_persons, asyncImWriter if (not handle_args()): print_usage() return 1 # Set logging level to only log errors mvnc.global_set_option(mvnc.GlobalOption.RW_LOG_LEVEL, 3) devices = mvnc.enumerate_devices() if len(devices) < 1: print('No NCS device detected.') print('Insert device and try again!') return 1 # Pick the first stick to run the network # use the first NCS device that opens for the object detection. dev_count = 0 for one_device in devices: try: obj_detect_dev = mvnc.Device(one_device) obj_detect_dev.open() print("opened device " + str(dev_count)) break except: print("Could not open device " + str(dev_count) + ", trying next device") pass dev_count += 1 cv2.namedWindow(cv_window_name) cv2.moveWindow(cv_window_name, 10, 10) cv2.waitKey(1) obj_detector_proc = SsdMobileNetProcessor( NETWORK_GRAPH_FILENAME, obj_detect_dev, inital_box_prob_thresh=min_score_percent / 100.0, classification_mask=object_classifications_mask) exit_app = False while (True): # video processor that will put video frames images on the object detector's input FIFO queue video_proc = CameraProcessor(CAMERA_INDEX, 1920, 1080, network_processor=obj_detector_proc) video_proc.start_processing() frame_count = 0 start_time = time.time() end_time = start_time while (True): try: (filtered_objs, display_image ) = obj_detector_proc.get_async_inference_result() except: print("exception caught in main") raise # check if the window is visible, this means the user hasn't closed # the window via the X button prop_val = cv2.getWindowProperty(cv_window_name, cv2.WND_PROP_ASPECT_RATIO) if (prop_val < 0.0): end_time = time.time() video_proc.stop_processing() exit_app = True break agg_results = overlay_on_image(display_image, filtered_objs) num_persons = len(agg_results) if (show_output): if (resize_output): display_image = cv2.resize( display_image, (resize_output_width, resize_output_height), cv2.INTER_LINEAR) cv2.imshow(cv_window_name, display_image) raw_key = cv2.waitKey(1) if (raw_key != -1): if (handle_keys(raw_key, obj_detector_proc) == False): end_time = time.time() exit_app = True video_proc.stop_processing() break frame_count += 1 # if (obj_detector_proc.is_input_queue_empty()): # end_time = time.time() # print('Neural Network Processor has nothing to process, assuming video is finished.') # break frames_per_second = frame_count / (end_time - start_time) print('Frames per Second: ' + str(frames_per_second)) throttling = obj_detect_dev.get_option( mvnc.DeviceOption.RO_THERMAL_THROTTLING_LEVEL) if (throttling > 0): print("\nDevice is throttling, level is: " + str(throttling)) print("Sleeping for a few seconds....") cv2.waitKey(2000) #video_proc.stop_processing() cv2.waitKey(1) if (exit_app): video_proc.cleanup() break # Clean up the graph and the device obj_detector_proc.cleanup() obj_detect_dev.close() obj_detect_dev.destroy() cv2.destroyAllWindows()
def handle_args(): """Reads the commandline args and adjusts initial values of globals values to match :return: False if there was an error with the args, or True if args processed ok. """ global resize_output, resize_output_width, resize_output_height, min_score_percent, object_classifications_mask labels = SsdMobileNetProcessor.get_classification_labels() for an_arg in argv: if (an_arg == argv[0]): continue elif (str(an_arg).lower() == 'help'): return False elif (str(an_arg).lower().startswith('exclude_classes=')): try: arg, val = str(an_arg).split('=', 1) exclude_list = str(val).split(',') for exclude_id_str in exclude_list: exclude_id = int(exclude_id_str) if (exclude_id < 0 or exclude_id > len(labels)): print("invalid exclude_classes= parameter") return False print("Excluding class ID " + str(exclude_id) + " : " + labels[exclude_id]) object_classifications_mask[int(exclude_id)] = 0 except: print('Error with exclude_classes argument. ') return False elif (str(an_arg).lower().startswith('init_min_score=')): try: arg, val = str(an_arg).split('=', 1) init_min_score_str = val init_min_score = int(init_min_score_str) if (init_min_score < 0 or init_min_score > 100): print( 'Error with init_min_score argument. It must be between 0-100' ) return False min_score_percent = init_min_score print('Initial Minimum Score: ' + str(min_score_percent) + ' %') except: print( 'Error with init_min_score argument. It must be between 0-100' ) return False elif (str(an_arg).lower().startswith('resize_window=')): try: arg, val = str(an_arg).split('=', 1) width_height = str(val).split('x', 1) resize_output_width = int(width_height[0]) resize_output_height = int(width_height[1]) resize_output = True print('GUI window resize now on: \n width = ' + str(resize_output_width) + '\n height = ' + str(resize_output_height)) except: print('Error with resize_window argument: "' + an_arg + '"') return False else: return False return True
def main(): """Main function for the program. Everything starts here. :return: None """ global resize_output, resize_output_width, resize_output_height, \ resize_output, resize_output_width, resize_output_height, \ device_count if (not handle_args()): print_usage() return 1 # get list of all the .mp4 files in the image directory input_video_filename_list = os.listdir(input_video_path) input_video_filename_list = [ i for i in input_video_filename_list if i.endswith('.mp4') ] if (len(input_video_filename_list) < 1): # no images to show print('No video (.mp4) files found') return 1 resting_image = cv2.imread("resting_image.png") if (resting_image is None): resting_image = numpy.zeros((800, 600, 3), numpy.uint8) if (resize_output): resting_image = cv2.resize(resting_image, (resize_output_width, resize_output_height), cv2.INTER_LINEAR) # Set logging level to only log errors mvnc.global_set_option(mvnc.GlobalOption.RW_LOG_LEVEL, 3) devices = mvnc.enumerate_devices() if len(devices) < 1: print('No NCS device detected.') print('Insert device and try again!') return 1 if (device_count < 1) or (device_count > len(devices)): device_count = len(devices) # Create an object detector processor for each device that opens # and store it in our list of processors obj_detect_list = list() idle_obj_detect_list = list() device_number = 0 for one_device in devices: try: obj_detect_dev = mvnc.Device(one_device) obj_detect_dev.open() print("opened device " + str(device_number)) obj_detector_proc = SsdMobileNetProcessor( NETWORK_GRAPH_FILENAME, obj_detect_dev, inital_box_prob_thresh=min_score_percent / 100.0, classification_mask=object_classifications_mask, name="object detector " + str(device_number)) if (device_number < device_count): obj_detect_list.append(obj_detector_proc) else: idle_obj_detect_list.append(obj_detector_proc) device_number += 1 except: print("Could not open device " + str(device_number) + ", trying next device") pass if len(obj_detect_list) < 1: print('Could not open any NCS devices.') print('Reinsert devices and try again!') return 1 print("Using " + str(len(obj_detect_list)) + " devices for object detection") print_hot_keys() cv2.namedWindow(cv_window_name) cv2.moveWindow(cv_window_name, 10, 10) cv2.waitKey(1) exit_app = False while (True): for input_video_file in input_video_filename_list: for one_obj_detect_proc in obj_detect_list: print("using object detector: " + one_obj_detect_proc.get_name()) one_obj_detect_proc.drain_queues() # video processor that will put video frames images on the object detector's input FIFO queue video_proc = VideoProcessor(input_video_path + '/' + input_video_file, network_processor_list=obj_detect_list) video_proc.start_processing() frame_count = 0 start_time = time.time() last_throttle_time = start_time end_time = start_time while (True): done = False for one_obj_detect_proc in obj_detect_list: try: (filtered_objs, display_image ) = one_obj_detect_proc.get_async_inference_result() except: print("exception caught in main") raise # check if the window is visible, this means the user hasn't closed # the window via the X button prop_val = cv2.getWindowProperty(cv_window_name, cv2.WND_PROP_ASPECT_RATIO) if (prop_val < 0.0): end_time = time.time() video_proc.stop_processing() video_proc.cleanup() exit_app = True break running_fps = frame_count / (time.time() - start_time) overlay_on_image(display_image, filtered_objs, running_fps) if (resize_output): display_image = cv2.resize( display_image, (resize_output_width, resize_output_height), cv2.INTER_LINEAR) cv2.imshow(cv_window_name, display_image) raw_key = cv2.waitKey(1) if (raw_key != -1): if (handle_keys(raw_key, obj_detect_list) == False): end_time = time.time() exit_app = True done = True break frame_count += 1 #if (one_obj_detect_proc.is_input_queue_empty()): if (not video_proc.is_processing()): # asssume the video is over. end_time = time.time() done = True print( 'video processor not processing, assuming video is finished.' ) break #if (frame_count % 100) == 0: if ((time.time() - last_throttle_time) > throttle_check_seconds): #long movie, check for throttling devices # throttling = one_obj_detect_proc.get_device().get_option(mvnc.DeviceOption.RO_THERMAL_THROTTLING_LEVEL) last_throttle_time = time.time() print( "movie not done, but going a long time so adjust for throttling" ) video_proc.pause() do_throttle_adjustment(obj_detect_list, idle_obj_detect_list) video_proc.unpause() if (done): break frames_per_second = frame_count / (end_time - start_time) print('Frames per Second: ' + str(frames_per_second)) # check for throttling devices and save in throttling list throttling_list = list() for one_obj_detect_proc in obj_detect_list: throttling = one_obj_detect_proc.get_device().get_option( mvnc.DeviceOption.RO_THERMAL_THROTTLING_LEVEL) if (throttling > 0): print("\nDevice " + one_obj_detect_proc.get_name() + " is throttling, level is: " + str(throttling)) throttling_list.append(one_obj_detect_proc) if (not exit_app): # rest between movies, display an image while resting resting_display_image = cv2.resize( resting_image, (display_image.shape[1], display_image.shape[0]), cv2.INTER_LINEAR) cv2.imshow(cv_window_name, resting_display_image) if ((len(throttling_list) > len(idle_obj_detect_list))): # more devices throttling than we have in the idle list # so do extra rest by applying a multiplier to the rest time print("throttling devices... resting") cv2.waitKey(rest_seconds * 1000 * rest_throttling_multiplier) else: cv2.waitKey(rest_seconds * 1000) # remove the throttling devices from the main list and put them at the end so they will # be moved to the idle list with priority for one_throttling in throttling_list: obj_detect_list.remove(one_throttling) obj_detect_list.append(one_throttling) num_idle = len(idle_obj_detect_list) if (num_idle > len(obj_detect_list)): num_idle = len(obj_detect_list) if (num_idle > 0): # replace one of the devices with an idle device for idle_index in range(0, num_idle): #for one_idle_proc in idle_obj_detect_list: obj_detect_list.insert(0, idle_obj_detect_list.pop(0)) for idle_count in range(0, num_idle): idle_obj_detect_list.append(obj_detect_list.pop()) video_proc.stop_processing() video_proc.cleanup() if (exit_app): break if (exit_app): break # Clean up the graph and the device for one_obj_detect_proc in obj_detect_list: cv2.waitKey(1) one_obj_detect_proc.cleanup(True) cv2.destroyAllWindows()
def print_usage(): """Prints usage information for the program. :return: None """ labels = SsdMobileNetProcessor.get_classification_labels() print('\nusage: ') print('python3 run_video.py [help][resize_window=<width>x<height>]') print('') print('options:') print(' help - Prints this message') print(' resize_window - Resizes the GUI window to specified dimensions') print( ' must be formated similar to resize_window=1280x720') print( ' Default isto not resize, use size of video frames.') print( ' init_min_score - Set the minimum score for a box to be recognized') print(' must be a number between 0 and 100 inclusive.') print(' Default is: ' + str(DEFAULT_INIT_MIN_SCORE)) print( " show_fps - Show or do not show the Frames Per Second while running") print(" must be 'True' or 'False'.") print(" Default is: " + str(DEFAULT_SHOW_FPS)) print( " device_count - The number of devices to use for inferencing. If there are " ) print( " more devices in the system than specified here then the extra" ) print( " devices will by cycled in and out of use, but no more than" ) print( " this many devices will be used at a time. Must be between 1 and " ) print(" the total number of devices in the system.") print(" Default is to use all devices in the system. ") print( " show_device_count - Show or do not show the number of devices in use while running" ) print(" must be 'True' or 'False'.") print(" Default is: " + str(DEFAULT_SHOW_NCS_COUNT)) print(" rest_seconds - The number of seconds to wait between movies ") print( " when devices are throttling a multiplier will be applied." ) print(" This must be a positive integer.") print(" Default is: " + str(DEFAULT_REST_SECONDS)) print( " throttle_check_seconds - The number of seconds between throttle checking during long movies " ) print(" This must be a positive integer.") print(" Default is: " + str(DEFAULT_THROTTLE_CHECK_SECONDS)) print( ' exclude_classes - Comma separated list of object class IDs to exclude from following:' ) index = 0 for oneLabel in labels: print(" class ID " + str(index) + ": " + oneLabel) index += 1 print(' must be a number between 0 and ' + str(len(labels) - 1) + ' inclusive.') print(' Default is to exclude none.') print('') print('Example: ') print( 'python3 video_objects_scalable.py resize_window=1920x1080 init_min_score=50 show_fps=False device_count=2 show_device_count=True rest_seconds=20 throttle_check_seconds=10.0 exclude_classes=5,11' )
def handle_args(): """Reads the commandline args and adjusts initial values of globals values to match :return: False if there was an error with the args, or True if args processed ok. """ global resize_output, resize_output_width, resize_output_height, min_score_percent, object_classifications_mask,\ show_fps, show_device_count, device_count, rest_seconds, throttle_check_seconds labels = SsdMobileNetProcessor.get_classification_labels() for an_arg in argv: if (an_arg == argv[0]): continue elif (str(an_arg).lower() == 'help'): return False elif (str(an_arg).lower().startswith('exclude_classes=')): try: arg, val = str(an_arg).split('=', 1) exclude_list = str(val).split(',') for exclude_id_str in exclude_list: exclude_id = int(exclude_id_str) if (exclude_id < 0 or exclude_id > len(labels)): print("invalid exclude_classes= parameter") return False print("Excluding class ID " + str(exclude_id) + " : " + labels[exclude_id]) object_classifications_mask[int(exclude_id)] = 0 except: print('Error with exclude_classes argument. ') return False elif (str(an_arg).lower().startswith('device_count=')): try: arg, val = str(an_arg).split('=', 1) device_count_str = val device_count = int(device_count_str) if (device_count < 0): print('Error with device_count argument. It must be > 0') return False print('Device count: ' + str(device_count)) except: print( 'Error with device count argument. It must be between 1 and number of devices' ) return False elif (str(an_arg).lower().startswith('rest_seconds=')): try: arg, val = str(an_arg).split('=', 1) rest_seconds_str = val rest_seconds = int(rest_seconds_str) if (rest_seconds < 0): print('Error with rest_seconds argument. It must be > 0') return False print('Rest Seconds: ' + str(rest_seconds)) except: print( 'Error with rest seconds argument. It must be between 1 and number of devices' ) return False elif (str(an_arg).lower().startswith('throttle_check_seconds=')): try: arg, val = str(an_arg).split('=', 1) throttle_check_seconds_str = val throttle_check_seconds = float(throttle_check_seconds_str) if (throttle_check_seconds < 0): print( 'Error with throttle_check_seconds argument. It must be > 0' ) return False print('Throttle Check Seconds: ' + str(throttle_check_seconds)) except: print( 'Error with throttle check seconds argument. It must be between 1 and number of devices' ) return False elif (str(an_arg).lower().startswith('init_min_score=')): try: arg, val = str(an_arg).split('=', 1) init_min_score_str = val init_min_score = int(init_min_score_str) if (init_min_score < 0 or init_min_score > 100): print( 'Error with init_min_score argument. It must be between 0-100' ) return False min_score_percent = init_min_score print('Initial Minimum Score: ' + str(min_score_percent) + ' %') except: print( 'Error with init_min_score argument. It must be between 0-100' ) return False elif (str(an_arg).lower().startswith('show_fps=')): try: arg, val = str(an_arg).split('=', 1) show_fps = (val.lower() == 'true') print('show_fps: ' + str(show_fps)) except: print( "Error with show_fps argument. It must be 'True' or 'False' " ) return False elif (str(an_arg).lower().startswith('show_device_count=')): try: arg, val = str(an_arg).split('=', 1) show_device_count = (val.lower() == 'true') print('show_device_count: ' + str(show_device_count)) except: print( "Error with show_device_count argument. It must be 'True' or 'False' " ) return False elif (str(an_arg).lower().startswith('resize_window=')): try: arg, val = str(an_arg).split('=', 1) width_height = str(val).split('x', 1) resize_output_width = int(width_height[0]) resize_output_height = int(width_height[1]) resize_output = True print('GUI window resize now on: \n width = ' + str(resize_output_width) + '\n height = ' + str(resize_output_height)) except: print('Error with resize_window argument: "' + an_arg + '"') return False else: return False return True
def main(): """Main function for the program. Everything starts here. :return: None """ global resize_output, resize_output_width, resize_output_height, \ obj_detector_proc, resize_output, resize_output_width, resize_output_height, video_proc if (not handle_args()): print_usage() return 1 # get list of all the .mp4 files in the image directory # input_video_filename_list = os.listdir(input_video_path) # input_video_filename_list = [i for i in input_video_filename_list if i.endswith('.mp4')] # if (len(input_video_filename_list) < 1): # # no images to show # print('No video (.mp4) files found') # return 1 # Set logging level to only log errors mvnc.global_set_option(mvnc.GlobalOption.RW_LOG_LEVEL, 3) devices = mvnc.enumerate_devices() if len(devices) < 1: print('No NCS device detected.') print('Insert device and try again!') return 1 # Pick the first stick to run the network # use the first NCS device that opens for the object detection. # open as many devices as we find dev_count = 0 ncs_devices = [] obj_detectors = [] # open as many devices as detected for one_device in devices: print('one device ', one_device, 'dev_count ', dev_count, 'devices ', devices) obj_detect_dev = mvnc.Device(one_device) status = obj_detect_dev.open() ncs_devices.append(obj_detect_dev) obj_detector_proc = SsdMobileNetProcessor( NETWORK_GRAPH_FILENAME, ncs_devices, # obj_detect_dev, inital_box_prob_thresh=min_score_percent / 100.0, classification_mask=object_classifications_mask) obj_detectors.append(obj_detector_proc) print("opened device " + str(dev_count), 'status ', status) dev_count += 1 print('ncs_devices', ncs_devices) cv2.namedWindow(cv_window_name) cv2.moveWindow(cv_window_name, 10, 10) cv2.waitKey(1) #obj_detector_proc = SsdMobileNetProcessor(NETWORK_GRAPH_FILENAME, ncs_devices[0], # obj_detect_dev, # inital_box_prob_thresh=min_score_percent/100.0, # classification_mask=object_classifications_mask) exit_app = False # output file # fourcc = cv2.VideoWriter_fourcc(*"MJPG") fourcc = cv2.VideoWriter_fourcc(*"mp4v") filenum = 1 # keep the number of video files to a reasonable number in the current directory while (filenum < 20): doesexist = os.path.isfile("output" + str(filenum) + ".mp4") if (doesexist == False): out_filename = "output" + str(filenum) + ".mp4" break filenum += 1 print("Using output file name " + out_filename) outfile = cv2.VideoWriter(out_filename, fourcc, 11.0, (640, 480)) while (True): # for input_video_file in input_video_filename_list : # video processor that will put video frames images on the object detector's input FIFO queue # video_proc = VideoProcessor(input_video_path + '/' + input_video_file, # network_processor = obj_detector_proc) # use the video cam (0) ***swb*** video_proc = VideoProcessor( 0, network_processor=obj_detectors[0]) # obj_detector_proc) video_proc.start_processing() frame_count = 0 start_time = time.time() end_time = start_time while (True): try: (filtered_objs, display_image ) = obj_detector_proc.get_async_inference_result() except: print("exception caught in main") raise # check if the window is visible, this means the user hasn't closed # the window via the X button prop_val = cv2.getWindowProperty(cv_window_name, cv2.WND_PROP_ASPECT_RATIO) if (prop_val < 0.0): end_time = time.time() video_proc.stop_processing() exit_app = True break overlay_on_image(display_image, filtered_objs) if (resize_output): display_image = cv2.resize( display_image, (resize_output_width, resize_output_height), cv2.INTER_LINEAR) cv2.imshow(cv_window_name, display_image) outfile.write(display_image) raw_key = cv2.waitKey(1) if (raw_key != -1): if (handle_keys(raw_key, obj_detector_proc) == False): end_time = time.time() exit_app = True video_proc.stop_processing() continue frame_count += 1 if (obj_detector_proc.is_input_queue_empty()): end_time = time.time() print( 'Neural Network Processor has nothing to process, assuming video is finished.' ) break frames_per_second = frame_count / (end_time - start_time) print('Frames per Second: ' + str(frames_per_second)) throttling = obj_detect_dev.get_option( mvnc.DeviceOption.RO_THERMAL_THROTTLING_LEVEL) if (throttling > 0): print("\nDevice is throttling, level is: " + str(throttling)) print("Sleeping for a few seconds....") cv2.waitKey(2000) #video_proc.stop_processing() cv2.waitKey(1) video_proc.cleanup() if (exit_app): break #if (exit_app): # break # Clean up the graph and the device obj_detector_proc.cleanup() obj_detect_dev.close() obj_detect_dev.destroy() cv2.destroyAllWindows() outfile.release()