def __init__(self, cfg, track_queue, action_queue, predictor_process): self.detector = get_detector(cfg) self.input_path = cfg.input_path self.start_mill = cfg.start self.duration_mill = cfg.duration self.realtime = cfg.realtime stream = cv2.VideoCapture(self.input_path) assert stream.isOpened(), 'Cannot capture source' self.fourcc = int(stream.get(cv2.CAP_PROP_FOURCC)) self.fps = stream.get(cv2.CAP_PROP_FPS) self.frameSize = (int(stream.get(cv2.CAP_PROP_FRAME_WIDTH)), int(stream.get(cv2.CAP_PROP_FRAME_HEIGHT))) self.videoinfo = { 'fourcc': self.fourcc, 'fps': self.fps, 'frameSize': self.frameSize } stream.release() self._stopped = mp.Value('b', False) self.track_queue = track_queue self.action_queue = action_queue self.predictor_process = predictor_process
def __init__(self, cfg): self.realtime = cfg.realtime # Action Predictor cfg_file_path = cfg.cfg_path model_weight_url = cfg.weight_path self.ava_predictor = AVAPredictor( cfg_file_path, model_weight_url, cfg.detect_rate, cfg.common_cate, cfg.device, ) # Object Detector if self.ava_predictor.has_object: object_cfg = copy.deepcopy(cfg) object_cfg.detector = "yolo" self.coco_det = get_detector(object_cfg) else: self.coco_det = None self.track_queue = mp.Queue(maxsize=1) self.input_queue = mp.Queue(maxsize=512) self.output_queue = mp.Queue() # Video Detection Loader self.predictor_process = mp.Value("i", 0) det_loader = VideoDetectionLoader(cfg, self.track_queue, self.input_queue, self.predictor_process) det_loader.start() self.timestamps = [] self.frame_stack = [] self.extra_stack = [] ava_cfg = self.ava_predictor.cfg self.frame_buffer_numbers = ava_cfg.INPUT.FRAME_NUM * ava_cfg.INPUT.FRAME_SAMPLE_RATE self.center_index = self.frame_buffer_numbers // 2 # detection interval should be 1 second like AVA, # one reason is that our model with memory feature is trained with that. # Since we may not be able to reach 25 fps, so the strategy here is based on the # number of frames. The duration of these frames may be varied. self.last_milli = -2000 self.detect_rate = cfg.detect_rate self.interval = 1000 // self.detect_rate self.vid_transforms = self.ava_predictor.transforms self._stopped = mp.Value('b', False) self._task_done = mp.Value('b', False) self.prediction_worker = mp.Process(target=self._compute_prediction, args=()) self.prediction_worker.start()
def pose_detection(image): mode = '' input_source = image if not os.path.exists(args.outputpath): os.makedirs(args.outputpath) det_loader = DetectionLoader(input_source, get_detector(args), cfg, args, batchSize=args.detbatch, mode=mode, queueSize=args.qsize) det_worker = det_loader.start()
def __init__(self): self.device = try_gpu() self.cfg = update_config( 'configs/coco/resnet/256x192_res50_lr1e-3_1x.yaml') self.detector = get_detector({'detector': yolo}) self.detector.load_model() self.pose_net = builder.build_sppe(self.cfg.MODEL, preset_cfg=self.cfg.DATA_PRESET) self.pose_net.load_state_dict( torch.load('pretrained_models/fast_res50_256x192.pth', map_location=self.device)) pose_model.to(self.device)
def __init__(self, args, cfg): self.args = args self.cfg = cfg # Load pose model self.pose_model = builder.build_sppe(cfg.MODEL, preset_cfg=cfg.DATA_PRESET) print(f'Loading pose model from {args.checkpoint}...') self.pose_model.load_state_dict(torch.load(args.checkpoint, map_location=args.device)) self.pose_dataset = builder.retrieve_dataset(cfg.DATASET.TRAIN) self.pose_model.to(args.device) self.pose_model.eval() self.det_loader = DetectionLoader(get_detector(self.args), self.cfg, self.args)
def write_coco_json(self, det_file): from pycocotools.coco import COCO import pathlib _coco = COCO(self._ann_file) image_ids = sorted(_coco.getImgIds()) det_model = get_detector(self._opt, cfg=self._detector_cfg) dets = [] for entry in tqdm(_coco.loadImgs(image_ids)): abs_path = os.path.join( self._root, self._img_prefix, entry['file_name']) det = det_model.detect_one_img(entry['id'], abs_path) if det: dets += det pathlib.Path(os.path.split(det_file)[0]).mkdir(parents=True, exist_ok=True) json.dump(dets, open(det_file, 'w'))
def loop(): n = 0 while True: yield n n += 1 if __name__ == "__main__": mode, input_source = check_input() if not os.path.exists(args.outputpath): os.makedirs(args.outputpath) # Load detection loader if mode == 'webcam': det_loader = WebCamDetectionLoader(input_source, get_detector(args), cfg, args) det_worker = det_loader.start() elif mode == 'detfile': det_loader = FileDetectionLoader(input_source, cfg, args) det_worker = det_loader.start() else: det_loader = DetectionLoader(input_source, get_detector(args), cfg, args, batchSize=args.detbatch, mode=mode, queueSize=args.qsize) det_worker = det_loader.start()
def run(self): if os.path.isfile(self.video): mode, input_source = 'video', self.video else: raise IOError( 'Error: --video must refer to a video file, not directory.') if not os.path.exists(self.outputpath): os.makedirs(self.outputpath) det_loader = DetectionLoader(input_source, get_detector(self), self.cfg, self, batchSize=self.detbatch, mode=mode, queueSize=self.qsize) det_worker = det_loader.start() # Load pose model pose_model = builder.build_sppe(self.cfg.MODEL, preset_cfg=self.cfg.DATA_PRESET) print(f'Loading pose model from {self.checkpoint}...') pose_model.load_state_dict( torch.load(self.checkpoint, map_location=self.device)) if self.pose_track: tracker = Tracker(tcfg, self) pose_model.to(self.device) pose_model.eval() if self.save_video: from alphapose.utils.writer import DEFAULT_VIDEO_SAVE_OPT as video_save_opt video_save_opt['savepath'] = self.outputpath + os.path.basename( self.video) video_save_opt.update(det_loader.videoinfo) writer = DataWriter(self.cfg, self, save_video=True, video_save_opt=video_save_opt, queueSize=self.qsize).start() else: writer = DataWriter(self.cfg, self, save_video=False, queueSize=self.qsize).start() data_len = det_loader.length im_names_desc = tqdm(range(data_len), dynamic_ncols=True) batchSize = self.posebatch try: for i in im_names_desc: start_time = getTime() with torch.no_grad(): (inps, orig_img, im_name, boxes, scores, ids, cropped_boxes) = det_loader.read() if orig_img is None: break if boxes is None or boxes.nelement() == 0: writer.save(None, None, None, None, None, orig_img, os.path.basename(im_name)) continue # Pose Estimation inps = inps.to(self.device) datalen = inps.size(0) leftover = 0 if (datalen) % batchSize: leftover = 1 num_batches = datalen // batchSize + leftover hm = [] for j in range(num_batches): inps_j = inps[j * batchSize:min((j + 1) * batchSize, datalen)] hm_j = pose_model(inps_j) hm.append(hm_j) hm = torch.cat(hm) #hm = hm.cpu() if self.pose_track: boxes, scores, ids, hm, cropped_boxes = track( tracker, self, orig_img, inps, boxes, hm, cropped_boxes, im_name, scores) writer.save(boxes, scores, ids, hm, cropped_boxes, orig_img, os.path.basename(im_name)) while (writer.running()): time.sleep(1) print('===========================> Rendering remaining ' + str(writer.count()) + ' images in the queue...') writer.stop() det_loader.stop() except KeyboardInterrupt: det_loader.terminate() while (writer.running()): time.sleep(1) print('===========================> Rendering remaining ' + str(writer.count()) + ' images in the queue...') writer.stop() self.all_results = writer.results() self._save()
action_model = joblib.load(svc_file) else: action_model = None for input_source in input_sources: if mode == 'video' and len(input_sources) > 1: lbl_name = input_source.split(os.sep)[-2] else: lbl_name = 'not_categorized' ### Moved from before load pose model # Load detection loader if mode == 'webcam': det_loader = WebCamDetectionLoader(input_source, get_detector(args), cfg, args).start() else: det_loader = DetectionLoader(input_source, get_detector(args), cfg, args, batchSize=args.detbatch, mode=mode).start() runtime_profile = {'dt': [], 'pt': [], 'pn': []} # Init data writer queueSize = 2 if mode == 'webcam' else args.qsize if args.save_video and mode != 'image': from alphapose.utils.writer import DEFAULT_VIDEO_SAVE_OPT as video_save_opt
n = 0 while True: yield n n += 1 if __name__ == "__main__": # mode = 'video', input_source = './videos/blCode_action1_scene1.avi' mode, input_source = check_input() if not os.path.exists(args.outputpath): os.makedirs(args.outputpath) # Load detection loader if mode == 'webcam': det_loader = WebCamDetectionLoader(input_source, get_detector(args), cfg, args) det_worker = det_loader.start() elif mode == 'detfile': det_loader = FileDetectionLoader(input_source, cfg, args) det_worker = det_loader.start() else: # 加载yolov4检测器(将视频流放到yolo中,用于检测人物的位置) det_loader = DetectionLoader(input_source, get_detector(args), cfg, args, batchSize=args.detbatch, mode=mode, queueSize=args.qsize) det_worker = det_loader.start() # Load pose model # 加载姿态检测模型 pose_model = builder.build_sppe(cfg.MODEL, preset_cfg=cfg.DATA_PRESET) # 打印模型 # print(pose_model)
'===========================> If this step takes too long, you can enable the --vis_fast flag to use fast rendering (real-time).' ) def loop(): n = 0 while True: yield n n += 1 if __name__ == "__main__": mode, input_root = check_input() output_root = args.outputpath detector = get_detector(args) # Load pose model pose_model = builder.build_sppe(cfg.MODEL, preset_cfg=cfg.DATA_PRESET) print(f'Loading pose model from {args.checkpoint}...') pose_model.load_state_dict( torch.load(args.checkpoint, map_location=args.device)) if len(args.gpus) > 1: pose_model = torch.nn.DataParallel( pose_model, device_ids=args.gpus).to(args.device) else: pose_model.to(args.device) pose_model.eval()
yield n n += 1 if __name__ == "__main__": mode, input_source = check_input() if not os.path.exists(args.outputpath): os.makedirs(args.outputpath) # Load detection loader if mode == 'detfile': det_loader = FileDetectionLoader(input_source, cfg, args) det_worker = det_loader.start() else: det_loader = DetectionLoader(input_source, get_detector(args), cfg, args, batchSize=args.detbatch, mode=mode, queueSize=args.qsize) det_worker = det_loader.start() # Load pose model pose_model = builder.build_sppe(cfg.MODEL, preset_cfg=cfg.DATA_PRESET) print('Loading pose model from %s...' % (args.checkpoint,)) pose_model.load_state_dict(torch.load(args.checkpoint, map_location=args.device)) pose_dataset = builder.retrieve_dataset(cfg.DATASET.TRAIN) if args.pose_track: tracker = Tracker(tcfg, args) if len(args.gpus) > 1: pose_model = torch.nn.DataParallel(pose_model, device_ids=args.gpus).to(args.device) else: pose_model.to(args.device) pose_model.eval()
n = 0 while True: yield n n += 1 if __name__ == "__main__": mode, input_source = check_input() if not os.path.exists(args.outputpath): os.makedirs(args.outputpath) # Load detection loader if mode == 'webcam': det_loader = WebCamDetectionLoader(input_source, get_detector(args, cfg['DETECTOR']), cfg, args) det_worker = det_loader.start() elif mode == 'detfile': det_loader = FileDetectionLoader(input_source, cfg, args) det_worker = det_loader.start() else: det_loader = DetectionLoader(input_source, get_detector(args, cfg['DETECTOR']), cfg, args, batchSize=args.detbatch, mode=mode, queueSize=args.qsize) det_worker = det_loader.start()
def loop(): n = 0 while True: yield n n += 1 if __name__ == "__main__": mode, input_source = check_input() if not os.path.exists(args.outputpath): os.makedirs(args.outputpath) # Load detection loader if mode == 'webcam': det_loader = RealsenseDetectionLoader(input_source, get_detector(args), cfg, args) det_worker = det_loader.start() elif mode == 'detfile': det_loader = FileDetectionLoader(input_source, cfg, args) det_worker = det_loader.start() else: det_loader = DetectionLoader(input_source, get_detector(args), cfg, args, batchSize=args.detbatch, mode=mode, queueSize=args.qsize) det_worker = det_loader.start()
def start(self): parser = argparse.ArgumentParser(description='AlphaPose Demo') parser.add_argument( '--cfg', type=str, required=False, help='experiment configure file name', default= "./AlphaPose/configs/coco/resnet/256x192_res50_lr1e-3_1x.yaml") parser.add_argument( '--checkpoint', type=str, required=False, help='checkpoint file name', default="./AlphaPose/pretrained_models/fast_res50_256x192.pth") parser.add_argument('--sp', default=False, action='store_true', help='Use single process for pytorch') parser.add_argument('--detector', dest='detector', help='detector name', default="yolo") parser.add_argument('--detfile', dest='detfile', help='detection result file', default="") parser.add_argument('--indir', dest='inputpath', help='image-directory', default="./media/img") parser.add_argument('--list', dest='inputlist', help='image-list', default="") parser.add_argument('--image', dest='inputimg', help='image-name', default="") parser.add_argument('--outdir', dest='outputpath', help='output-directory', default="./output") parser.add_argument('--save_img', default=True, action='store_true', help='save result as image') parser.add_argument('--vis', default=False, action='store_true', help='visualize image') parser.add_argument('--showbox', default=False, action='store_true', help='visualize human bbox') parser.add_argument('--profile', default=False, action='store_true', help='add speed profiling at screen output') parser.add_argument( '--format', type=str, help= 'save in the format of cmu or coco or openpose, option: coco/cmu/open', default="open") parser.add_argument('--min_box_area', type=int, default=0, help='min box area to filter out') parser.add_argument('--detbatch', type=int, default=1, help='detection batch size PER GPU') parser.add_argument('--posebatch', type=int, default=30, help='pose estimation maximum batch size PER GPU') parser.add_argument( '--eval', dest='eval', default=False, action='store_true', help= 'save the result json as coco format, using image index(int) instead of image name(str)' ) parser.add_argument( '--gpus', type=str, dest='gpus', default="0", help= 'choose which cuda device to use by index and input comma to use multi gpus, e.g. 0,1,2,3. (input -1 for cpu only)' ) parser.add_argument( '--qsize', type=int, dest='qsize', default=1024, help= 'the length of result buffer, where reducing it will lower requirement of cpu memory' ) parser.add_argument('--flip', default=False, action='store_true', help='enable flip testing') parser.add_argument('--debug', default=False, action='store_true', help='print detail information') """----------------------------- Video options -----------------------------""" parser.add_argument('--video', dest='video', help='video-name', default="") parser.add_argument('--webcam', dest='webcam', type=int, help='webcam number', default=-1) parser.add_argument('--save_video', dest='save_video', help='whether to save rendered video', default=False, action='store_true') parser.add_argument('--vis_fast', dest='vis_fast', help='use fast rendering', action='store_true', default=False) """----------------------------- Tracking options -----------------------------""" parser.add_argument('--pose_flow', dest='pose_flow', help='track humans in video with PoseFlow', action='store_true', default=False) parser.add_argument('--pose_track', dest='pose_track', help='track humans in video with reid', action='store_true', default=True) args = parser.parse_args() cfg = update_config(args.cfg) if platform.system() == 'Windows': args.sp = True args.gpus = [int(i) for i in args.gpus.split(',') ] if torch.cuda.device_count() >= 1 else [-1] args.device = torch.device( "cuda:" + str(args.gpus[0]) if args.gpus[0] >= 0 else "cpu") args.detbatch = args.detbatch * len(args.gpus) args.posebatch = args.posebatch * len(args.gpus) args.tracking = args.pose_track or args.pose_flow or args.detector == 'tracker' if not args.sp: torch.multiprocessing.set_start_method('forkserver', force=True) torch.multiprocessing.set_sharing_strategy('file_system') def check_input(): # for wecam if args.webcam != -1: args.detbatch = 1 return 'webcam', int(args.webcam) # for video if len(args.video): if os.path.isfile(args.video): videofile = args.video return 'video', videofile else: raise IOError( 'Error: --video must refer to a video file, not directory.' ) # for detection results if len(args.detfile): if os.path.isfile(args.detfile): detfile = args.detfile return 'detfile', detfile else: raise IOError( 'Error: --detfile must refer to a detection json file, not directory.' ) # for images if len(args.inputpath) or len(args.inputlist) or len( args.inputimg): inputpath = args.inputpath inputlist = args.inputlist inputimg = args.inputimg if len(inputlist): im_names = open(inputlist, 'r').readlines() elif len(inputpath) and inputpath != '/': for root, dirs, files in os.walk(inputpath): im_names = files im_names = natsort.natsorted(im_names) elif len(inputimg): args.inputpath = os.path.split(inputimg)[0] im_names = [os.path.split(inputimg)[1]] return 'image', im_names else: raise NotImplementedError def print_finish_info(): print('===========================> Finish Model Running.') if (args.save_img or args.save_video) and not args.vis_fast: print( '===========================> Rendering remaining images in the queue...' ) print( '===========================> If this step takes too long, you can enable the --vis_fast flag to use fast rendering (real-time).' ) def loop(): n = 0 while True: yield n n += 1 # dirList = os.listdir(args.inputpath) # inDir = args.inputpath # outDir = args.outputpath # for i in dirList : mode, input_source = check_input() if not os.path.exists(args.outputpath): os.makedirs(args.outputpath) # Load detection loader if mode == 'webcam': det_loader = WebCamDetectionLoader(input_source, get_detector(args), cfg, args) det_worker = det_loader.start() elif mode == 'detfile': det_loader = FileDetectionLoader(input_source, cfg, args) det_worker = det_loader.start() else: det_loader = DetectionLoader(input_source, get_detector(args), cfg, args, batchSize=args.detbatch, mode=mode, queueSize=args.qsize) det_worker = det_loader.start() # Load pose model pose_model = builder.build_sppe(cfg.MODEL, preset_cfg=cfg.DATA_PRESET) print(f'Loading pose model from {args.checkpoint}...') pose_model.load_state_dict( torch.load(args.checkpoint, map_location=args.device)) pose_dataset = builder.retrieve_dataset(cfg.DATASET.TRAIN) if args.pose_track: tracker = Tracker(tcfg, args) if len(args.gpus) > 1: pose_model = torch.nn.DataParallel(pose_model, device_ids=args.gpus).to( args.device) else: pose_model.to(args.device) pose_model.eval() runtime_profile = {'dt': [], 'pt': [], 'pn': []} # Init data writer queueSize = 2 if mode == 'webcam' else args.qsize if args.save_video and mode != 'image': from alphapose.utils.writer import DEFAULT_VIDEO_SAVE_OPT as video_save_opt if mode == 'video': video_save_opt['savepath'] = os.path.join( args.outputpath, 'AlphaPose_' + os.path.basename(input_source)) else: video_save_opt['savepath'] = os.path.join( args.outputpath, 'AlphaPose_webcam' + str(input_source) + '.mp4') video_save_opt.update(det_loader.videoinfo) writer = DataWriter(cfg, args, save_video=True, video_save_opt=video_save_opt, queueSize=queueSize).start() else: writer = DataWriter(cfg, args, save_video=False, queueSize=queueSize).start() if mode == 'webcam': print('Starting webcam demo, press Ctrl + C to terminate...') sys.stdout.flush() im_names_desc = tqdm(loop()) else: data_len = det_loader.length im_names_desc = tqdm(range(data_len), dynamic_ncols=True) batchSize = args.posebatch if args.flip: batchSize = int(batchSize / 2) try: self.percentage[2] = '관절정보 분석중' for i in range(len(im_names_desc)): start_time = getTime() # print(start_time) self.percentage[0] += 1 # with torch.no_grad(): (inps, orig_img, im_name, boxes, scores, ids, cropped_boxes) = det_loader.read() if orig_img is None: break if boxes is None or boxes.nelement() == 0: writer.save(None, None, None, None, None, orig_img, im_name) continue if args.profile: ckpt_time, det_time = getTime(start_time) runtime_profile['dt'].append(det_time) # Pose Estimation inps = inps.to(args.device) datalen = inps.size(0) leftover = 0 if (datalen) % batchSize: leftover = 1 num_batches = datalen // batchSize + leftover hm = [] for j in range(num_batches): inps_j = inps[j * batchSize:min((j + 1) * batchSize, datalen)] if args.flip: inps_j = torch.cat((inps_j, flip(inps_j))) hm_j = pose_model(inps_j) if args.flip: hm_j_flip = flip_heatmap(hm_j[int(len(hm_j) / 2):], pose_dataset.joint_pairs, shift=True) hm_j = (hm_j[0:int(len(hm_j) / 2)] + hm_j_flip) / 2 hm.append(hm_j) hm = torch.cat(hm) if args.profile: ckpt_time, pose_time = getTime(ckpt_time) runtime_profile['pt'].append(pose_time) if args.pose_track: boxes, scores, ids, hm, cropped_boxes = track( tracker, args, orig_img, inps, boxes, hm, cropped_boxes, im_name, scores) hm = hm.cpu() writer.save(boxes, scores, ids, hm, cropped_boxes, orig_img, im_name) if args.profile: ckpt_time, post_time = getTime(ckpt_time) runtime_profile['pn'].append(post_time) if args.profile: # TQDM im_names_desc.set_description( 'det time: {dt:.4f} | pose time: {pt:.4f} | post processing: {pn:.4f}' .format(dt=np.mean(runtime_profile['dt']), pt=np.mean(runtime_profile['pt']), pn=np.mean(runtime_profile['pn']))) print_finish_info() print("마무리 작업중...") while (writer.running()): time.sleep(1) print('===========================> Rendering remaining ' + str(writer.count()) + ' images in the queue...') writer.stop() det_loader.stop() print("작업종료") except Exception as e: print(repr(e)) print( 'An error as above occurs when processing the images, please check it' ) pass except KeyboardInterrupt: print_finish_info() # Thread won't be killed when press Ctrl+C if args.sp: det_loader.terminate() while (writer.running()): time.sleep(1) print('===========================> Rendering remaining ' + str(writer.count()) + ' images in the queue...') writer.stop() else: # subprocesses are killed, manually clear queues det_loader.terminate() writer.terminate() writer.clear_queues() det_loader.clear_queues()
def predict(self, image, img_name): args = self.args # Load detection loader det_loader = DetectionLoader(self.input_source, [img_name], [image], get_detector(args), self.cfg, args, batchSize=args.detbatch, mode=self.mode).start() # Init data writer queueSize = args.qsize self.writer = DataWriter(self.cfg, args, save_video=False, queueSize=queueSize).start() runtime_profile = {'dt': [], 'pt': [], 'pn': []} data_len = det_loader.length im_names_desc = tqdm(range(data_len), dynamic_ncols=True) batchSize = args.posebatch if args.flip: batchSize = int(batchSize / 2) try: for i in im_names_desc: start_time = getTime() with torch.no_grad(): (inps, orig_img, im_name, boxes, scores, ids, cropped_boxes) = det_loader.read() if orig_img is None: break if boxes is None or boxes.nelement() == 0: self.writer.save(None, None, None, None, None, orig_img, os.path.basename(im_name)) continue if args.profile: ckpt_time, det_time = getTime(start_time) runtime_profile['dt'].append(det_time) # Pose Estimation inps = inps.to(args.device) datalen = inps.size(0) leftover = 0 if (datalen) % batchSize: leftover = 1 num_batches = datalen // batchSize + leftover hm = [] for j in range(num_batches): inps_j = inps[j * batchSize:min((j + 1) * batchSize, datalen)] if args.flip: inps_j = torch.cat((inps_j, flip(inps_j))) hm_j = self.pose_model(inps_j) if args.flip: hm_j_flip = flip_heatmap(hm_j[int(len(hm_j) / 2):], det_loader.joint_pairs, shift=True) hm_j = (hm_j[0:int(len(hm_j) / 2)] + hm_j_flip) / 2 hm.append(hm_j) hm = torch.cat(hm) if args.profile: ckpt_time, pose_time = getTime(ckpt_time) runtime_profile['pt'].append(pose_time) hm = hm.cpu() self.writer.save(boxes, scores, ids, hm, cropped_boxes, orig_img, os.path.basename(im_name)) if args.profile: ckpt_time, post_time = getTime(ckpt_time) runtime_profile['pn'].append(post_time) if args.profile: # TQDM im_names_desc.set_description( 'det time: {dt:.4f} | pose time: {pt:.4f} | post processing: {pn:.4f}' .format(dt=np.mean(runtime_profile['dt']), pt=np.mean(runtime_profile['pt']), pn=np.mean(runtime_profile['pn']))) while (self.writer.running()): time.sleep(1) print('===========================> Rendering remaining ' + str(self.writer.count()) + ' images in the queue...') self.writer.stop() det_loader.stop() except KeyboardInterrupt: self.print_finish_info(args) # Thread won't be killed when press Ctrl+C if args.sp: det_loader.terminate() while (self.writer.running()): time.sleep(1) print('===========================> Rendering remaining ' + str(self.writer.count()) + ' images in the queue...') self.writer.stop() else: # subprocesses are killed, manually clear queues self.writer.commit() self.writer.clear_queues() # det_loader.clear_queues() final_result = self.writer.results() return write_json(final_result, args.outputpath, form=args.format, for_eval=args.eval)