|
|
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 |