tracking
This commit is contained in:
@@ -282,7 +282,7 @@ class Marker:
|
|||||||
(current[1], current[2]),
|
(current[1], current[2]),
|
||||||
(current[3], current[4]),
|
(current[3], current[4]),
|
||||||
color,
|
color,
|
||||||
1,
|
2,
|
||||||
)
|
)
|
||||||
cv2.circle(frame, (current[6], current[7]), 10, color, 1)
|
cv2.circle(frame, (current[6], current[7]), 10, color, 1)
|
||||||
|
|
||||||
@@ -483,80 +483,13 @@ class Marker:
|
|||||||
if self.opts.output_points is None:
|
if self.opts.output_points is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
old_nr = self.nr
|
tracker_gui = TrackerGUI(self)
|
||||||
|
if len(tracker_gui.points) > 0:
|
||||||
curr_point = self.get_point()
|
for nr in tracker_gui.points:
|
||||||
if curr_point[0] is None:
|
self.points[self.point_index][nr] = tracker_gui.points[nr]
|
||||||
self.add_message("Not in point frame (green)")
|
self.interpolate_points()
|
||||||
return
|
self.nr = max(tracker_gui.points)-1
|
||||||
|
self.read_next = True
|
||||||
max_frames = int(min(self.point_tracking_length * self.fps, self.frames - self.nr - 1))
|
|
||||||
cv2.namedWindow("tsmark - tracker", flags=cv2.WINDOW_AUTOSIZE | cv2.WINDOW_KEEPRATIO | cv2.WINDOW_GUI_NORMAL)
|
|
||||||
tracker = cv2.TrackerKCF_create()
|
|
||||||
|
|
||||||
self.video_reader.set(cv2.CAP_PROP_POS_FRAMES, self.nr)
|
|
||||||
ok, frame = self.video_reader.read()
|
|
||||||
frame = cv2.resize(frame.copy(), self.video_res)
|
|
||||||
bbox = tuple([*curr_point[0:2], *curr_point[6:8]])
|
|
||||||
ok = tracker.init(frame, bbox)
|
|
||||||
tracked = {}
|
|
||||||
for i in range(max_frames):
|
|
||||||
# Read a new frame
|
|
||||||
ok, frame = self.video_reader.read()
|
|
||||||
frame = cv2.resize(frame.copy(), self.video_res)
|
|
||||||
if not ok:
|
|
||||||
break
|
|
||||||
|
|
||||||
ok, bbox = tracker.update(frame)
|
|
||||||
# Draw bounding box
|
|
||||||
if ok:
|
|
||||||
# Tracking success
|
|
||||||
p1 = (int(bbox[0]), int(bbox[1]))
|
|
||||||
p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3]))
|
|
||||||
cv2.rectangle(frame, p1, p2, (255, 0, 0), 2, 1)
|
|
||||||
tracked[i] = bbox
|
|
||||||
cv2.putText(frame, "Tracking...", (100, 80), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)
|
|
||||||
else:
|
|
||||||
# Tracking failure
|
|
||||||
cv2.putText(
|
|
||||||
frame, "Tracking failure detected", (100, 80), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2
|
|
||||||
)
|
|
||||||
|
|
||||||
# Display result
|
|
||||||
cv2.imshow("tsmark - tracker", frame)
|
|
||||||
|
|
||||||
# Exit if ESC pressed
|
|
||||||
if cv2.waitKey(1) & 0xFF == ord("q"): # if press SPACE bar
|
|
||||||
break
|
|
||||||
|
|
||||||
done = False
|
|
||||||
while True:
|
|
||||||
if done:
|
|
||||||
break
|
|
||||||
self.video_reader.set(cv2.CAP_PROP_POS_FRAMES, self.nr + 1)
|
|
||||||
for i in range(max_frames):
|
|
||||||
show_time = time.time()
|
|
||||||
ok, frame = self.video_reader.read()
|
|
||||||
frame = cv2.resize(frame.copy(), self.video_res)
|
|
||||||
cv2.putText(frame, "Replay...", (100, 80), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)
|
|
||||||
if i in tracked:
|
|
||||||
bbox = tracked[i]
|
|
||||||
p1 = (int(bbox[0]), int(bbox[1]))
|
|
||||||
p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3]))
|
|
||||||
cv2.rectangle(frame, p1, p2, (255, 0, 0), 2, 1)
|
|
||||||
cv2.imshow("tsmark - tracker", frame)
|
|
||||||
if cv2.waitKey(1) & 0xFF == ord("q"): # if press SPACE bar
|
|
||||||
done = True
|
|
||||||
break
|
|
||||||
|
|
||||||
time_to_wait = self.viewer_spf - time.time() + show_time
|
|
||||||
if time_to_wait > 0:
|
|
||||||
time.sleep(time_to_wait)
|
|
||||||
|
|
||||||
cv2.destroyWindow("tsmark - tracker")
|
|
||||||
|
|
||||||
self.nr = old_nr - 1
|
|
||||||
self.read_next = True
|
|
||||||
|
|
||||||
def interpolate_points(self):
|
def interpolate_points(self):
|
||||||
|
|
||||||
@@ -936,7 +869,7 @@ class Marker:
|
|||||||
ret, frame = self.video_reader.read()
|
ret, frame = self.video_reader.read()
|
||||||
if ret == True:
|
if ret == True:
|
||||||
|
|
||||||
draw_wait = 200 if self.paused or self.point_click == 0 else 1
|
draw_wait = 200 if self.paused or ( self.paused and self.point_click == 0 ) else 1
|
||||||
|
|
||||||
if (not self.paused) or self.read_next:
|
if (not self.paused) or self.read_next:
|
||||||
self.read_next = False
|
self.read_next = False
|
||||||
@@ -1037,7 +970,7 @@ class Marker:
|
|||||||
|
|
||||||
elif k & 0xFF == ord("f"): # modify FPS
|
elif k & 0xFF == ord("f"): # modify FPS
|
||||||
FPS_modifier = (FPS_modifier + 1) % len(FPS_modifiers)
|
FPS_modifier = (FPS_modifier + 1) % len(FPS_modifiers)
|
||||||
self.add_message(f"Player speed {FPS_modifiers[FPS_modifier]}")
|
self.add_message(f"Player speed {round(1/FPS_modifiers[FPS_modifier],2)}")
|
||||||
elif k & 0xFF == ord("a"): # toggle crop offset
|
elif k & 0xFF == ord("a"): # toggle crop offset
|
||||||
self.crop_click = 0 if self.crop_click == 1 else 1
|
self.crop_click = 0 if self.crop_click == 1 else 1
|
||||||
self.crop[2] = True
|
self.crop[2] = True
|
||||||
@@ -1064,6 +997,54 @@ class Marker:
|
|||||||
self.point_click = 0
|
self.point_click = 0
|
||||||
else:
|
else:
|
||||||
self.point_index = chr(k2)
|
self.point_index = chr(k2)
|
||||||
|
elif k & 0xFF == ord("g"): # Go to
|
||||||
|
self.shadow_text(
|
||||||
|
frame_visu,
|
||||||
|
"Enter frame or time",
|
||||||
|
(20, 70),
|
||||||
|
0.9,
|
||||||
|
2,
|
||||||
|
(255,255,255),
|
||||||
|
)
|
||||||
|
cv2.imshow("tsmark", frame_visu)
|
||||||
|
entered_chars=""
|
||||||
|
while True:
|
||||||
|
frame_query = frame_visu.copy()
|
||||||
|
self.shadow_text(
|
||||||
|
frame_query,
|
||||||
|
entered_chars,
|
||||||
|
(20, 100),
|
||||||
|
0.9,
|
||||||
|
2,
|
||||||
|
(255,255,255),
|
||||||
|
)
|
||||||
|
cv2.imshow("tsmark", frame_query)
|
||||||
|
del frame_query
|
||||||
|
k2 = cv2.waitKey(0)
|
||||||
|
if k2 & 0xFF == ord("q") or k2 & 0xFF == 27:
|
||||||
|
break
|
||||||
|
elif k2 & 0xFF == ord("g") or k2 & 0xFF == 13:
|
||||||
|
try:
|
||||||
|
self.nr = int(entered_chars) -1
|
||||||
|
except ValueError:
|
||||||
|
try:
|
||||||
|
self.nr = self.parse_time(entered_chars)
|
||||||
|
except Exception:
|
||||||
|
self.add_message("Cannot parse time")
|
||||||
|
break
|
||||||
|
self.read_next = True
|
||||||
|
break
|
||||||
|
elif k2 & 0xFF == 8: # backspace
|
||||||
|
entered_chars = entered_chars[0:-1]
|
||||||
|
elif k2 & 0xFF in digits_ords:
|
||||||
|
entered_chars += str(digits_ords.index(k2 & 0xFF))
|
||||||
|
elif k2 & 0xFF == ord(":"):
|
||||||
|
entered_chars += ":"
|
||||||
|
elif k2 & 0xFF == ord("."):
|
||||||
|
entered_chars += "."
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
elif k & 0xFF == ord("t"): # tracking
|
elif k & 0xFF == ord("t"): # tracking
|
||||||
self.track_point()
|
self.track_point()
|
||||||
@@ -1106,3 +1087,150 @@ class Marker:
|
|||||||
cv2.destroyAllWindows()
|
cv2.destroyAllWindows()
|
||||||
self.print_timestamps()
|
self.print_timestamps()
|
||||||
self.save_timestamps()
|
self.save_timestamps()
|
||||||
|
|
||||||
|
|
||||||
|
class TrackerGUI:
|
||||||
|
def __init__(self, marker):
|
||||||
|
|
||||||
|
self.marker = marker
|
||||||
|
self.start()
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
|
||||||
|
|
||||||
|
old_nr = self.marker.nr
|
||||||
|
|
||||||
|
curr_point = self.marker.get_point()
|
||||||
|
if curr_point[0] is None:
|
||||||
|
self.marker.add_message("Not in point frame (green)")
|
||||||
|
return
|
||||||
|
|
||||||
|
max_frames = int(min(self.marker.point_tracking_length * self.marker.fps, self.marker.frames - self.marker.nr - 1))
|
||||||
|
cv2.namedWindow("tsmark - tracker", flags=cv2.WINDOW_AUTOSIZE | cv2.WINDOW_KEEPRATIO | cv2.WINDOW_GUI_NORMAL)
|
||||||
|
tracker = cv2.TrackerKCF_create()
|
||||||
|
|
||||||
|
self.marker.video_reader.set(cv2.CAP_PROP_POS_FRAMES, self.marker.nr)
|
||||||
|
ok, frame = self.marker.video_reader.read()
|
||||||
|
frame = cv2.resize(frame.copy(), self.marker.video_res)
|
||||||
|
bbox = tuple([*curr_point[0:2], *curr_point[6:8]])
|
||||||
|
ok = tracker.init(frame, bbox)
|
||||||
|
tracked = {}
|
||||||
|
for i in range(max_frames):
|
||||||
|
# Read a new frame
|
||||||
|
ok, frame = self.marker.video_reader.read()
|
||||||
|
frame = cv2.resize(frame.copy(), self.marker.video_res)
|
||||||
|
if not ok:
|
||||||
|
break
|
||||||
|
|
||||||
|
ok, bbox = tracker.update(frame)
|
||||||
|
# Draw bounding box
|
||||||
|
if ok:
|
||||||
|
# Tracking success
|
||||||
|
p1 = (int(bbox[0]), int(bbox[1]))
|
||||||
|
p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3]))
|
||||||
|
cv2.rectangle(frame, p1, p2, (255, 0, 0), 2, 1)
|
||||||
|
tracked[i] = [*bbox,1]
|
||||||
|
cv2.putText(frame, "Tracking...", (100, 80), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)
|
||||||
|
else:
|
||||||
|
# Tracking failure
|
||||||
|
cv2.putText(
|
||||||
|
frame, "Tracking failure detected", (100, 80), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2
|
||||||
|
)
|
||||||
|
|
||||||
|
# Display result
|
||||||
|
cv2.imshow("tsmark - tracker", frame)
|
||||||
|
|
||||||
|
# Exit if ESC pressed
|
||||||
|
if cv2.waitKey(1) & 0xFF == ord("q"): # if press SPACE bar
|
||||||
|
break
|
||||||
|
|
||||||
|
done = False
|
||||||
|
paused = False
|
||||||
|
seek = False
|
||||||
|
cut_after = max_frames
|
||||||
|
while True:
|
||||||
|
if done:
|
||||||
|
break
|
||||||
|
self.marker.video_reader.set(cv2.CAP_PROP_POS_FRAMES, self.marker.nr + 1)
|
||||||
|
i = 0
|
||||||
|
while True:
|
||||||
|
show_time = time.time()
|
||||||
|
if done:
|
||||||
|
break
|
||||||
|
if paused:
|
||||||
|
frame = frame_copy.copy()
|
||||||
|
if (not paused) or seek:
|
||||||
|
ok, frame = self.marker.video_reader.read()
|
||||||
|
frame = cv2.resize(frame.copy(), self.marker.video_res)
|
||||||
|
frame_copy = frame.copy()
|
||||||
|
i += 1
|
||||||
|
seek = False
|
||||||
|
|
||||||
|
cv2.putText(frame, f"Replay... {i}", (100, 80), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)
|
||||||
|
if i in tracked:
|
||||||
|
bbox = tracked[i]
|
||||||
|
p1 = (int(bbox[0]), int(bbox[1]))
|
||||||
|
p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3]))
|
||||||
|
color = (0,255,0) if cut_after > i else (0, 192, 192)
|
||||||
|
thicc = 2 if cut_after > i else 1
|
||||||
|
cv2.rectangle(frame, p1, p2, color, thicc, 1)
|
||||||
|
cv2.imshow("tsmark - tracker", frame)
|
||||||
|
k = cv2.waitKey(1)
|
||||||
|
if k & 0xFF == ord("q"): # if press SPACE bar
|
||||||
|
done = True
|
||||||
|
break
|
||||||
|
elif k & 0xFF == 32: # space
|
||||||
|
paused = not paused
|
||||||
|
# Movement =================
|
||||||
|
elif k & 0xFF == 83 or k & 0xFF == ord("l"): # right arrow
|
||||||
|
i += int(self.marker.fps) - 1
|
||||||
|
seek = True
|
||||||
|
elif k & 0xFF == 81 or k & 0xFF == ord("j"): # left arrow
|
||||||
|
i -= int(self.marker.fps) + 1
|
||||||
|
seek = True
|
||||||
|
# Move by frame
|
||||||
|
elif k & 0xFF == ord("."):
|
||||||
|
paused = True
|
||||||
|
seek = True
|
||||||
|
elif k & 0xFF == ord(","):
|
||||||
|
paused = True
|
||||||
|
i -= 2
|
||||||
|
seek = True
|
||||||
|
elif k & 0xFF == ord("x"):
|
||||||
|
cut_after = i
|
||||||
|
#if i in tracked:
|
||||||
|
# tracked[i][4] = 1 - tracked[i][4]
|
||||||
|
|
||||||
|
time_to_wait = self.marker.viewer_spf - time.time() + show_time
|
||||||
|
if time_to_wait > 0:
|
||||||
|
time.sleep(time_to_wait)
|
||||||
|
|
||||||
|
if i >= max_frames:
|
||||||
|
i = max_frames-1
|
||||||
|
paused = True
|
||||||
|
seek = True
|
||||||
|
if i<0:
|
||||||
|
i=0
|
||||||
|
paused = True
|
||||||
|
seek = True
|
||||||
|
|
||||||
|
if seek:
|
||||||
|
self.marker.video_reader.set(cv2.CAP_PROP_POS_FRAMES, self.marker.nr + 1 + i)
|
||||||
|
|
||||||
|
|
||||||
|
cv2.destroyWindow("tsmark - tracker")
|
||||||
|
|
||||||
|
self.marker.nr = old_nr - 1
|
||||||
|
self.marker.read_next = True
|
||||||
|
self.points = {}
|
||||||
|
for i in sorted(list(tracked.keys())):
|
||||||
|
if i >= cut_after:
|
||||||
|
continue
|
||||||
|
self.points[self.marker.nr+1+i] = [
|
||||||
|
tracked[i][0],
|
||||||
|
tracked[i][1],
|
||||||
|
tracked[i][0]+tracked[i][2],
|
||||||
|
tracked[i][1]+tracked[i][3],
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user