|
|
|
|
import numpy as np
|
|
|
|
|
import cv2
|
|
|
|
|
import os
|
|
|
|
|
import time
|
|
|
|
|
import mediapipe as mp
|
|
|
|
|
|
|
|
|
|
from ultralytics import YOLO
|
|
|
|
|
import queue
|
|
|
|
|
|
|
|
|
|
import threading
|
|
|
|
|
from config import Q_SZ
|
|
|
|
|
|
|
|
|
|
from personDet import analysis_yolov8
|
|
|
|
|
import tools
|
|
|
|
|
from holisticDet import MediapipeProcess
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DealVideo():
|
|
|
|
|
|
|
|
|
|
def __init__(self,video_file,video_save_file,person_model,mediapipe_model,pptsmv2_model):
|
|
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
加载数据
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
self.video_file = video_file
|
|
|
|
|
self.video_save_file = video_save_file
|
|
|
|
|
|
|
|
|
|
# 初始化模型
|
|
|
|
|
|
|
|
|
|
self.person_model = person_model
|
|
|
|
|
self.mediapipe_model = mediapipe_model
|
|
|
|
|
self.pptsmv2_model = pptsmv2_model
|
|
|
|
|
|
|
|
|
|
# 图片检测后队列
|
|
|
|
|
self.videoQueue = queue.Queue(maxsize=Q_SZ)
|
|
|
|
|
self.frameQueue = queue.Queue(maxsize=0)
|
|
|
|
|
self.cutbboxQueue = queue.Queue(maxsize=0)
|
|
|
|
|
self.videoframeQueue = queue.Queue(maxsize=0)
|
|
|
|
|
self.videohandsQueue = queue.Queue(maxsize=0)
|
|
|
|
|
self.videoheadQueue = queue.Queue(maxsize=0)
|
|
|
|
|
self.videopersonQueue = queue.Queue(maxsize=0)
|
|
|
|
|
|
|
|
|
|
#线程
|
|
|
|
|
self.get_video_listThread = threading.Thread(target=self.get_video_list)
|
|
|
|
|
self.get_video_frameThread = threading.Thread(target=self.get_video_frame)
|
|
|
|
|
self.person_detThread = threading.Thread(target=self.person_det)
|
|
|
|
|
self.write_videoThread = threading.Thread(target=self.write_video)
|
|
|
|
|
self.select_video_frameThread = threading.Thread(target=self.select_video_frame)
|
|
|
|
|
self.head_hands_detThread = threading.Thread(target=self.head_hands_det)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_video_list(self):
|
|
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
获取数据文件
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
if os.path.isdir(self.video_file):
|
|
|
|
|
|
|
|
|
|
video_ext = [".mp4", ".avi",".MP4"]
|
|
|
|
|
for maindir, subdir, file_name_list in os.walk(self.video_file):
|
|
|
|
|
for filename in file_name_list:
|
|
|
|
|
apath = os.path.join(maindir, filename)
|
|
|
|
|
ext = os.path.splitext(apath)[1]
|
|
|
|
|
if ext in video_ext:
|
|
|
|
|
self.videoQueue.put(apath)
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
self.videoQueue.put(self.video_file)
|
|
|
|
|
|
|
|
|
|
# def cut_video_seg(self):
|
|
|
|
|
|
|
|
|
|
# pass
|
|
|
|
|
|
|
|
|
|
def get_video_frame(self):
|
|
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
对视频进行分帧、每一帧都保存队列
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while True:
|
|
|
|
|
if ~self.videoQueue.empty():
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
video_path = self.videoQueue.get()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# video_basename = os.path.basename(video_path).split('.')[0]
|
|
|
|
|
|
|
|
|
|
cap = cv2.VideoCapture(video_path)
|
|
|
|
|
|
|
|
|
|
frame_list = []
|
|
|
|
|
count_fps = 0
|
|
|
|
|
|
|
|
|
|
while cap.isOpened():
|
|
|
|
|
success, frame = cap.read()
|
|
|
|
|
if not success:
|
|
|
|
|
print(video_path,"Ignoring empty camera frame.")
|
|
|
|
|
break
|
|
|
|
|
count_fps += 1
|
|
|
|
|
# print('count_fps_read_video=',count_fps)
|
|
|
|
|
|
|
|
|
|
frame_dict = {'fps':count_fps,'frame':frame}
|
|
|
|
|
frame_list.append(frame_dict)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
video_dict = {'video_path':video_path,'frame_list':frame_list}
|
|
|
|
|
|
|
|
|
|
self.frameQueue.put(video_dict)
|
|
|
|
|
# time.sleep(30)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(e)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def person_det(self):
|
|
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
从队列中获取视频帧frame,进行第一步人员的检测
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
while True:
|
|
|
|
|
|
|
|
|
|
if ~self.videoframeQueue.empty():
|
|
|
|
|
|
|
|
|
|
video_frame_dict = self.videoframeQueue.get()
|
|
|
|
|
|
|
|
|
|
frame_list = video_frame_dict['frame_list']
|
|
|
|
|
video_path = video_frame_dict['video_path']
|
|
|
|
|
|
|
|
|
|
frame_result_contact = []
|
|
|
|
|
|
|
|
|
|
for i in range(len(frame_list)):
|
|
|
|
|
|
|
|
|
|
if frame_list[i]["fps"] == i + 1:
|
|
|
|
|
|
|
|
|
|
person_det = analysis_yolov8(frame=frame_list[i]['frame'],
|
|
|
|
|
model_coco=self.person_model,
|
|
|
|
|
confidence_set=0.5)
|
|
|
|
|
|
|
|
|
|
# 当前帧检测的结果列表,只包含bboxlist
|
|
|
|
|
person_list = tools.get_dict_values(person_det)
|
|
|
|
|
|
|
|
|
|
label_name = list(person_det[0].keys())[0]
|
|
|
|
|
|
|
|
|
|
update_frame_result_contact = self.get_cut_message(fps1=frame_list[i]["fps"],
|
|
|
|
|
label_name = label_name,
|
|
|
|
|
re_list=person_list,
|
|
|
|
|
video_path=video_path,
|
|
|
|
|
frame_result_contact=frame_result_contact)
|
|
|
|
|
|
|
|
|
|
frame_result_contact = update_frame_result_contact
|
|
|
|
|
# print('frame_result_contact:',frame_result_contact)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def head_hands_det(self):
|
|
|
|
|
|
|
|
|
|
while True:
|
|
|
|
|
|
|
|
|
|
if ~self.videopersonQueue.empty():
|
|
|
|
|
|
|
|
|
|
person_frame_dict = self.videopersonQueue.get()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
person_frame_list = person_frame_dict['frame_list']
|
|
|
|
|
video_path = person_frame_dict['video_path']
|
|
|
|
|
|
|
|
|
|
head_result_contact = []
|
|
|
|
|
hands_result_contact = []
|
|
|
|
|
|
|
|
|
|
for i in range(len(person_frame_list)):
|
|
|
|
|
|
|
|
|
|
if person_frame_list[i]["fps"] == i + 1:
|
|
|
|
|
|
|
|
|
|
image = person_frame_list[i]["frame"]
|
|
|
|
|
|
|
|
|
|
imgsize = image.shape
|
|
|
|
|
|
|
|
|
|
# print(type(image))
|
|
|
|
|
|
|
|
|
|
# 模型推理
|
|
|
|
|
hh_result = MediapipeProcess.mediapipe_det(image=image,
|
|
|
|
|
holistic=self.mediapipe_model)
|
|
|
|
|
hh_result_dict = MediapipeProcess.get_analysis_result(image=image,results=hh_result)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 获得当前坐标列表
|
|
|
|
|
head_result = hh_result_dict['face_bbox']
|
|
|
|
|
head_result_1 = tools.select_list(head_result)
|
|
|
|
|
hands_result = hh_result_dict['hand_bbox']
|
|
|
|
|
hands_result_1 = tools.select_list(hands_result)
|
|
|
|
|
|
|
|
|
|
print('head_result_1:',head_result_1)
|
|
|
|
|
print('head_result_1:',hands_result_1)
|
|
|
|
|
|
|
|
|
|
# 统一修正坐标,分别对头和手进行分析
|
|
|
|
|
if head_result_1:
|
|
|
|
|
head_bbox_list = tools.para_list_correction(images_size=imgsize,
|
|
|
|
|
bbox_list=head_result_1,
|
|
|
|
|
dertpara=[])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
update_head_result_contact = self.get_cut_message(fps1=person_frame_list[i]["fps"],
|
|
|
|
|
label_name = 'head',
|
|
|
|
|
re_list=head_bbox_list,
|
|
|
|
|
video_path=video_path,
|
|
|
|
|
frame_result_contact=head_result_contact)
|
|
|
|
|
head_result_contact = update_head_result_contact
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if hands_result_1:
|
|
|
|
|
|
|
|
|
|
hands_bbox_list = tools.para_list_correction(images_size=imgsize,
|
|
|
|
|
bbox_list=hands_result_1,
|
|
|
|
|
dertpara=[])
|
|
|
|
|
|
|
|
|
|
update_hands_result_contact = self.get_cut_message(fps1=person_frame_list[i]["fps"],
|
|
|
|
|
label_name = 'hands',
|
|
|
|
|
re_list=hands_bbox_list,
|
|
|
|
|
video_path=video_path,
|
|
|
|
|
frame_result_contact=hands_result_contact)
|
|
|
|
|
|
|
|
|
|
hands_result_contact = update_hands_result_contact
|
|
|
|
|
|
|
|
|
|
# print("head_result_contact:",head_result_contact)
|
|
|
|
|
# print("hands_result_contact:",hands_result_contact)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_cut_message(self,fps1,label_name,re_list,video_path,frame_result_contact):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not frame_result_contact:
|
|
|
|
|
|
|
|
|
|
bbox_list_all = tools.change_list_dict(fps1=fps1,re_list=re_list)
|
|
|
|
|
|
|
|
|
|
frame_result_contact = bbox_list_all
|
|
|
|
|
# print("frame_result_contact:",frame_result_contact)
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
|
|
example_dict_list = frame_result_contact
|
|
|
|
|
print('example_dict_list:',example_dict_list)
|
|
|
|
|
print('re_list:',re_list)
|
|
|
|
|
|
|
|
|
|
cut_list,example_lst,re_dict_lst = tools.analysis_re01_list(example_list=example_dict_list,
|
|
|
|
|
result_list=re_list)
|
|
|
|
|
|
|
|
|
|
# print('cut_list:',cut_list)
|
|
|
|
|
# print('example_sorted_lst:',example_lst)
|
|
|
|
|
# print('re_dict_sorted_lst:',re_dict_lst)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 有目标减少情况
|
|
|
|
|
if example_lst:
|
|
|
|
|
|
|
|
|
|
# 截图保存视频
|
|
|
|
|
|
|
|
|
|
cut_dict = {'video_path':video_path,'label_name':label_name,"stop_fps":fps1,'bbox_list':example_lst}
|
|
|
|
|
|
|
|
|
|
# 添加到新的队列
|
|
|
|
|
self.cutbboxQueue.put(cut_dict)
|
|
|
|
|
|
|
|
|
|
frame_result_contact = [item for item in frame_result_contact if item not in example_lst]
|
|
|
|
|
|
|
|
|
|
# 有新添加目标情况
|
|
|
|
|
if re_dict_lst:
|
|
|
|
|
|
|
|
|
|
# 对比示例列表更新
|
|
|
|
|
update_list = tools.change_list_dict(fps1=fps1,re_list=re_dict_lst)
|
|
|
|
|
|
|
|
|
|
frame_result_contact = frame_result_contact + update_list
|
|
|
|
|
|
|
|
|
|
# 统计截止时间
|
|
|
|
|
time_out_list = tools.statistics_fps(fps_now=fps1,re_list=frame_result_contact,parameter=20)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if time_out_list:
|
|
|
|
|
|
|
|
|
|
# 裁剪保存视频
|
|
|
|
|
# bbox_list = Process_tools.change_dict_list(time_out_list)
|
|
|
|
|
|
|
|
|
|
cut_dict = {'video_path':video_path,'label_name':label_name,"stop_fps":fps1,'bbox_list':time_out_list}
|
|
|
|
|
|
|
|
|
|
# 添加到新的队列
|
|
|
|
|
self.cutbboxQueue.put(cut_dict)
|
|
|
|
|
|
|
|
|
|
# 对比示例列表更新
|
|
|
|
|
frame_result_contact = [item for item in frame_result_contact if item not in time_out_list]
|
|
|
|
|
|
|
|
|
|
# print('frame_result_contact:',frame_result_contact)
|
|
|
|
|
|
|
|
|
|
return frame_result_contact
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def write_video(self):
|
|
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
保存成视频
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
while True:
|
|
|
|
|
|
|
|
|
|
if ~self.cutbboxQueue.empty():
|
|
|
|
|
|
|
|
|
|
video_frame_dict = self.cutbboxQueue.get()
|
|
|
|
|
|
|
|
|
|
# print('video_frame_dict:',video_frame_dict)
|
|
|
|
|
|
|
|
|
|
# 视频路径
|
|
|
|
|
video_path = video_frame_dict['video_path']
|
|
|
|
|
video_basename = os.path.basename(video_path).split('.')[0]
|
|
|
|
|
file_name = video_frame_dict['label_name']
|
|
|
|
|
# video_name_save = os.path.join(self.video_save_file, video_basename)
|
|
|
|
|
|
|
|
|
|
# 原视频帧率和尺寸
|
|
|
|
|
cap = cv2.VideoCapture(video_path)
|
|
|
|
|
fps = cap.get(cv2.CAP_PROP_FPS)
|
|
|
|
|
|
|
|
|
|
# 获得起始帧
|
|
|
|
|
stop_fps = video_frame_dict['stop_fps']
|
|
|
|
|
|
|
|
|
|
# 裁剪信息
|
|
|
|
|
result_list = video_frame_dict['bbox_list']
|
|
|
|
|
|
|
|
|
|
for i,bbox_dict in enumerate(result_list):
|
|
|
|
|
|
|
|
|
|
start_fps = bbox_dict['fps']
|
|
|
|
|
bbox_list = bbox_dict['result']
|
|
|
|
|
|
|
|
|
|
w = int(bbox_list[2]) - int(bbox_list[0])
|
|
|
|
|
h = int(bbox_list[3]) - int(bbox_list[1])
|
|
|
|
|
|
|
|
|
|
size = (w,h)
|
|
|
|
|
|
|
|
|
|
# 根据标签保存不同视频分类
|
|
|
|
|
video_name_save = video_basename + '_' + str(start_fps) + '_' + str(stop_fps) + '_' + str(i) + '.avi'
|
|
|
|
|
video_save_file = self.video_save_file + '/' + file_name
|
|
|
|
|
os.makedirs(video_save_file, exist_ok=True)
|
|
|
|
|
video_save_path = os.path.join(video_save_file, video_name_save)
|
|
|
|
|
|
|
|
|
|
videoWriter =cv2.VideoWriter(video_save_path,cv2.VideoWriter_fourcc('X','V','I','D'),fps,size)
|
|
|
|
|
|
|
|
|
|
tools.save_seg_video(video_name=video_path,
|
|
|
|
|
frameToStart=start_fps,
|
|
|
|
|
frametoStop=stop_fps,
|
|
|
|
|
videoWriter=videoWriter,
|
|
|
|
|
bbox=bbox_list)
|
|
|
|
|
|
|
|
|
|
videoWriter.release()
|
|
|
|
|
|
|
|
|
|
self.videoQueue.put(video_save_path)
|
|
|
|
|
|
|
|
|
|
cap.release()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def select_video_frame(self):
|
|
|
|
|
|
|
|
|
|
while True:
|
|
|
|
|
|
|
|
|
|
if ~self.frameQueue.empty():
|
|
|
|
|
|
|
|
|
|
video_dict = self.frameQueue.get()
|
|
|
|
|
video_path = video_dict["video_path"]
|
|
|
|
|
directory = os.path.dirname(video_path)
|
|
|
|
|
labels = directory.split('/')[-1]
|
|
|
|
|
|
|
|
|
|
print('labels:',labels)
|
|
|
|
|
|
|
|
|
|
if labels == 'person':
|
|
|
|
|
|
|
|
|
|
self.videopersonQueue.put(video_dict)
|
|
|
|
|
|
|
|
|
|
if labels == 'head':
|
|
|
|
|
|
|
|
|
|
# print('youshou')
|
|
|
|
|
|
|
|
|
|
self.videoheadQueue.put(video_dict)
|
|
|
|
|
|
|
|
|
|
if labels == 'hands':
|
|
|
|
|
|
|
|
|
|
# print('youshou')
|
|
|
|
|
|
|
|
|
|
self.videohandsQueue.put(video_dict)
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
|
|
self.videoframeQueue.put(video_dict)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
|
|
|
|
|
|
self.get_video_listThread.start()
|
|
|
|
|
self.get_video_frameThread.start()
|
|
|
|
|
self.person_detThread.start()
|
|
|
|
|
self.write_videoThread.start()
|
|
|
|
|
self.select_video_frameThread.start()
|
|
|
|
|
self.head_hands_detThread.start()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
video = "E:/Bank_files/Bank_02/dataset/video_test/test03_3.avi"
|
|
|
|
|
video_save = 'test_video'
|
|
|
|
|
|
|
|
|
|
person_model = YOLO("model_file/yolov8x_person.pt")
|
|
|
|
|
|
|
|
|
|
mp_holistic = mp.solutions.holistic
|
|
|
|
|
holistic = mp_holistic.Holistic(
|
|
|
|
|
min_detection_confidence=0.5,
|
|
|
|
|
min_tracking_confidence=0.5)
|
|
|
|
|
|
|
|
|
|
# get_seg_video(video_file=video,video_save_path=video_save,dertTime=dertTime)
|
|
|
|
|
deal = DealVideo(video_file=video,video_save_file=video_save,person_model=person_model,mediapipe_model=holistic,pptsmv2_model='model_file/yolov8x_person.pt')
|
|
|
|
|
deal.run()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|