def __init__(self, cfg, opt, save_video=False, video_save_opt=DEFAULT_VIDEO_SAVE_OPT, queueSize=1024): self.cfg = cfg self.opt = opt self.video_save_opt = video_save_opt self.eval_joints = EVAL_JOINTS self.save_video = save_video self.final_result = [] self.heatmap_to_coord = get_func_heatmap_to_coord(cfg) # initialize the queue used to store frames read from # the video file if opt.sp: self.result_queue = Queue(maxsize=queueSize) self.final_result_queue = Queue(maxsize=queueSize) else: self.result_queue = mp.Queue(maxsize=queueSize) self.final_result_queue = mp.Queue(maxsize=queueSize) if opt.save_img: if not os.path.exists(opt.outputpath + '/vis'): os.mkdir(opt.outputpath + '/vis') if opt.pose_track: from PoseFlow.poseflow_infer import PoseFlowWrapper self.pose_flow_wrapper = PoseFlowWrapper( save_path=os.path.join(opt.outputpath, 'poseflow'))
class DataWriter(): def __init__(self, cfg, opt, save_video=False, video_save_opt=DEFAULT_VIDEO_SAVE_OPT, queueSize=1024): self.cfg = cfg self.opt = opt self.video_save_opt = video_save_opt self.eval_joints = EVAL_JOINTS self.save_video = save_video self.final_result = [] self.heatmap_to_coord = get_func_heatmap_to_coord(cfg) # initialize the queue used to store frames read from # the video file if opt.sp: self.result_queue = Queue(maxsize=queueSize) self.final_result_queue = Queue(maxsize=queueSize) else: self.result_queue = mp.Queue(maxsize=queueSize) self.final_result_queue = mp.Queue(maxsize=queueSize) if opt.save_img: if not os.path.exists(opt.outputpath + '/vis'): os.mkdir(opt.outputpath + '/vis') if opt.pose_track: from PoseFlow.poseflow_infer import PoseFlowWrapper self.pose_flow_wrapper = PoseFlowWrapper( save_path=os.path.join(opt.outputpath, 'poseflow')) def start_worker(self, target): if self.opt.sp: p = Thread(target=target, args=()) else: p = mp.Process(target=target, args=()) # p.daemon = True p.start() return p def start(self): # start a thread to read pose estimation results per frame self.result_worker = self.start_worker(self.update) return self def update(self): if self.save_video: # initialize the file video stream, adapt ouput video resolution to original video stream = cv2.VideoWriter(*[ self.video_save_opt[k] for k in ['savepath', 'fourcc', 'fps', 'frameSize'] ]) if not stream.isOpened(): print("Try to use other video encoders...") ext = self.video_save_opt['savepath'].split('.')[-1] fourcc, _ext = self.recognize_video_ext(ext) self.video_save_opt['fourcc'] = fourcc self.video_save_opt[ 'savepath'] = self.video_save_opt['savepath'][:-4] + _ext stream = cv2.VideoWriter(*[ self.video_save_opt[k] for k in ['savepath', 'fourcc', 'fps', 'frameSize'] ]) assert stream.isOpened(), 'Cannot open video for writing' # keep looping infinitelyd while True: # ensure the queue is not empty and get item (boxes, scores, ids, hm_data, cropped_boxes, orig_img, im_name) = self.wait_and_get(self.result_queue) if orig_img is None: # if the thread indicator variable is set (img is None), stop the thread self.wait_and_put(self.final_result_queue, None) if self.save_video: stream.release() return # image channel RGB->BGR orig_img = np.array(orig_img, dtype=np.uint8)[:, :, ::-1] if boxes is None: if self.opt.save_img or self.save_video or self.opt.vis: self.write_image( orig_img, im_name, stream=stream if self.save_video else None) else: # location prediction (n, kp, 2) | score prediction (n, kp, 1) pred = hm_data.cpu().data.numpy() assert pred.ndim == 4 if hm_data.size()[1] == 49: self.eval_joints = [*range(0, 49)] pose_coords = [] pose_scores = [] for i in range(hm_data.shape[0]): bbox = cropped_boxes[i].tolist() pose_coord, pose_score = self.heatmap_to_coord( pred[i][self.eval_joints], bbox) pose_coords.append( torch.from_numpy(pose_coord).unsqueeze(0)) pose_scores.append( torch.from_numpy(pose_score).unsqueeze(0)) preds_img = torch.cat(pose_coords) preds_scores = torch.cat(pose_scores) result = pose_nms(boxes, scores, ids, preds_img, preds_scores, self.opt.min_box_area) result = {'imgname': im_name, 'result': result} if self.opt.pose_track: poseflow_result = self.pose_flow_wrapper.step( orig_img, result) for i in range(len(poseflow_result)): result['result'][i]['idx'] = poseflow_result[i]['idx'] self.wait_and_put(self.final_result_queue, result) if self.opt.save_img or self.save_video or self.opt.vis: if hm_data.size()[1] == 49: from alphapose.utils.vis import vis_frame_dense as vis_frame elif self.opt.vis_fast: from alphapose.utils.vis import vis_frame_fast as vis_frame else: from alphapose.utils.vis import vis_frame img = vis_frame( orig_img, result, add_bbox=(self.opt.pose_track | self.opt.tracking | self.opt.showbox)) self.write_image( img, im_name, stream=stream if self.save_video else None) def write_image(self, img, im_name, stream=None): if self.opt.vis: cv2.imshow("AlphaPose Demo", img) cv2.waitKey(30) if self.opt.save_img: cv2.imwrite(os.path.join(self.opt.outputpath, 'vis', im_name), img) if self.save_video: stream.write(img) def wait_and_put(self, queue, item): queue.put(item) def wait_and_get(self, queue): return queue.get() def save(self, boxes, scores, ids, hm_data, cropped_boxes, orig_img, im_name): self.commit() # save next frame in the queue self.wait_and_put( self.result_queue, (boxes, scores, ids, hm_data, cropped_boxes, orig_img, im_name)) def running(self): # indicate that the thread is still running time.sleep(0.2) self.commit() return not self.result_queue.empty() def count(self): # indicate the remaining images return self.result_queue.qsize() def stop(self): # indicate that the thread should be stopped self.save(None, None, None, None, None, None, None) while True: final_res = self.wait_and_get(self.final_result_queue) if final_res: self.final_result.append(final_res) else: break self.result_worker.join() def clear_queues(self): self.clear(self.result_queue) self.clear(self.final_result_queue) def clear(self, queue): while not queue.empty(): queue.get() def commit(self): # commit finished final results to main process while not self.final_result_queue.empty(): self.final_result.append(self.wait_and_get( self.final_result_queue)) def results(self): # return final result return self.final_result def recognize_video_ext(self, ext=''): if ext == 'mp4': return cv2.VideoWriter_fourcc(*'mp4v'), '.' + ext elif ext == 'avi': return cv2.VideoWriter_fourcc(*'XVID'), '.' + ext elif ext == 'mov': return cv2.VideoWriter_fourcc(*'XVID'), '.' + ext else: print("Unknow video format {}, will use .mp4 instead of it".format( ext)) return cv2.VideoWriter_fourcc(*'mp4v'), '.mp4'