import cv2 import os from deepdiff import DeepDiff # 图像文件夹 def get_video_list(path): video_ext = [".mp4", ".avi",".MP4"] video_names = [] for maindir, subdir, file_name_list in os.walk(path): for filename in file_name_list: apath = os.path.join(maindir, filename) ext = os.path.splitext(apath)[1] if ext in video_ext: video_names.append(apath) return video_names # # 截取裁剪需要的视频帧 # def save_seg_video(video_name, frameToStart, frametoStop, videoWriter, bbox): # cap = video_name # cap.set(cv2.CAP_PROP_POS_FRAMES, frameToStart) # 设置初始帧数 # count = frameToStart # while True: # success, frame = cap.read() # if not success or count > frametoStop: # break # if count >= frameToStart: # # 裁剪视频画面 # frame_target = frame[int(bbox[1]):int(bbox[3]), int(bbox[0]):int(bbox[2])] # videoWriter.write(frame_target) # count += 1 # cap.release() # 截取裁剪需要的视频帧 def save_seg_video(video_name,frameToStart,frametoStop,videoWriter,bbox,size): cap = cv2.VideoCapture(video_name) count = 0 while True: success,frame = cap.read() if success: count += 1 if count <= frametoStop and count > frameToStart: # 选取起始帧 # print('correct= ', count) #裁剪视频画面 frame_target = frame[bbox[1]:bbox[3], bbox[0]:bbox[2]] # (split_height, split_width) try: frame_target = cv2.resize(frame_target,size) videoWriter.write(frame_target) except Exception as e: print('----------------------------------',size,'----------------------------------') print(e) if not success or count >= frametoStop: break videoWriter.release() cap.release() # 获得字典中所有values值(这个值是列表) def get_dict_values(lst): """ 获取列表中所有字典的 values 值(如果值是列表) 参数: lst: 包含字典的列表 返回值: values: 包含所有字典的 values 值的列表(如果值是列表) """ return [value for dictionary in lst for value in dictionary.values() if isinstance(value, list)] # 解析检测后的结果,为检测后的结果排序 def analysis_sort_list(re_list): # print('result_dict:',result_dict) # 获得检测列表 # re_list = result_dict['start_bbox'] # print('re_list:',re_list) # 获得列表中所有字典的values值 # re_bbox_list = Process_tools.get_dict_values(re_list) # 为检测出来的标注框排序 sorted_lst = sorted(re_list, key=lambda x: x[0]) return sorted_lst #对比重叠率高的两个部分,并结合标注框,保存最大的标注框 def contrast_bbox(e_bbox,r_bbox): e_bbox_min = e_bbox[:2] r_bbox_min = r_bbox[:2] bbox_min = [min(x, y) for x, y in zip(e_bbox_min, r_bbox_min)] e_bbox_max = e_bbox[-2:] r_bbox_max = r_bbox[-2:] bbox_max = [max(x, y) for x, y in zip(e_bbox_max, r_bbox_max)] bbox = bbox_min + bbox_max return bbox # 解析result_list列表 def analysis_re01_list(example_list,result_list): ''' example_dict:对比的参照 result_dict: 需要与参照对比的结果 example_sorted_lst:返回值中,原先有现在没有部分 re_dict_sorted_lst:返回值中,现在有原先没有部分 cut_list:原先有,现在也有的部分 ''' # 第一次检测到目标的帧率和信息 # example_dict_fps = list(example_dict.keys())[0] # example_sorted_lst = Process_tools.analysis_sort_list(example_list) # 当前帧检测结果中所有的检测结果数值 # re_dict_fps = list(result_dict.keys())[0] # re_dict_sorted_lst = Process_tools.analysis_sort_list(result_list) # 保存前后帧率连续的范围、筛选出相同的部分 cut_list = [] example_temp = [] re_temp = [] for i,ex_bbox_dict in enumerate(example_list): ex_bbox = ex_bbox_dict['result'] for j,re_bbox in enumerate(result_list): iou = calculate_iou(box1=ex_bbox, box2=re_bbox) # print(iou) if iou > 0.5: # bbox = Process_tools.contrast_bbox(e_bbox=ex_bbox,r_bbox=re_bbox) # cut_list.append({i:re_bbox}) cut_list.append(re_bbox) example_temp.append(ex_bbox) re_temp.append(re_bbox) break # print('example_temp:',example_temp) # print('re_temp:',re_temp) example_sorted_lst = [item for item in example_list if item['result'] not in example_temp] re_dict_sorted_lst = [item for item in result_list if item not in re_temp] return cut_list,example_sorted_lst,re_dict_sorted_lst # 计算前后帧率重叠范围 def calculate_iou(box1, box2): """ 计算两个边界框之间的IoU值 参数: box1: 边界框1的坐标(x1, y1, x2, y2) box2: 边界框2的坐标(x1, y1, x2, y2) 返回值: iou: 两个边界框之间的IoU值 """ x1 = max(box1[0], box2[0]) y1 = max(box1[1], box2[1]) x2 = min(box1[2], box2[2]) y2 = min(box1[3], box2[3]) # 计算交集区域面积 intersection_area = max(0, x2 - x1 + 1) * max(0, y2 - y1 + 1) # 计算边界框1和边界框2的面积 box1_area = (box1[2] - box1[0] + 1) * (box1[3] - box1[1] + 1) box2_area = (box2[2] - box2[0] + 1) * (box2[3] - box2[1] + 1) # 计算并集区域面积 union_area = box1_area + box2_area - intersection_area # 计算IoU值 iou = intersection_area / union_area return iou # 修正坐标参数 def para_correction(images_size,bbox,dertpara): ''' 修正检测后标注框过小的情况,如果有修正参数则使用修正参数,如果没有就按照坐标值扩大两倍 ''' # if dertpara: # pass # else: w = (bbox[2] - bbox[0]) / int(dertpara) h = (bbox[3] - bbox[1]) / int(dertpara) bbox_extand_list_x = [bbox[0] - w,bbox[2] + w] bbox_extand_list_y = [bbox[1] - h,bbox[3] + h] bbox_list_x = contrast(size=images_size[0],bbox_extand_list=bbox_extand_list_x) bbox_list_y = contrast(size=images_size[1],bbox_extand_list=bbox_extand_list_y) bbox_list = [bbox_list_x[0],bbox_list_y[0],bbox_list_x[1],bbox_list_y[1]] return bbox_list def para_correction_back(x1, y1, x2, y2): ''' 修正检测后标注框还原 ''' # if dertpara: # pass # else: # x1, y1, x2, y2 = bbox[0], bbox[1],bbox[2],bbox[3] # 原始坐标 width = x2 - x1 height = y2 - y1 scaled_width = int(width * 1.2) scaled_height = int(height * 1.2) restored_width = int(scaled_width / 1.2) restored_height = int(scaled_height / 1.2) restored_x1 = x1 + (width - restored_width) // 2 restored_y1 = y1 + (height - restored_height) // 2 restored_x2 = restored_x1 + restored_width restored_y2 = restored_y1 + restored_height bbox_list = [restored_x1,restored_y1,restored_x2,restored_y2] return bbox_list def para_list_correction(images_size,bbox_list,dertpara): updata_result_list = [] for bbox in bbox_list: updata_bbox = para_correction(images_size,bbox,dertpara) updata_result_list.append(updata_bbox) return updata_result_list # 对比数值是否在这个范围内 def contrast(size,bbox_extand_list): ''' 对比数值是否在这个范围内 ''' # print('bbox_extand_list:',bbox_extand_list) # print('size:',size) bbox_list = [] for x in bbox_extand_list: # print('size:',size) if 0 <= int(x) <= int(size): # print('in:',x,size) bbox_list.append(x) if int(x) > int(size): # print('>:',x,size) bbox_list.append(size) if int(x) < 0: # print('<:',x,size) bbox_list.append(0) # print('bbox_list:',bbox_list) return bbox_list def change_list_dict(fps1,re_list): ''' 给列表的结果设置对应帧率 ''' bbox_list_all = [] for bbox_list in re_list: bbox_dict = {'fps':fps1,'result':bbox_list} bbox_list_all.append(bbox_dict) return bbox_list_all def statistics_fps(fps_now,re_list,parameter): ''' 统计时长,返回时间满足截取要求的目标坐标 ''' time_out_list = [] for bbox_dict in re_list: con_fps = int(fps_now) - int(bbox_dict["fps"]) if con_fps > parameter: time_out_list.append(bbox_dict) return time_out_list def change_dict_list(dict_list): ''' 从字典列表得到bbox列表 ''' bbox_list = [] for dicts1 in dict_list: bbox_list.append(dicts1['result']) return bbox_list def select_list(result_list): ''' 筛选列表中的空列表 ''' if result_list: result_only = [] for result in result_list: if result == None : pass else: # result_bbox = select_bbox(result) result_only.append(result) return result_only def select_bbox(bbox_list): # bbox_list_return = [] # print('bbox:',bbox_list) left_top = [min(bbox_list, key=lambda p: p[0])[0], min(bbox_list, key=lambda p: p[1])[1]] right_bottom = [max(bbox_list, key=lambda p: p[0])[0], max(bbox_list, key=lambda p: p[1])[1]] bbox_list_return = left_top + right_bottom # print('bbox_list:',bbox_list_return) return bbox_list_return # 对比两字典中的值是否完全一致 def compare_dicts(dict1, list_of_dicts): for d in list_of_dicts: diff = DeepDiff(dict1, d) if not diff: return False return True