def main(): example = tf.train.Example() for record_path in args.records: if not os.path.isfile(record_path): print("Record %s does not exist!" % record_path) continue for record in tf.io.tf_record_iterator(record_path): example.ParseFromString(record) features = example.features.feature # dict mapping image_bytes = np.frombuffer( features["image/encoded"].bytes_list.value[0], dtype=np.uint8) image = cv2.imdecode(image_bytes, cv2.IMREAD_COLOR) im_height, im_width, _ = image.shape xmin = np.array( features['image/object/bbox/xmin'].float_list.value) * \ im_width xmax = np.array( features['image/object/bbox/xmax'].float_list.value) * \ im_width ymin = np.array( features['image/object/bbox/ymin'].float_list.value) * \ im_height ymax = np.array( features['image/object/bbox/ymax'].float_list.value) * \ im_height text = features['image/object/class/text'].bytes_list.value text = [text[i].decode('utf-8') for i in range(len(text))] width = xmax - xmin height = ymax - ymin bboxes = np.column_stack((xmin, ymin, width, height)) print("Bounding Boxes:", bboxes) image = cv2.resize(image, (0, 0), fx=args.scale, fy=args.scale) scaled_bboxes = bboxes * args.scale drawing_utils.draw_bboxes(image, scaled_bboxes, text) lines = [] filename = features['image/filename'].bytes_list.value[0] filename = filename.decode('utf-8') filename = "/".join(filename.split("/")[-3:]) lines.append("Record: %s" % record_path) lines.append(filename) lines.append("Num boxes: %d" % len(text)) for i, line in enumerate(lines): drawing_utils.shadow_text(image, line, (5, 20 * i + 15), font_scale=0.5, font_weight=1) cv2.imshow("window", image) if (cv2.waitKey(0) & 0xFF) == ord('q'): return
def mouse_callback(event, x, y, flags, params): nonlocal tracked_box, tracked_point orig, trackers, bboxes, classes = params im = orig.copy() # Determine which bbox is corresponded to by the click click = np.array([x, y]) / WINDOW_SCALE radius = 10 # If there is no tracked point, determine which point gets clicked, if # any, and set variables accordingly. if tracked_point is None and event == cv2.EVENT_LBUTTONDOWN: for i, bbox in enumerate(bboxes): top_left = bbox[:2] top_right = top_left + [bbox[2], 0] bottom_left = top_left + [0, bbox[3]] bottom_right = top_left + bbox[2:] found = False for j, p in enumerate( [top_left, top_right, bottom_left, bottom_right]): if np.linalg.norm(p - click) < radius: tracked_point = POSITIONS[j] tracked_box = i modified.add(tracked_box) found = True if found: break elif tracked_point is not None and event == cv2.EVENT_LBUTTONDOWN: tracked_point = None elif tracked_point is not None: # There must be a tracked point, so move the point to the location # of the mouse click. p0 = bboxes[tracked_box][:2] p1 = p0 + bboxes[tracked_box][2:] if tracked_point == TOP_LEFT: p0 = click elif tracked_point == TOP_RIGHT: p0[1] = click[1] p1[0] = click[0] elif tracked_point == BOTTOM_LEFT: p0[0] = click[0] p1[1] = click[1] elif tracked_point == BOTTOM_RIGHT: p1 = click bboxes[tracked_box][:2] = p0 bboxes[tracked_box][2:] = p1 - p0 drawing_utils.draw_bboxes(im, bboxes, classes, args.scale) drawing_utils.draw_dots(im, bboxes) show_scaled(window, im)
def save_frame(orig, frame, bboxes, classes, run_name, frame_count): # Scale the bboxes back down by original scale factor. # This gives us the tight bounding box for the object, rather than the one # which has been scaled for the tracker. bboxes = drawing_utils.scale_bboxes(bboxes, 1 / args.scale) frame_to_draw = orig.copy() drawing_utils.draw_bboxes(frame_to_draw, bboxes, classes) show_scaled("Saved Frame", frame_to_draw) cv2.imwrite(os.path.join(run_name, "%05d.png" % frame_count), orig) cv2.imwrite(os.path.join(run_name, "rect_%05d.png" % frame_count), frame) bbox_writer.write_bboxes(bboxes, classes, os.path.join(run_name, "%05d.txt" % frame_count))
def verify_bboxes(frame, bboxes, classes, yes): frame_to_draw = frame.copy() drawing_utils.draw_bboxes(frame_to_draw, bboxes, classes, args.scale) cv2.putText(frame_to_draw, "Do boxes look okay (y/n)?", (100, 80), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (255, 0, 0), 2) show_scaled(window, frame_to_draw) if yes: return # Confirm sanity check key = cv2.waitKey(0) & 0xFF if key == ord('n'): print("Poor bounding boxes. Quitting!") sys.exit()
def mouse_callback(event, x, y, flags, params): nonlocal tracked_point, is_top_left orig, trackers, bboxes, classes = params im = orig.copy() # Determine which bbox is corresponded to by the click click = np.array([x, y]) / WINDOW_SCALE radius = 10 # If there is no tracked point, determine which point gets clicked, if # any, and set variables accordingly. if tracked_point is None and event == cv2.EVENT_LBUTTONDOWN: for i, bbox in enumerate(bboxes): p0 = bbox[:2] p1 = p0 + bbox[2:] if np.linalg.norm(p0 - click) < radius: tracked_point = i modified.add(tracked_point) is_top_left = True break elif np.linalg.norm(p1 - click) < radius: tracked_point = i modified.add(tracked_point) is_top_left = False break elif tracked_point is not None and event == cv2.EVENT_LBUTTONDOWN: tracked_point = None elif tracked_point is not None: # There must be a tracked point, so move the point to the location # of the mouse click. p0 = bboxes[tracked_point][:2] p1 = p0 + bboxes[tracked_point][2:] if is_top_left: # No fancy handling necessary bboxes[tracked_point][:2] = click bboxes[tracked_point][2:] = p1 - click else: bboxes[tracked_point][2:] = click - bboxes[tracked_point][:2] drawing_utils.draw_bboxes(im, bboxes, classes, args.scale) drawing_utils.draw_dots(im, bboxes) show_scaled(window, im)
def mouse_callback(event, x, y, flags, params): im = params.copy() h, w, c = im.shape x = int(x / WINDOW_SCALE) y = int(y / WINDOW_SCALE) if event == cv2.EVENT_LBUTTONDOWN: points.append(np.array([x, y])) if len(points) == 1: # Still drawing a rectangle cv2.rectangle(im, tuple(points[0]), (x, y), (255, 255, 0), 1, 1) # If the mouse is moved, draw crosshairs cv2.line(im, (x, 0), (x, h), (255, 0, 0)) cv2.line(im, (0, y), (w, y), (255, 0, 0)) if len(points) == 2: # We've got a rectangle bbox = np.array([points[0], points[1] - points[0]]).reshape(-1) bbox = standardize_bbox(bbox) cls = str(current_class) bboxes.append(bbox) classes.append(cls) points.clear() # Write the bboxes out to file. # We get the filename itself, not the full path. filename = args.filename.name bbox_filename = bbox_writer.get_bbox_filename(filename) bbox_path = os.path.join(os.path.dirname(filename), bbox_filename) bbox_writer.write_bboxes(bboxes, classes, bbox_path) print("Wrote bboxes to file:", bbox_path) drawing_utils.draw_bboxes(im, bboxes, classes) cv2.putText(im, "Current class: %s" % current_class, (100, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50, 170, 50), 2) show_scaled(window, im)
def main(): vid = open_vid(args.filename.name) autoplay = False autoplay_delay = 32 stop_at_next_save = False current_frame_number = 0 last_removed_frame = -1 stored_frames = dict() # Initialize the storage on disk filename = os.path.splitext(os.path.basename(args.filename.name))[0] run_name = "%s" % (filename) + "_labels" run_path = os.path.join(os.path.dirname(args.filename.name), run_name) try: os.mkdir(run_path) except: print("Directory probably exists already, continuing anyway.") while True: is_save_frame = (args.frames > 0 and current_frame_number % args.frames == 0) if current_frame_number not in stored_frames: ret, frame = vid.read() if not ret: print("Unable to open frame, quitting!") break # If this is a frame we care about, save it to disk. Also, see if # there is already a saved set of bboxes, and load those if they # exist. bboxes, classes = load_bboxes(current_frame_number, run_path) stored_frames[current_frame_number] = (frame, bboxes, classes) if len(stored_frames) > CACHE_SIZE: last_removed_frame += 1 print("Removing frame", last_removed_frame, " from cache") stored_frames.pop(last_removed_frame) else: frame, bboxes, classes = stored_frames[current_frame_number] drawable_frame = frame.copy() frame_text = [ "Frame number: " + str(current_frame_number) + (" (saved)" if is_save_frame else ""), "Autoplay: " + str(autoplay), "Autoplay delay: " + str(autoplay_delay), "Stopping at next save frame: " + str(stop_at_next_save), ] draw_frame_text(drawable_frame, frame_text) drawing_utils.draw_bboxes(drawable_frame, bboxes, classes) show_scaled(WINDOW, drawable_frame) if autoplay: delay = autoplay_delay if autoplay else 0 key = cv2.waitKey(delay) & 0xFF else: key = label_frame(frame, bboxes, classes, frame_text) if is_save_frame: save_frame(frame, bboxes, classes, run_path, current_frame_number) if stop_at_next_save: stop_at_next_save = False autoplay = False # Handle whatever key the user pressed. The user may have potentially # labeled something, as above. if key == ord('q'): break if key == ord('l'): current_frame_number += 1 elif key == ord('h'): current_frame_number -= 1 current_frame_number = max(current_frame_number, last_removed_frame + 1) elif key == ord('j'): autoplay_delay = max(autoplay_delay // 2, 1) elif key == ord('k'): autoplay_delay *= 2 elif key == ord(' '): autoplay = not autoplay autoplay_delay = 32 elif key == ord('n'): stop_at_next_save = True autoplay = True autoplay_delay = 1 current_frame_number += 1 elif autoplay: current_frame_number += 1 vid.release() cv2.destroyAllWindows()
def draw(frame): drawing_utils.draw_bboxes(frame, bboxes, classes) draw_frame_text(frame, frame_text + ["Current class: %s" % current_class]) show_scaled(WINDOW, frame)
def main(): vid = open_vid(args.filename.name) rotate_image = args.rotate validation = args.validation autoplay = False autoplay_delay = 32 stop_at_next_save = False global brightness current_frame_number = 0 last_removed_frame = -1 stored_frames = dict() # Initialize the storage on disk filename = os.path.splitext(os.path.basename(args.filename.name))[0] if args.run_path == "": run_name = "%s" % (filename) run_path = os.path.join(os.path.dirname(args.filename.name), run_name) try: os.mkdir(run_path) except: print("Directory probably exists already, continuing anyway.") else: run_path = args.run_path if not os.path.isdir(run_path): print("Run path %s is not a directory!" % run_path) return while True: is_save_frame = (args.frames > 0 and current_frame_number % args.frames == 0) if current_frame_number not in stored_frames: ret, frame = vid.read() if not ret: print("Unable to open frame, quitting!") break # If this is a frame we care about, save it to disk. Also, see if # there is already a saved set of bboxes, and load those if they # exist. bboxes, classes = load_bboxes(current_frame_number, run_path) stored_frames[current_frame_number] = (frame, bboxes, classes) if len(stored_frames) > CACHE_SIZE: last_removed_frame += 1 stored_frames.pop(last_removed_frame) else: frame, bboxes, classes = stored_frames[current_frame_number] if rotate_image: frame = frame[::-1, ::-1, :] # Makes a copy drawable_frame = frame.copy() frame_text = [ "Frame number: " + str(current_frame_number) + (" (saved)" if is_save_frame else ""), "Autoplay: " + str(autoplay), "Autoplay delay: " + str(autoplay_delay), "Stopping at next save frame: " + str(stop_at_next_save), "Validation mode: " + str(validation), ] draw_frame_text(drawable_frame, frame_text) drawing_utils.draw_bboxes(drawable_frame, bboxes, classes) show_scaled(WINDOW, drawable_frame) if autoplay: delay = autoplay_delay if autoplay else 0 key = cv2.waitKey(delay) & 0xFF else: key = label_frame(frame, bboxes, classes, frame_text) if is_save_frame: save_frame(frame, bboxes, classes, run_path, current_frame_number, validation) if stop_at_next_save: stop_at_next_save = False autoplay = False # Handle whatever key the user pressed. The user may have potentially # labeled something, as above. if key == ord('q'): break elif key == ord('r'): rotate_image = not rotate_image elif key == ord('v'): validation = not validation elif key == ord('l'): current_frame_number += 1 elif key == ord('h'): current_frame_number -= 1 current_frame_number = max(current_frame_number, last_removed_frame + 1) elif key == ord('j'): autoplay_delay = max(autoplay_delay // 2, 1) elif key == ord('k'): autoplay_delay *= 2 elif key == ord(' '): autoplay = not autoplay autoplay_delay = 32 elif key == ord('n'): stop_at_next_save = True autoplay = True autoplay_delay = 1 current_frame_number += 1 elif key == ord('+') or key == ord('='): brightness = min(brightness + 0.1, 3.0) elif key == ord('-') or key == ord('_'): brightness = max(brightness - 0.1, 0) elif autoplay: current_frame_number += 1 vid.release() cv2.destroyAllWindows()
boxes = [] for i in range(result['num_detections']): if result['detection_scores'][i] > args.threshold: class_ = result['detection_classes'][i] box = result['detection_boxes'][i] score = result['detection_scores'][i] y1, x1 = int(box[0] * h), int(box[1] * w) y2, x2 = int(box[2] * h), int(box[3] * w) boxes.append((class_, score, x1, y1, x2, y2)) bboxes = [ np.array([x1, y1, x2 - x1, y2 - y1]) for (cls, score, x1, y1, x2, y2) in boxes ] classes = [objdet.category_index[int(cls)]['name'] for cls, *_ in boxes] drawing_utils.draw_bboxes(img, bboxes, classes) print("Frame:", counter, end="\r") img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) drawing_utils.shadow_text( img, "Frame Rate: %0.2f" % (1.0 / (det_end - det_start)), (0, 20)) if not args.headless: cv2.imshow('image', img) if cv2.waitKey(1) & 0xFF == ord('q'): break if args.write_movie: writer.write(img) if args.write_images:
def correction_mode(orig, trackers, bboxes, classes, annotated_classes): frame = orig.copy() drawing_utils.draw_bboxes(frame, bboxes, annotated_classes, args.scale) drawing_utils.draw_dots(frame, bboxes) show_scaled(window, frame) modified = set() tracked_point = None is_top_left = False def mouse_callback(event, x, y, flags, params): nonlocal tracked_point, is_top_left orig, trackers, bboxes, classes = params im = orig.copy() # Determine which bbox is corresponded to by the click click = np.array([x, y]) / WINDOW_SCALE radius = 10 # If there is no tracked point, determine which point gets clicked, if # any, and set variables accordingly. if tracked_point is None and event == cv2.EVENT_LBUTTONDOWN: for i, bbox in enumerate(bboxes): p0 = bbox[:2] p1 = p0 + bbox[2:] if np.linalg.norm(p0 - click) < radius: tracked_point = i modified.add(tracked_point) is_top_left = True break elif np.linalg.norm(p1 - click) < radius: tracked_point = i modified.add(tracked_point) is_top_left = False break elif tracked_point is not None and event == cv2.EVENT_LBUTTONDOWN: tracked_point = None elif tracked_point is not None: # There must be a tracked point, so move the point to the location # of the mouse click. p0 = bboxes[tracked_point][:2] p1 = p0 + bboxes[tracked_point][2:] if is_top_left: # No fancy handling necessary bboxes[tracked_point][:2] = click bboxes[tracked_point][2:] = p1 - click else: bboxes[tracked_point][2:] = click - bboxes[tracked_point][:2] drawing_utils.draw_bboxes(im, bboxes, classes, args.scale) drawing_utils.draw_dots(im, bboxes) show_scaled(window, im) cv2.setMouseCallback(window, mouse_callback, param=(orig, trackers, bboxes, annotated_classes)) while True: key = cv2.waitKey(1) & 0xFF if key == ord('c') or key == ord(' '): for mod in modified: print("Reinitializing tracker %d" % mod) new_tracker = init_trackers(args.tracker, orig, [bboxes[mod]]) trackers[mod] = new_tracker[0] break elif key == ord('r'): refine_bboxes(bboxes, classes, orig, trackers) # Clear the mouse callback cv2.setMouseCallback(window, lambda *args: None)
if not ret: print("Tracking failure for object", i) bboxes.append(None) annotated_classes.append("[FAILURE] %d:%s" % (i, classes[i])) else: bboxes.append(np.array(bbox)) annotated_classes.append("%d:%s" % (i, classes[i])) if args.refine: refine_bboxes(bboxes, classes, frame, trackers) end = time.time() fps = 1.0 / (end - start) original = frame.copy() drawing_utils.draw_bboxes(frame, bboxes, annotated_classes, args.scale) # Potentially save the frame to disk using @dek's format if args.frames > 0 and frame_count % args.frames == 0: save_frame(original, frame, bboxes, classes, run_path, frame_count) drawing_utils.shadow_text(frame, tracker_name, (100, 20)) drawing_utils.shadow_text(frame, "FPS: " + str(int(fps)), (100, 50)) drawing_utils.shadow_text(frame, "Frame: " + str(frame_count), (100, 80)) # Display result show_scaled(window, frame) if not args.experiment: writer.write(frame)
def correction_mode(orig, trackers, bboxes, classes, annotated_classes): frame = orig.copy() drawing_utils.draw_bboxes(frame, bboxes, annotated_classes, args.scale) drawing_utils.draw_dots(frame, bboxes) show_scaled(window, frame) modified = set() tracked_box = None tracked_point = None TOP_LEFT = 0 TOP_RIGHT = 1 BOTTOM_LEFT = 2 BOTTOM_RIGHT = 3 POSITIONS = [TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT] def mouse_callback(event, x, y, flags, params): nonlocal tracked_box, tracked_point orig, trackers, bboxes, classes = params im = orig.copy() # Determine which bbox is corresponded to by the click click = np.array([x, y]) / WINDOW_SCALE radius = 10 # If there is no tracked point, determine which point gets clicked, if # any, and set variables accordingly. if tracked_point is None and event == cv2.EVENT_LBUTTONDOWN: for i, bbox in enumerate(bboxes): top_left = bbox[:2] top_right = top_left + [bbox[2], 0] bottom_left = top_left + [0, bbox[3]] bottom_right = top_left + bbox[2:] found = False for j, p in enumerate( [top_left, top_right, bottom_left, bottom_right]): if np.linalg.norm(p - click) < radius: tracked_point = POSITIONS[j] tracked_box = i modified.add(tracked_box) found = True if found: break elif tracked_point is not None and event == cv2.EVENT_LBUTTONDOWN: tracked_point = None elif tracked_point is not None: # There must be a tracked point, so move the point to the location # of the mouse click. p0 = bboxes[tracked_box][:2] p1 = p0 + bboxes[tracked_box][2:] if tracked_point == TOP_LEFT: p0 = click elif tracked_point == TOP_RIGHT: p0[1] = click[1] p1[0] = click[0] elif tracked_point == BOTTOM_LEFT: p0[0] = click[0] p1[1] = click[1] elif tracked_point == BOTTOM_RIGHT: p1 = click bboxes[tracked_box][:2] = p0 bboxes[tracked_box][2:] = p1 - p0 drawing_utils.draw_bboxes(im, bboxes, classes, args.scale) drawing_utils.draw_dots(im, bboxes) show_scaled(window, im) cv2.setMouseCallback(window, mouse_callback, param=(orig, trackers, bboxes, annotated_classes)) while True: key = cv2.waitKey(1) & 0xFF if key == ord('c') or key == ord(' '): for mod in modified: print("Reinitializing tracker %d" % mod) new_tracker = init_trackers(args.tracker, orig, [bboxes[mod]]) trackers[mod] = new_tracker[0] break elif key == ord('r'): refine_bboxes(bboxes, classes, orig, trackers) # Clear the mouse callback cv2.setMouseCallback(window, lambda *args: None)
def main(): vid = open_vid(args.filename.name) back_track = False prev_classes = [] backward = False frame_classes = [] trackers = [] classes = [] bboxes = [] back_first = False tracker_index = args.tracker tracker_fn = tracker_fns[tracker_index] tracker_name = tracker_fn.__name__.split("_")[0] rotate_image = args.rotate validation = args.validation autoplay = False autoplay_delay = 32 stop_at_next_save = False global brightness current_frame_number = 0 last_removed_frame = -1 stored_frames = dict() # Initialize the storage on disk filename = os.path.splitext(os.path.basename(args.filename.name))[0] if args.run_path == "": run_name = "%s" % (filename) run_path = os.path.join(os.path.dirname(args.filename.name), run_name) if not args.experiment: try: os.mkdir(run_path) except: print("Directory probably exists already, continuing anyway.") else: run_path = args.run_path if not os.path.isdir(run_path): print("Run path %s is not a directory!" % run_path) return while True: is_save_frame = (args.frames > 0 and current_frame_number % args.frames == 0) new_bboxes = [] temp_bboxes = [] annotated_classes = [] bboxes = [] # print("%d:%d:%d" % (len(bboxes), len(classes), current_frame_number)) if (current_frame_number not in stored_frames): ret, frame = vid.read() if not ret: print("Unable to open frame, quitting!") break # If this is a frame we care about, save it to disk. Also, see if # there is already a saved set of bboxes, and load those if they # exist. if validation: bboxes, classes = load_bboxes(current_frame_number, run_path) else: scaled_frame = scale_frame_for_tracking(frame) rem = [] for i, tracker in enumerate(trackers): ret, bbox = tracker.update(scaled_frame) bbox = unscale_bbox_for_tracking(bbox) if not ret: bboxes.append(None) rem.append(i) print("Tracking failure for %s" % classes[i]) elif not check_bbox(bbox, frame): bboxes.append(None) rem.append(i) print("%s lost" % classes[i]) else: bboxes.append(np.array(bbox)) #annotated_classes.append("%d:%s" % (i, classes[i])) n = 0 for i in rem: j = i - n bboxes.pop(j) classes.pop(j) trackers.pop(j) n += 1 if args.refine: refine_bboxes(bboxes, classes, frame, trackers) # stored_frames[current_frame_number] = (frame.copy(), bboxes.copy(), classes.copy()) if len(stored_frames) > CACHE_SIZE: last_removed_frame += 1 stored_frames.pop(last_removed_frame) else: frame, temp_bboxes, temp_classes = stored_frames[ current_frame_number] if (not validation) and ((back_track and not back_first) or not temp_bboxes): scaled_frame = scale_frame_for_tracking(frame) rem = [] for i, tracker in enumerate(trackers): ret, bbox = tracker.update(scaled_frame) bbox = unscale_bbox_for_tracking(bbox) if not ret: bboxes.append(None) rem.append(i) print("Tracking failure for %s" % classes[i]) elif not check_bbox(bbox, frame): bboxes.append(None) rem.append(i) print("%s lost" % classes[i]) else: bboxes.append(np.array(bbox)) #annotated_classes.append("%d:%s" % (i, classes[i])) n = 0 for i in rem: j = i - n bboxes.pop(j) classes.pop(j) trackers.pop(j) n += 1 if args.refine: refine_bboxes(bboxes, classes, frame, trackers) elif back_first: back_first = False bboxes = temp_bboxes classes = temp_classes else: bboxes = temp_bboxes classes = temp_classes trackers.clear() add_trackers(tracker_index, frame.copy(), bboxes.copy(), trackers) # stored_frames[current_frame_number] = (frame.copy(), bboxes.copy(), classes.copy()) if rotate_image: frame = frame[::-1, ::-1, :] # Makes a copy drawable_frame = frame.copy() frame_text = [ "Frame number: " + str(current_frame_number) + (" (saved)" if is_save_frame else ""), "Autoplay: " + str(autoplay), "Autoplay delay: " + str(autoplay_delay), "Stopping at next save frame: " + str(stop_at_next_save), "Validation mode: " + str(validation), "Backward Tracking: " + str(back_track), ] draw_frame_text(drawable_frame, frame_text) # print("%d:%d:%d" % (len(bboxes), len(classes), current_frame_number)) drawing_utils.draw_bboxes(drawable_frame, bboxes, classes) show_scaled(WINDOW, drawable_frame) if autoplay: delay = autoplay_delay if autoplay else 0 key = cv2.waitKey(delay) & 0xFF elif backward: delay = autoplay_delay if backward else 0 key = cv2.waitKey(delay) & 0xFF else: key = label_frame(frame, bboxes, new_bboxes, classes, frame_text, trackers) if is_save_frame: save_frame(frame, bboxes, classes, run_path, current_frame_number, validation) if stop_at_next_save: stop_at_next_save = False autoplay = False backward = False ## if not validation: add_trackers(tracker_index, frame.copy(), new_bboxes.copy(), trackers) stored_frames[current_frame_number] = (frame.copy(), bboxes.copy(), classes.copy()) original = frame.copy() # Handle whatever key the user pressed. The user may have potentially # labeled something, as above. if key == ord('q'): break elif key == ord('d'): rotate_image = not rotate_image elif key == ord('w'): validation = not validation elif key == ord('l'): current_frame_number += 1 back_track = False elif key == ord('g'): current_frame_number -= 1 current_frame_number = max(current_frame_number, last_removed_frame + 1) elif key == ord('j'): autoplay_delay = max(autoplay_delay // 2, 1) elif key == ord('k'): autoplay_delay *= 2 elif key == ord(' '): autoplay = not autoplay autoplay_delay = 32 back_track = False elif key == ord('m'): back_track = not back_track back_first = True elif key == ord('v'): backward = True stop_at_next_save = True current_frame_number -= 1 elif key == ord('e'): correction_mode(original, trackers, bboxes, classes) stored_frames[current_frame_number] = (original.copy(), bboxes.copy(), classes.copy()) elif key == ord('n'): stop_at_next_save = True autoplay = True autoplay_delay = 1 current_frame_number += 1 back_track = False elif key == ord('+') or key == ord('='): brightness = min(brightness + 0.1, 3.0) elif key == ord('-') or key == ord('_'): brightness = max(brightness - 0.1, 0) elif autoplay: current_frame_number += 1 elif backward: current_frame_number -= 1 current_frame_number = max(current_frame_number, last_removed_frame + 1) vid.release() cv2.destroyAllWindows()