def imgs_sorted_by_ReID(self,imgs_tracking,imgs_detection,action_index): '''通过ReID模型来筛选与目标特征相符的图片''' sub_imgs = [] # 把追踪序列和目标人物进行对比,剔除后得到追踪序列的平均ReID特征值 if len(imgs_tracking) == 0: # 如果追踪序列长度为0的话,那就没什么好处理的了,直接返回 空 就行。 return sub_imgs else: imgs_tracking_index, distmat_tracking, output_feature = imgs_sorted_by_ReID(self.ReID, self.ReIDCfg, imgs_tracking, distance_threshold=self.distance_threshold, feat_norm='yes', version=0, batch_size=self.ReID_BatchSize) for P_index in imgs_tracking_index: sub_imgs.append(imgs_tracking[P_index]) if len(imgs_detection) > 0: # 把追踪序列的平均ReID特征值和坐标转换序列对比,进行第二次筛选 imgs_detection_index, distmat_detection, _ = imgs_sorted_by_ReID(self.ReID, self.ReIDCfg, imgs_detection, distance_threshold=self.distance_threshold, feat_norm='yes', version=2, input_features=output_feature, batch_size=self.ReID_BatchSize) for P_index_detection in imgs_detection_index: sub_imgs.append(imgs_detection[P_index_detection]) if self.vis ==True: # 将追踪序列的sub_imgs 按ReID的分类结果保存 Positive_dir = os.path.join(self.vis_path, '{}/ReID'.format(action_index)) makedir_v1(Positive_dir) Negative_dir = os.path.join(self.vis_path, '{}/ReID/Negative'.format(action_index)) for P_index, _ in enumerate(imgs_tracking): distance = distmat_tracking[0, P_index] if P_index in imgs_tracking_index: cv2.imwrite(os.path.join(Positive_dir, '{}_{:3f}.jpg'.format(P_index, distance)), imgs_tracking[P_index]) else: cv2.imwrite(os.path.join(Negative_dir, '{}_{:3f}.jpg'.format(P_index, distance)), imgs_tracking[P_index]) # 将坐标转换后序列的sub_imgs 按ReID的分类结果保存 Positive_dir_detection = os.path.join(self.vis_path, '{}/ReID/detection'.format(action_index)) makedir_v1(Positive_dir_detection) Negative_dir_detection = os.path.join(self.vis_path, '{}/ReID/detection/Negative'.format(action_index)) makedir_v1(Negative_dir_detection) for P_index_detection, _ in enumerate(imgs_detection): distance = distmat_detection[0, P_index_detection] if P_index_detection in imgs_detection_index: cv2.imwrite(os.path.join(Positive_dir_detection, '{}_{:3f}.jpg'.format(P_index_detection, distance)), imgs_detection[P_index_detection]) else: cv2.imwrite(os.path.join(Negative_dir_detection, '{}_{:3f}.jpg'.format(P_index_detection, distance)), imgs_detection[P_index_detection]) return sub_imgs
def Predict(self): ''' 使用 SVHN 对完成预处理的图片进行号码预测 ''' Predict_timer = Timer() self.logger.debug('The pid of SVHN_Predict.Predict() : {}'.format( os.getpid())) self.logger.debug('The thread of SVHN_Predict.Predict() : {}'.format( currentThread())) for action_index in range(self.S_Number_Predict, self.datalen): Predict_timer.tic() # 开始计时 PreProcess_Flag, PreResults = self.PreProcess_Q.get() self.logger.debug( 'Predict() ======================================== action {}'. format(action_index)) if PreProcess_Flag == False: # 输入的数据无意义 preNum = -1 self.action_datas[action_index]['predicted_nums'] = [] else: # 输入的数据有意义, 读取数据 _, rectangle_imgs, original_imgs = PreResults imgs_length = rectangle_imgs.size(0) leftover = 0 if (imgs_length) % self.batch_size: leftover = 1 num_batches = imgs_length // self.batch_size + leftover if self.vis == True: vis_dir = os.path.join(self.vis_path, '{}'.format(action_index), 'SVHN_Predict') makedir_v1(vis_dir) vis_dir_0 = os.path.join(self.vis_path, '{}'.format(action_index), 'SVHN_Predict_Minus_one') makedir_v1(vis_dir_0) NumsArray = [] for j in range(num_batches): input_imgs_j = rectangle_imgs[j * self.batch_size:min( (j + 1) * self.batch_size, imgs_length)] length_logits_j, digits_logits_j = self.SVHN_predictor( input_imgs_j.cuda()) '''This max function return two column, the first row is value, and the second row is index ''' length_predictions_j = length_logits_j.max( 1)[1].cpu().tolist() digits_predictions_j = [ digits_logits_j.max(1)[1].cpu().tolist() for digits_logits_j in digits_logits_j ] NumsArray_j = [] for Num_i in range(len(length_predictions_j)): Number_len = length_predictions_j[Num_i] if Number_len == 1: Num = digits_predictions_j[0][Num_i] NumsArray_j.append(Num) elif Number_len == 2: Num = digits_predictions_j[0][ Num_i] * 10 + digits_predictions_j[1][Num_i] NumsArray_j.append(Num) elif Number_len == 0: Num = -1 if self.vis == True: cv2.imwrite( os.path.join( vis_dir_0, '{}_P{}.jpg'.format( num_batches * j + Num_i, Num)), original_imgs[Num_i]) continue else: continue if self.vis == True: cv2.imwrite( os.path.join( vis_dir, '{}_P{}.jpg'.format( num_batches * j + Num_i, Num)), original_imgs[Num_i]) NumsArray.extend(NumsArray_j) # 将数据保存下来 self.action_datas[action_index]['predicted_nums'] = NumsArray if len(NumsArray) > 1: # NumberArray range from 0 to 99. # We need to count how many times does each number appear! NumsArray = np.histogram(NumsArray, bins=100, range=(0, 100))[0] preNum = np.argmax(NumsArray) # if preNum == 10: # print('wrong value') preNum_count = NumsArray[preNum] if np.where(NumsArray == preNum_count)[0].size > 1: # if there are more than one number have the maximun counts, then return -1 # can sort by number classification scores. preNum = -1 else: preNum = -1 # 保存数据 True_num = self.action_datas[action_index]['num'] self.action_datas[action_index]['num'] = '{}'.format(preNum) self.logger.log( 24, 'SVHN_Predict.Predict action {} consums {}s'.format( action_index, Predict_timer.toc())) self.logger.log( 24, 'action {} ====================== True num = {}, Predict num = {} =============' .format(action_index, True_num, preNum)) if self.save_results == True: self.save_intermediate_resutls(action_index) self.logger.log( 24, '-----------------------------Finished SVHN_Predict.Predict() datalen = {}-----------------------------' .format(self.datalen)) # Finished 完成了所有的计算,保存最终结果,未进行号码矫正 write_data_to_json_file( self.root_path, self.file_name, self.action_datas, self.parameter, file_save_name=self.file_save_name_before_Number_Rectify) # 根据四官报告修改最终结果 self.action_datas = self.Number_Rectifier( os.path.join( self.root_path, self.file_save_name_before_Number_Rectify + self.file_name)).rectify() self.logger.log( 24, 'Successfully Rectify numbers according to four officials report') write_data_to_json_file( self.root_path, self.file_name, self.action_datas, self.parameter, file_save_name=self.file_save_name_after_Number_Rectify) # 并根据ReID特征划分主图片。 self.cluster_main_imgs()
def Predict(self): ''' 使用 SVHN 对完成预处理的图片进行号码预测 ''' Predict_timer = Timer() self.logger.debug( 'The pid of SVHN_Predict.Predict() : {}'.format(os.getpid())) self.logger.debug( 'The thread of SVHN_Predict.Predict() : {}'.format(currentThread())) Number_TrackingID_dict = {} for dir_index in range(self.Start_Index, self.datalen): Predict_timer.tic() # 开始计时 Predict_len = 0 dir_name = self.dir_list[dir_index] PreProcess_Flag, PreResults = self.PreProcess_Q.get() # self.logger.debug('Predict() ======================================== action {}'.format(action_index)) if PreProcess_Flag == False: # 输入的数据无意义 preNum = -1 else: # 输入的数据有意义, 读取数据 _, rectangle_imgs,original_imgs = PreResults imgs_length = rectangle_imgs.size(0) leftover = 0 if (imgs_length) % self.batch_size: leftover = 1 num_batches = imgs_length // self.batch_size + leftover if self.vis_path: vis_dir = os.path.join(self.vis_path,'{}'.format(dir_name),'SVHN_Predict') makedir_v1(vis_dir) vis_dir_0 = os.path.join(self.vis_path, '{}'.format(dir_name), 'SVHN_Predict_Minus_one') makedir_v1(vis_dir_0) NumsArray = [] for j in range(num_batches): input_imgs_j = rectangle_imgs[j*self.batch_size:min((j+1)*self.batch_size , imgs_length)] length_logits_j, digits_logits_j = self.SVHN_predictor(input_imgs_j.cuda()) '''This max function return two column, the first row is value, and the second row is index ''' length_predictions_j = length_logits_j.max(1)[1].cpu().tolist() digits_predictions_j = [digits_logits_j.max(1)[1].cpu().tolist() for digits_logits_j in digits_logits_j] NumsArray_j = [] for Num_i in range(len(length_predictions_j)): Number_len = length_predictions_j[Num_i] if Number_len == 1: Num = digits_predictions_j[0][Num_i] NumsArray_j.append(Num) elif Number_len == 2: Num = digits_predictions_j[0][Num_i] * 10 + digits_predictions_j[1][Num_i] NumsArray_j.append(Num) elif Number_len == 0: Num = -1 if self.vis_path: cv2.imwrite(os.path.join(vis_dir_0, '{}_P{}.jpg'.format(num_batches*j + Num_i, Num)), original_imgs[Num_i]) continue else: continue if self.vis_path: cv2.imwrite(os.path.join(vis_dir, '{}_P{}.jpg'.format(num_batches*j + Num_i, Num)), original_imgs[Num_i]) NumsArray.extend(NumsArray_j) Predict_len = len(NumsArray) if Predict_len > 1: # NumberArray range from 0 to 99. # We need to count how many times does each number appear! NumsArray = np.histogram(NumsArray, bins=100, range=(0, 100))[0] preNum = np.argmax(NumsArray) # if preNum == 10: # print('wrong value') preNum_count = NumsArray[preNum] if np.where(NumsArray == preNum_count)[0].size > 1: # if there are more than one number have the maximun counts, then return -1 # can sort by number classification scores. preNum = -1 else: preNum = -1 # 保存数据 # self.logger.log(24, 'SVHN_Predict.Predict action {} consums {}s'.format(action_index, Predict_timer.toc())) self.logger.log(24,'dir_name {} Predict_len = {} Predict num = {} ============='.format(dir_name, Predict_len, preNum)) Number_TrackingID_dict[int(dir_name)] = int(preNum) with open(os.path.join(self.vis_path,'Number_results.json'),'w') as f : json.dump(Number_TrackingID_dict,f) self.logger.log(24, '-----------------------------Finished SVHN_Predict.Predict() datalen = {}-----------------------------'.format(self.datalen))
def posing_postprocess(self): '''对骨骼关键节点的检测结果坐后处理,并通过 简单规则对结果进行以此初步筛选。''' pposing_postprocess_timer = Timer() for dir_index in range(self.start, self.datalen): Flag_posing_postprocess, posing_detect_resutls = self.PostProcess_Q.get( ) if Flag_posing_postprocess == False: continue else: pposing_postprocess_timer.tic() keypoints_all, sub_imgs = posing_detect_resutls target_regions = [] sub_imgs_out = [] Negative_num = 0 small_target_num = 0 Positive_num = 0 if self.save_dir: vis_dir_positive = os.path.join( self.save_dir, '{:0>6d}'.format(int(self.dir_list[dir_index])), 'Alphapose_positive') makedir_v1(vis_dir_positive) vis_dir_negative = os.path.join( self.save_dir, '{:0>6d}'.format(int(self.dir_list[dir_index])), 'Alphapose_negative') makedir_v1(vis_dir_negative) vis_dir_small_target = os.path.join( self.save_dir, '{:0>6d}'.format(int(self.dir_list[dir_index])), 'Alphapose_small_target') makedir_v1(vis_dir_small_target) target_dir = os.path.join( self.save_dir, '{:0>6d}'.format(int(self.dir_list[dir_index])), 'Target') makedir_v1(target_dir) for k_index in range(len(keypoints_all)): # 对每一张关节点图做逐一处理 origin_img = sub_imgs[k_index] height, width, _ = origin_img.shape keypoints = keypoints_all[k_index] img_name = '{}.jpg'.format(k_index) # 这个判断标准和get_box的标准不一样。 # 用来判断是否背向的 l_x_max = max(keypoints[5 * 3], keypoints[11 * 3]) r_x_min = min(keypoints[6 * 3], keypoints[12 * 3]) t_y_max = max(keypoints[5 * 3 + 1], keypoints[6 * 3 + 1]) b_y_min = min(keypoints[11 * 3 + 1], keypoints[12 * 3 + 1]) if l_x_max < r_x_min and t_y_max < b_y_min: '初步判断球员是否背向' [xmin_old, xmax_old], [xmin, xmax, ymin, ymax] = self.get_box(keypoints, height, width, ratio=0.1, expand_w_min=10) # 计算上半身体长度 body_length = ymax - ymin if body_length < 20: # 130 和 60 应该来自 opt small_target_num += 1 if self.save_dir: cv2.imwrite( os.path.join(vis_dir_small_target, img_name), origin_img) continue # 计算肩宽、胯宽 Shoulder_width = keypoints[6 * 3] - keypoints[5 * 3] Crotch_width = keypoints[12 * 3] - keypoints[11 * 3] aspect_ratio = (max(Shoulder_width, Crotch_width)) / ( body_length) # 计算比例 if aspect_ratio >= self.aspect_ratio: # 如果这个比例合适,则送入号码检测 # 各个条件都满足需求了,则可以保存起来,放入号码检测的列表中 this_sub_img = origin_img[ymin:ymax, xmin:xmax] if this_sub_img.size == 0: continue cv2.imwrite(os.path.join(target_dir, img_name), this_sub_img, [cv2.IMWRITE_JPEG_QUALITY, 100]) # sub_imgs_out.append(origin_img) # target_regions.append([xmin, xmax, ymin, ymax]) Positive_num += 1 # 复合条件的 +1 if self.save_dir: vis_img = np.copy(origin_img) cv2.rectangle(vis_img, (xmin_old, ymin), (xmax_old, ymax), color=(255, 0, 0), thickness=1) cv2.rectangle(vis_img, (xmin, ymin), (xmax, ymax), color=(0, 255, 0), thickness=1) cv2.imwrite( os.path.join(vis_dir_positive, img_name), vis_img) else: Negative_num += 1 if self.save_dir: cv2.imwrite( os.path.join(vis_dir_negative, img_name), origin_img) print('3 :posing_postprocess : {} '.format(dir_index), 'Positive_num, Negative_num,small_target_num', Positive_num, Negative_num, small_target_num)
def postProcess(self): ''' 对检测完之后的结果进行后处理 ''' postProcess_timer = Timer() self.logger.debug( 'The pid of Calibrate_transfer.postProcess() : {}'.format( os.getpid())) self.logger.debug( 'The thread of Calibrate_transfer.postProcess() : {}'.format( currentThread())) for action_index in range(self.S_Coordinate_transfer, self.datalen): self.logger.debug( 'postProcess ------------action {} has been read '.format( action_index)) Flag_detect, (acton_index_detection, results) = self.detecions_Q.get() Flag_tracking, (action_index_tracking, sub_imgs_tracking, ReID_features_tracking) = self.tracking_Q.get() postProcess_timer.tic() if Flag_detect == False or Flag_tracking == False: self.output_Q.put((False, (action_index, [], [], [], []))) continue elif acton_index_detection != action_index or action_index_tracking != action_index: raise Exception( 'acton_index_detection {} != action_index_tracking {} '. format(acton_index_detection, action_index_tracking)) if self.vis == True: vis_dir_ = os.path.join(self.vis_path, '{}'.format(action_index), 'Calibrate_transfer') makedir_v1(vis_dir_) # 把每个sub_box提取出来。 sub_imgs_detection = [] ReID_features_detection = [] # 对所有结果进行筛选,选出和目标人物相同ID的。 for r_index, [ img0, dets, id_feature, reference_point, sub_img_bias ] in enumerate(results): I_h, I_w, _ = img0.shape new_reference_point, target_id = sort_by_point( [acton_index_detection, dets, False], reference_point, input_index='{}_{}'.format(action_index, r_index)) if target_id == None: '''根据reference_point来筛选框时,没有合适的框''' if self.vis == True: vis_img = np.copy(img0) for cv2_index in range(int(dets.shape[0])): box = dets[cv2_index].tolist() x1, y1, w, h = box c_intbox = tuple( map(int, (max(0, x1), max(0, y1), min( x1 + w, I_w), min(y1 + h, I_h)))) cv2.rectangle(vis_img, (c_intbox[0], c_intbox[1]), (c_intbox[2], c_intbox[3]), (255, 0, 0), thickness=2) cv2.circle( vis_img, (int(reference_point[0]), int(reference_point[1])), radius=5, color=(0, 0, 255), thickness=-1) # 原始点为红色 cv2.imwrite( os.path.join(vis_dir_, '{}.jpg'.format(r_index)), vis_img) continue # print('dets.shape, target_id : ',dets.shape, target_id) target_bbox = dets[target_id] # print('target_bbox.shape : ', target_bbox.shape) target_bbox = target_bbox.tolist() # print('target_bbox : ', target_bbox) x1, y1, w, h = target_bbox # 目标区域 intbox = tuple( map(int, (max(0, x1), max(0, y1), min( x1 + w, I_w), min(y1 + h, I_h)))) sub_img = img0[intbox[1]:intbox[3], intbox[0]:intbox[2]] # ids = np.arryy(result[2]) target_feature = id_feature[target_id] sub_imgs_detection.append(sub_img) ReID_features_detection.append(target_feature) if self.vis == True: vis_img = np.copy(img0) for cv2_index in range(int(dets.shape[0])): box = dets[cv2_index].tolist() x1, y1, w, h = box c_intbox = tuple( map(int, (max(0, x1), max(0, y1), min( x1 + w, I_w), min(y1 + h, I_h)))) cv2.rectangle(vis_img, (c_intbox[0], c_intbox[1]), (c_intbox[2], c_intbox[3]), (255, 0, 0), thickness=2) cv2.circle( vis_img, (int(reference_point[0]), int(reference_point[1])), radius=5, color=(0, 0, 255), thickness=-1) # 原始点为红色 cv2.circle(vis_img, (int( new_reference_point[0]), int(new_reference_point[1])), radius=5, color=(0, 255, 255), thickness=-1) cv2.rectangle(vis_img, (intbox[0], intbox[1]), (intbox[2], intbox[3]), (0, 255, 255), thickness=2) cv2.imwrite( os.path.join(vis_dir_, '{}.jpg'.format(r_index)), vis_img) # 可以在此处加一个 ReID 模块 ,用于剔除劣质 sub_imgs sub_imgs = sub_imgs_detection + sub_imgs_tracking ReID_features = ReID_features_detection + ReID_features_tracking self.output_Q.put( (True, (action_index, sub_imgs_tracking, ReID_features_tracking, sub_imgs_detection, ReID_features_detection))) # 保存中间结果 if self.save_results == True: self.save_intermediate_resutls(action_index, sub_imgs, ReID_features, sub_imgs_detection, sub_imgs_tracking, ReID_features_detection, ReID_features_tracking) self.logger.log( 22, 'Calibrate_transfer.postProcess() action {} consums {}s'. format(action_index, postProcess_timer.toc()))
def PostProcess(self): ''' 数据结果后处理 ''' self.PostProcess_timer = Timer() self.logger.debug('The pid of FMLoader.PostProcess : {}'.format( os.getpid())) self.logger.debug('The thread of FMLoader.PostProcess : {}'.format( currentThread())) for action_index in range(self.S_Short_track, self.datalen): self.PostProcess_timer.tic() # show_memory_info('action _ {}, {}'.format(action_index, 'Before get ')) Flag, results, target_frame, start_time, frame_rate, Left_Up_points, reference_point = self.PostProcess_Q.get( ) self.logger.debug( 'PostProcess <===========> action {} '.format(action_index)) # 截图都没有。 if Flag == False: self.Output_Q.put((False, action_index, [])) continue # 把每个sub_box提取出来。 sub_imgs = [] ReID_feature_list = [] frames_time = [] bottom_center_point_list = [] for bias in [0, -1, 1, -2, 2]: # 总能检测到的? input_result = results[target_frame + bias] if len(input_result[1]) == 0: # 有可能目标帧没有检测到,一个目标都没有。 target_id = None continue new_reference_point, target_id = sort_by_point( results[target_frame + bias], reference_point, IoUthreshold=self.IoUthreshold) if target_id != None: # 检测到了的话,就跳出循环 # 将目标帧的图片放在了sub_imgs 和 ReID_feature_list 队列的首个 bboxes = input_result[1] ids = input_result[2] target_id_index = ids.index(target_id) box = bboxes[target_id_index] ReID_features = input_result[3] ReID_feature = ReID_features[target_id_index] img0 = input_result[4] I_h, I_w, _ = img0.shape x1, y1, w, h = box intbox = tuple( map(int, (max(0, x1), max(0, y1), min( x1 + w, I_w), min(y1 + h, I_h)))) sub_img = img0[intbox[1]:intbox[3], intbox[0]:intbox[2]] '''队列的首项是终极目标,用于校准,不用于后续的坐标转换计算''' frames_time.append(None) bottom_center_point_list.append(None) # sub_imgs 和 ReID_feature_list 在后续直接用于计算,因此不需要与 frames_time 保持长度上的一致 sub_imgs.append(sub_img) ReID_feature_list.append(ReID_feature) if self.vis == True: vis_dir_ = os.path.join(self.vis_path, '{}'.format(action_index), 'tracking') makedir_v1(vis_dir_) self.vis_target_frame(input_result, target_id, reference_point, new_reference_point, vis_dir_) break # 如果前中后三帧都没有检测到,那就说明这个动作区分不开了。 放弃了。 if target_id == None: # 目标不存在 self.Output_Q.put((False, action_index, [])) continue # 对所有结果进行筛选,选出和目标人物相同ID的。 for r_index, result in enumerate(results): frame_id = result[0] time = start_time + frame_id / frame_rate # 这帧画面对应的时间(相对于开球时间) bboxes = result[1] # ids = np.arryy(result[2]) ids = result[2] ReID_features = result[3] img0 = result[4] I_h, I_w, _ = img0.shape # 找出复合target id的那一个bbox。 每一帧最多存在一个复合要求的box # 有可能有几帧是不存在的。因此需要标注时间,或者相对帧数 if target_id not in ids: # 需要记录每个sub_imgs所对应的时间。 # 要保证时间连续,就算没有信号,也需要添加在其中, # 各个参数之间的长度需要保持一致 frames_time.append(time) bottom_center_point_list.append([]) continue else: id_index = ids.index(target_id) box = bboxes[id_index] ReID_feature = ReID_features[id_index] x1, y1, w, h = box intbox = tuple( map(int, (max(0, x1), max(0, y1), min( x1 + w, I_w), min(y1 + h, I_h)))) # print(intbox) sub_img = img0[intbox[1]:intbox[3], intbox[0]:intbox[2]] # 底部中心的坐标从相对于截图的位置,还原到相对于原图的位置。 bottom_center_point = (x1 + 0.5 * w + Left_Up_points[0], y1 + h + Left_Up_points[1]) # 需要记录每个bottom_center_point所对应的时间。 # frames_time 和 bottom_center_point 需要在长度上保持一致 frames_time.append(time) bottom_center_point_list.append(bottom_center_point) # sub_imgs 和 ReID_feature_list 在后续直接用于计算,因此不需要与 frames_time 保持长度上的一致 sub_imgs.append(sub_img) ReID_feature_list.append(ReID_feature) if self.vis == True: img_vis = np.copy(img0) cv2.rectangle(img_vis, (intbox[0], intbox[1]), (intbox[2], intbox[3]), (255, 255, 0), thickness=2) cv2.imwrite( os.path.join(vis_dir_, '{}.jpg'.format(r_index)), img_vis) # cv2.imwrite(os.path.join(vis_dir_,'{}.jpg'.format(r_index)),img_vis) self.Output_Q.put((True, action_index, [ frames_time, sub_imgs, ReID_feature_list, bottom_center_point_list ])) if self.save_results == True: self.save_intermediate_resutls(action_index, frames_time, sub_imgs, ReID_feature_list, bottom_center_point_list) self.logger.log( 21, 'FMLoader.PostProcess() action {} consums {}s'.format( action_index, self.PostProcess_timer.toc()))
def posing_postprocess(self): '''对骨骼关键节点的检测结果坐后处理,并通过 简单规则对结果进行以此初步筛选。''' pposing_postprocess_timer = Timer() for action_index in range(self.S_Pose_Estimate, self.datalen): self.logger.debug('posing_postprocess ------------action {} has been read '.format(action_index)) Flag_posing_postprocess, posing_detect_resutls = self.PostProcess_Q.get() if Flag_posing_postprocess == False: self.output_Q.put((False,[action_index])) continue else: pposing_postprocess_timer.tic() keypoints_all,sub_imgs = posing_detect_resutls target_regions = [] sub_imgs_out = [] if self.vis == True: vis_dir_positive = os.path.join(self.vis_path, '{}'.format(action_index), 'Alphapose_positive') makedir_v1(vis_dir_positive) vis_dir_negative = os.path.join(self.vis_path, '{}'.format(action_index), 'Alphapose_negative') makedir_v1(vis_dir_negative) Negative_num = 0 vis_dir_small_size = os.path.join(self.vis_path, '{}'.format(action_index), 'Alphapose_small_size') makedir_v1(vis_dir_small_size) small_size_num = 0 vis_dir_small_target = os.path.join(self.vis_path, '{}'.format(action_index), 'Alphapose_small_target') makedir_v1(vis_dir_small_target) small_target_num = 0 Positive_num = 0 for k_index in range(len(keypoints_all)): # 对每一张关节点图做逐一处理 origin_img = sub_imgs[k_index] height, width, _ = origin_img.shape if height < self.height_threshold or width < self.width_threshold: small_size_num += 1 if self.vis == True: img_name = '{}.jpg'.format(k_index) cv2.imwrite(os.path.join(vis_dir_small_size, img_name), origin_img) continue keypoints = keypoints_all[k_index] # 这个判断标准和get_box的标准不一样。 # 用来判断是否背向的 l_x_max = max(keypoints[5 * 3], keypoints[11 * 3]) r_x_min = min(keypoints[6 * 3], keypoints[12 * 3]) t_y_max = max(keypoints[5 * 3 + 1], keypoints[6 * 3 + 1]) b_y_min = min(keypoints[11 * 3 + 1], keypoints[12 * 3 + 1]) if l_x_max < r_x_min and t_y_max < b_y_min: '初步判断球员是否背向' [xmin_old, xmax_old], [xmin, xmax, ymin, ymax] = self.get_box(keypoints, height, width, ratio=0.1, expand_w_min=10) # 计算上半身体长度 body_length = ymax - ymin if body_length < 20: # 130 和 60 应该来自 opt small_target_num += 1 if self.vis == True: img_name = '{}.jpg'.format(k_index) cv2.imwrite(os.path.join(vis_dir_small_target, img_name), origin_img) continue # 计算肩宽、胯宽 Shoulder_width = keypoints[6 * 3] - keypoints[5 * 3] Crotch_width = keypoints[12 * 3] - keypoints[11 * 3] aspect_ratio = (max(Shoulder_width, Crotch_width)) / (body_length) # 计算比例 if aspect_ratio >= self.aspect_ratio: # 如果这个比例合适,则送入号码检测 sub_imgs_out.append(origin_img) target_regions.append([xmin, xmax, ymin, ymax]) Positive_num += 1 # 复合条件的 +1 if self.vis == True: img_name = '{}.jpg'.format(k_index) vis_img = np.copy(origin_img) cv2.rectangle(vis_img, (xmin_old, ymin), (xmax_old, ymax), color=(255, 0, 0), thickness=1) cv2.rectangle(vis_img, (xmin, ymin), (xmax, ymax), color=(0, 255, 0), thickness=1) cv2.imwrite(os.path.join(vis_dir_positive, img_name), vis_img) else: Negative_num += 1 if self.vis == True: img_name = '{}.jpg'.format(k_index) cv2.imwrite(os.path.join(vis_dir_negative, img_name), origin_img) self.output_Q.put((True, [action_index, sub_imgs_out,target_regions ])) # 保存中间结果 if self.save_results == True: self.save_intermediate_resutls(action_index,sub_imgs_out,target_regions) # # 输出 日志 # self.logger.log(23,'Positive_num {}, Negative_num {}, small_target_num {}, small_size_num {}, all {}'.format( # Positive_num, # Negative_num, # small_target_num, # small_size_num, # len(keypoints_all))) self.logger.log(23, 'alphapose.posing_postprocess() action {} consums {}s Positive_num / All = {}/{}'.format( action_index, pposing_postprocess_timer.toc(), Positive_num, len(keypoints_all)))