def _main_(args): ############################### # Prepare data to be detected ############################### # data_folder = "/home/peng/data/good_rolo_data/" data_folder = "/home/peng/data/sort_data/images/" # data_folder = "/home/peng/data/sort_data/images/" video_folders_list = sorted(glob.glob(data_folder + '*')) sort_nicely(video_folders_list) ############################### # Make the model and Load trained weights ############################### dn.set_gpu(0) # Original YOLOv3 weights net = dn.load_net("cfg/yolov3.cfg", "yolov3.weights", 0) meta = dn.load_meta("cfg/coco.data") # Aerial YOLOv3 weights # net = dn.load_net("cfg/yolov3.cfg", "yolov3-aerial.weights", 0) # meta = dn.load_meta("cfg/voc.data") ############################### # Predict bounding boxes ############################### for video_folder in video_folders_list: video_name = basename(video_folder) #if video_name != "person14_3": # continue print("Processing %s." % video_name) image_paths = sorted(glob.glob(os.path.join(video_folder, '*jpg'))) sort_nicely(image_paths) """ Remember to modify the following path """ with open('det_mot(before_ft)/' + video_name + '.txt', 'w') as out_file: for i in tqdm(range(len(image_paths))): # image = cv2.imread(image_paths[i]) results = dn.detect(net, meta, image_paths[i], thresh=0.45, nms=0.5) for r in results: if r[0] == 'person' and r[1] > 0.88: box = BoundBox(r[2][0], r[2][1], r[2][2], r[2][3], r[1], r[0]) x1 = (box.x - box.w / 2) y1 = (box.y - box.h / 2) print('%d,-1,%.2f,%.2f,%.2f,%.2f,%.6f,-1,-1,-1' % (i + 1, x1, y1, box.w, box.h, box.c), file=out_file)
def mot(data_dir, sort_result_path, STORE=False): if not os.path.exists(data_dir): raise IOError("Invalid data path:", data_dir) if not os.path.exists(sort_result_path): raise IOError("Invalid annotation path:", sort_result_path) colours = np.round(np.random.rand(32, 3) * 255) if STORE: video_name = data_dir.split('/')[-2] FPS = 30 # remember to modify frame width and height before testing video frame_width = 1280 frame_height = 720 video_writer = cv2.VideoWriter( video_name + '.avi', cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'), FPS, (frame_width, frame_height)) image_paths = sorted(glob.glob(os.path.join(data_dir, '*jpg'))) sort_nicely(image_paths) sort_result = np.loadtxt(sort_result_path, delimiter=',') sort_result[:, 2:6] = xywh_to_xyxy(sort_result[:, 2:6]) for i, image_path in enumerate(image_paths): image = cv2.imread(image_path) index_list = np.argwhere(sort_result[:, 0] == (i + 1)) if index_list.shape[0] != 0: for index in index_list[:, 0]: cv2.rectangle( image, (int(sort_result[index, 2]), int(sort_result[index, 3])), (int(sort_result[index, 4]), int(sort_result[index, 5])), colours[int(sort_result[index, 1]) % 32], 3) if STORE: video_writer.write(image) else: cv2.imshow("output", image) try: if index_list.shape[0] == 0: cv2.waitKey(0) else: cv2.waitKey(30) except ValueError: cv2.waitKey(30) if i > 20: break
def online_tracking(data_dir, STORE=False): """ Online tracking, detect and track in one step (with target trajectory and moving direction) Params: data_dir: list, path to directory of video frames STORE: bool, whether you need to store the video or just show directky Return: None """ if not os.path.exists(data_dir): raise IOError("Invalid data path:", data_dir) dn.set_gpu(0) # net = dn.load_net("../cfg/yolov3.cfg", "../yolov3.weights", 0) net = dn.load_net("../cfg/yolov3.cfg", "../yolov3-aerial.weights", 0) meta = dn.load_meta("../cfg/voc.data") cmap = matplotlib.cm.get_cmap('tab20') ci = np.linspace(0, 1, 20) colours = cmap(ci)[:, :3] colours = colours[:, ::-1] * 255 scn = scncd.SCNCD() frame_width = 1280 frame_height = 720 if STORE: video_name = data_dir.split('/')[-2] FPS = 30 # remember to modify frame width and height before testing video video_writer = cv2.VideoWriter( 'velocity_output_video/' + video_name + '.avi', cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'), FPS, (frame_width, frame_height)) image_paths = sorted(glob.glob(os.path.join(data_dir, '*jpg'))) sort_nicely(image_paths) ####################################################################################################3 # mot_tracker = Sort(max_age=1, min_hits=3) # create instance of the SORT tracker mot_tracker = Sort(max_age=150, min_hits=3) # create instance of the SORT tracker ####################################################################################################3 total_time = 0.0 total_det_time = 0.0 total_sort_time = 0.0 target_pts_dict = {} target_pts_appear_dict = {} for i, image_path in enumerate(tqdm(image_paths)): image = cv2.imread(image_path) track_start_time = time.time() results = dn.detect(net, meta, image_paths[i]) detect_time = time.time() - track_start_time total_det_time += detect_time sort_start_time = time.time() dets = results2dets(results, image.shape) ####################### Sort Reid ############################# feats = np.zeros((dets.shape[0], 16)) for det_id in range(len(feats)): x1 = int(dets[det_id, 0]) y1 = int(dets[det_id, 1]) x2 = int(dets[det_id, 2]) y2 = int(dets[det_id, 3]) feat = scn.compute(image[y1:y2, x1:x2]) feats[det_id] = feat trackers = mot_tracker.update(dets, feats) ####################### Sort Reid ############################# ####################### Sort ############################# # trackers = mot_tracker.update(dets) ####################### Sort ############################# end_time = time.time() cycle_time = end_time - track_start_time total_time += cycle_time sort_time = end_time - sort_start_time total_sort_time += sort_time # print("#{} frame".format(i)) # print(results) for d in trackers: target_id = d[4] if target_pts_dict.get(target_id) is None: # initialize the list of tracked points """ Ref: https://www.pyimagesearch.com/2015/09/21/opencv-track-object-movement/ """ target_pts_dict[target_id] = deque(maxlen=PT_BUFFER) target_pts_appear_dict[target_id] = 0 color = colours[int(target_id - 1) % 20] # Draw tracked bounding box cv2.rectangle(image, (int(d[0]), int(d[1])), (int(d[2]), int(d[3])), color, 3) # Show target ID cv2.rectangle(image, (int(d[0]) - 2, int(d[1] - 20)), (int(d[0]) + 20 + int(d[4]) // 10, int(d[1]) + 1), color, -1) cv2.putText(image, str(int(d[4])), (int(d[0] + 2), int(d[1]) - 3), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 0), 2) ######################################################### # Add point into trajectory ######################################################### x_center = (d[0] + d[2]) / 2 y_center = (d[1] + d[3]) / 2 if target_pts_dict.get(target_id) is not None: target_pts_dict[target_id].appendleft( (int(x_center), int(y_center))) target_pts_appear_dict[target_id] = 0 ######################################################### # Draw trajectory ######################################################### pts = target_pts_dict[target_id] # loop over the set of tracked points for pti in range(1, len(pts)): # if either of the tracked points are None, ignore them if pts[pti - 1] is None or pts[pti] is None: continue if distance(pts[pti - 1], pts[pti]) > 30: # If the distance of two consective points is too far, don't draw continue # otherwise, compute the thickness of the line and draw the connecting lines thickness = int(np.sqrt(PT_BUFFER / float(pti + 1)) * 2.5) cv2.line(image, pts[pti - 1], pts[pti], color, thickness) ######################################################### # Draw velocity direction ######################################################### velocity_x = d[5] * (d[2] - d[0]) * 0.5 + x_center velocity_y = d[6] * (d[3] - d[1]) * 0.5 + y_center cv2.arrowedLine(image, (int(x_center), int(y_center)), (int(velocity_x), int(velocity_y)), color, 2) ######################################################### # FPS information cv2.putText(image, ' Tracking FPS = {:.2f}'.format(1 / cycle_time + 3), (frame_width - 350, 25), cv2.FONT_HERSHEY_SIMPLEX, 1e-3 * image.shape[0], (0, 250, 0), 2) cv2.putText(image, ' YOLO FPS = {:.2f}'.format(1 / detect_time + 3), (frame_width - 350, 55), cv2.FONT_HERSHEY_SIMPLEX, 1e-3 * image.shape[0], (0, 250, 0), 2) cv2.putText(image, 'SORT(Reid) FPS = {:.2f}'.format(1 / sort_time), (frame_width - 350, 75), cv2.FONT_HERSHEY_SIMPLEX, 1e-3 * image.shape[0], (0, 250, 0), 2) ######################################################### if STORE: video_writer.write(image) else: cv2.imshow("output", image) cv2.waitKey(0) if i > 400: break total_frames = i + 1 print("Total Tracking took: %.3f for %d frames or %.1f FPS" % (total_time, total_frames, total_frames / total_time)) print("Total Detection took: %.3f for %d frames or %.1f FPS" % (total_det_time, total_frames, total_frames / total_det_time)) print("Total SORT took: %.3f for %d frames or %.1f FPS" % (total_sort_time, total_frames, total_frames / total_sort_time))
def online_tracking(data_dir, STORE=False): if not os.path.exists(data_dir): raise IOError("Invalid data path:", data_dir) yolo_config_path = "../config_aerial.json" with open(yolo_config_path) as config_buffer: yolo_config = json.load(config_buffer) yolo = YOLO(architecture=yolo_config['model']['architecture'], input_size=yolo_config['model']['input_size'], labels=yolo_config['model']['labels'], max_box_per_image=yolo_config['model']['max_box_per_image'], anchors=yolo_config['model']['anchors']) yolo_weights_path = "../yolo_coco_aerial_person.h5" print("YOLO weights path:", yolo_weights_path) yolo.load_weights(yolo_weights_path) colours = np.round(np.random.rand(32, 3) * 255) frame_width = 1280 frame_height = 720 if STORE: video_name = data_dir.split('/')[-2] FPS = 30 # remember to modify frame width and height before testing video video_writer = cv2.VideoWriter( 'output_video/' + video_name + '.avi', cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'), FPS, (frame_width, frame_height)) image_paths = sorted(glob.glob(os.path.join(data_dir, '*jpg'))) sort_nicely(image_paths) mot_tracker = Sort() # create instance of the SORT tracker total_time = 0.0 for i, image_path in enumerate(tqdm(image_paths)): image = cv2.imread(image_path) track_start_time = time.time() boxes = yolo.predict(image) detect_time = time.time() - track_start_time sort_start_time = time.time() dets = boxes2dets(boxes, image.shape) trackers = mot_tracker.update(dets) end_time = time.time() cycle_time = end_time - track_start_time total_time += cycle_time sort_time = end_time - sort_start_time for d in trackers: color = colours[int(d[4]) % 32] cv2.rectangle(image, (int(d[0]), int(d[1])), (int(d[2]), int(d[3])), color, 3) cv2.putText(image, 'id = ' + str(int(d[4])), (int(d[0]), int(d[1]) - 13), cv2.FONT_HERSHEY_SIMPLEX, 1e-3 * image.shape[0], color, 2) cv2.putText(image, 'Tracking FPS = {:.2f}'.format(1 / cycle_time), (frame_width - 300, 25), cv2.FONT_HERSHEY_SIMPLEX, 1e-3 * image.shape[0], (0, 250, 0), 2) cv2.putText(image, ' YOLO FPS = {:.2f}'.format(1 / detect_time), (frame_width - 300, 55), cv2.FONT_HERSHEY_SIMPLEX, 1e-3 * image.shape[0], (0, 250, 0), 2) cv2.putText(image, ' SORT FPS = {:.2f}'.format(1 / sort_time), (frame_width - 300, 75), cv2.FONT_HERSHEY_SIMPLEX, 1e-3 * image.shape[0], (0, 250, 0), 2) if STORE: video_writer.write(image) else: cv2.imshow("output", image) cv2.waitKey(0) if i > 450: break total_frames = i + 1 print("Total Tracking took: %.3f for %d frames or %.1f FPS" % (total_time, total_frames, total_frames / total_time))
os.makedirs('output') for vid, det in enumerate(detections): mot_tracker = Sort(max_age=150, min_hits=3) # create instance of the SORT tracker seq_dets = np.loadtxt(det, delimiter=',') # load detections video_name = splitext(basename(det))[0] if video_name != "person14_1": continue with open('velocity_output/' + video_name + '.txt', 'w') as out_file: print("Processing %s." % video_name) data_dir = videos[vid] image_paths = sorted(glob.glob(os.path.join(data_dir, '*jpg'))) sort_nicely(image_paths) for frame in tqdm(range(int(seq_dets[:, 0].max()))): start_time = time.time() img = cv2.imread(image_paths[frame]) cycle_time = time.time() - start_time # print("imread: {:.3f}s".format(cycle_time)) frame += 1 # detection and frame numbers begin at 1 total_frames += 1 # print("\n------------ {}th frmae start ---------------\n".format(frame)) dets = seq_dets[seq_dets[:, 0] == frame, 2:7] dets[:,
def store_output(result_dir, video_dir): """ Store tracking results to video (with velocity) Params: result_dir: string, path to tracking result directory video_dir: string, path to video frames Return: None, video will be stored in the store_path """ cmap = matplotlib.cm.get_cmap('tab20') ci = np.linspace(0, 1, 20) colours = cmap(ci)[:, :3] colours = colours[:, ::-1] * 255 # print(colours) # exit() PT_BUFFER = 64 r_paths = sorted(glob.glob(os.path.join(result_dir, '*.txt'))) sort_nicely(r_paths) for r_path in r_paths: FPS = 30 # remember to modify frame width and height before testing video frame_width = 1280 frame_height = 720 video_name = splitext(basename(r_path))[0] ############################################################################## # Modify here to ouput only one video. if video_name != 'person14_1': continue ############################################################################## store_path = 'velocity_output_video/' + video_name + '_velocity.avi' print("Store path:", store_path) video_writer = cv2.VideoWriter( store_path, cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'), FPS, (frame_width, frame_height)) video_folder = os.path.join(video_dir, video_name) image_paths = sorted(glob.glob(os.path.join(video_folder, '*.jpg'))) sort_nicely(image_paths) trk_result = np.loadtxt(r_path, delimiter=',') # trk_result[:, 2:6] = xywh_to_xyxy(trk_result[:, 2:6]) print("Stroing " + video_name) target_pts_dict = {} target_pts_appear_dict = {} for i, image_path in enumerate(tqdm(image_paths)): image = cv2.imread(image_path) for key in target_pts_appear_dict: target_pts_appear_dict[key] += 1 index_list = np.argwhere(trk_result[:, 0] == (i + 1)) if index_list.shape[0] != 0: for index in index_list[:, 0]: target_id = trk_result[index, 1] color_index = int(target_id - 1) % 20 if target_pts_dict.get(target_id) is None: # initialize the list of tracked points target_pts_dict[target_id] = deque(maxlen=PT_BUFFER) target_pts_appear_dict[target_id] = 0 color = colours[color_index] bbox = trk_result[index, 2:6] cv2.rectangle( image, (int(bbox[0]), int(bbox[1])), (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3])), color, 3) x_center = bbox[0] + bbox[2] / 2 y_center = bbox[1] + bbox[3] / 2 if target_pts_dict.get(target_id) is not None: target_pts_dict[target_id].appendleft( (int(x_center), int(y_center))) target_pts_appear_dict[target_id] = 0 pts = target_pts_dict[target_id] # loop over the set of tracked points for pti in range(1, len(pts)): # if either of the tracked points are None, ignore them if pts[pti - 1] is None or pts[pti] is None: continue # otherwise, compute the thickness of the line and draw the connecting lines thickness = int( np.sqrt(PT_BUFFER / float(pti + 1)) * 2.5) cv2.line(image, pts[pti - 1], pts[pti], color, thickness) velocity_x = trk_result[index, 10] * bbox[2] * 0.5 + x_center velocity_y = trk_result[index, 11] * bbox[3] * 0.5 + y_center cv2.arrowedLine(image, (int(x_center), int(y_center)), (int(velocity_x), int(velocity_y)), color, 2) # alpha = 0.5 # overlay = image.copy() # v_bbox = trk_result[index, -4:] # cv2.rectangle(overlay, # (int(v_bbox[0]),int(v_bbox[1])), # (int(v_bbox[2]),int(v_bbox[3])), # color, -1) # cv2.addWeighted(overlay, alpha, image, 1 - alpha, 0, image) # Tag rectangle (filled rect) cv2.rectangle( image, (int(bbox[0] - 2), int(bbox[1] - 20)), (int(bbox[0] + 20 + int(trk_result[index, 1]) // 10), int(bbox[1] + 1)), color, -1) # Index tag cv2.putText(image, str(int(trk_result[index, 1])), (int(bbox[0] + 2), int(bbox[1] - 3)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 0), 2) # cv2.imshow('g',image) # cv2.waitKey(0) # exit() for key, value in target_pts_appear_dict.items(): if value > 3: target_pts_dict.pop(key, None) target_pts_appear_dict.pop(key, None) video_writer.write(image)
def store_output(result_dir, video_dir): """ Store tracking results to video Params: result_dir: string, path to tracking result directory video_dir: string, path to video frames Return: None, video will be stored in the store_path """ cmap = matplotlib.cm.get_cmap('tab20') ci = np.linspace(0,1,20) colours = cmap(ci)[:,:3] colours = colours[:,::-1] * 255 r_paths = sorted(glob.glob(os.path.join(result_dir, '*.txt'))) sort_nicely(r_paths) for r_path in r_paths: FPS = 30 # remember to modify frame width and height before testing video frame_width = 1280 frame_height = 720 video_name = splitext(basename(r_path))[0] ############################################################################## # Modify here to ouput only one video. if video_name != 'person14_1': continue ############################################################################## store_path = 'output_video/' + video_name + '_pretty.avi' print("Store path:", store_path) video_writer = cv2.VideoWriter(store_path, cv2.VideoWriter_fourcc('M','J','P','G'), FPS, (frame_width, frame_height)) video_folder = os.path.join(video_dir, video_name) image_paths = sorted(glob.glob(os.path.join(video_folder, '*.jpg'))) sort_nicely(image_paths) trk_result = np.loadtxt(r_path, delimiter=',') trk_result[:, 2:6] = xywh_to_xyxy(trk_result[:, 2:6]) print("Stroing " + video_name) for i, image_path in enumerate(tqdm(image_paths)): image = cv2.imread(image_path) index_list = np.argwhere(trk_result[:, 0] == (i+1)) if index_list.shape[0] != 0: for index in index_list[:, 0]: target_index = trk_result[index,1] color = colours[int(target_index-1)%20] cv2.rectangle(image, (int(trk_result[index, 2]),int(trk_result[index, 3])), (int(trk_result[index, 4]),int(trk_result[index, 5])), color, 3) if target_index//10 > 0: digit = 2 else: digit = 1 # Tag rectangle (filled rect) cv2.rectangle(image, (int(trk_result[index, 2])-2,int(trk_result[index, 3]-20)), (int(trk_result[index, 2])+10*digit+10 ,int(trk_result[index, 3])+1), color, -1) # Index tag cv2.putText(image, str(int(trk_result[index, 1])), (int(trk_result[index, 2]+2), int(trk_result[index, 3])-3), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0,0,0), 2) # cv2.imshow('g',image) # cv2.waitKey(0) # exit() video_writer.write(image)