7 Commits

Author SHA1 Message Date
q
a9eb716081 fixing more broken interpolated strings 2025-09-23 15:04:13 +03:00
q
758ad12629 another bug 2025-09-23 14:59:54 +03:00
q
000822e8c8 typo fix 2025-09-23 14:53:21 +03:00
q
cdab3613c3 try interpolation over center and dimensions 2025-09-22 11:04:23 +03:00
q
40ef8d4599 faster update times for point drawing 2025-09-16 14:36:31 +03:00
q
7e3bac601d untested: modfiy-wh dont clear visibility, at interpolation toggle, refresh whole track 2025-09-16 14:24:19 +03:00
q
ded05acfb3 remove interpolation of new track 2025-09-04 15:10:17 +03:00
2 changed files with 35 additions and 18 deletions

View File

@@ -2,7 +2,7 @@ import argparse
from tsmark.video_annotator import Marker from tsmark.video_annotator import Marker
VERSION = "0.7.14" VERSION = "0.7.15"
class SmartFormatter(argparse.HelpFormatter): class SmartFormatter(argparse.HelpFormatter):

View File

@@ -710,7 +710,6 @@ class Marker:
self.points[self.point_index][self.nr]["y0"] = int(curr_point["cy"] - new_hh) self.points[self.point_index][self.nr]["y0"] = int(curr_point["cy"] - new_hh)
self.points[self.point_index][self.nr]["x1"] = int(curr_point["cx"] + new_wh) self.points[self.point_index][self.nr]["x1"] = int(curr_point["cx"] + new_wh)
self.points[self.point_index][self.nr]["y1"] = int(curr_point["cy"] + new_hh) self.points[self.point_index][self.nr]["y1"] = int(curr_point["cy"] + new_hh)
self.points[self.point_index][self.nr]["visible"] = POINT_VISIBILITY[0]
self.interpolate_set(self.point_index, self.nr) self.interpolate_set(self.point_index, self.nr)
def toggle_point_visibility(self): def toggle_point_visibility(self):
@@ -842,6 +841,7 @@ class World:
if point_index is None: if point_index is None:
point_index = self.point_index point_index = self.point_index
if not point_index in self.points: if not point_index in self.points:
self.points_interpolation_required[point_index] = []
return return
try: try:
@@ -849,7 +849,25 @@ class World:
return {"x0": x0, "y0": y0, "x1": x1, "y1": y1, "type": t, "visible": visible, "age": age} return {"x0": x0, "y0": y0, "x1": x1, "y1": y1, "type": t, "visible": visible, "age": age}
def point2array(p): def point2array(p):
return [p["x0"], p["y0"], p["x1"], p["y1"]] """cx, cy, w, h"""
return [
(p["x0"] + p["x1"]) / 2,
(p["y0"] + p["y1"]) / 2,
abs(p["x0"] - p["x1"]),
abs(p["y0"] - p["y1"]),
]
def array2point(a, visibility):
w2 = max(1, a[3] / 2)
h2 = max(1, a[4] / 2)
return {
"x0": int(a[1] - w2),
"y0": int(a[2] - h2),
"x1": int(a[1] + w2),
"y1": int(a[2] + h2),
"type": "interp",
"visible": visible,
}
if point_index in self.points_interpolation_required: if point_index in self.points_interpolation_required:
seed_keys = ( seed_keys = (
@@ -865,6 +883,10 @@ class World:
new_points = {k: v for k, v in self.points_interpolated[point_index].items()} new_points = {k: v for k, v in self.points_interpolated[point_index].items()}
if len(self.points[point_index]) == 0: # no points yet
self.points_interpolation_required[point_index] = []
return
if len(self.points[point_index]) == 1: # only one point added if len(self.points[point_index]) == 1: # only one point added
key = list(self.points[point_index].keys())[0] key = list(self.points[point_index].keys())[0]
vals = self.points[point_index][key] vals = self.points[point_index][key]
@@ -900,8 +922,8 @@ class World:
else: else:
point_keys = global_point_keys point_keys = global_point_keys
xyxy = np.array([point2array(self.points[point_index][k]) for k in point_keys]).T xywh = np.array([point2array(self.points[point_index][k]) for k in point_keys]).T
spline = PchipInterpolator(point_keys, xyxy, axis=1) spline = PchipInterpolator(point_keys, xywh, axis=1)
start_key = min(global_point_keys) start_key = min(global_point_keys)
end_key = max(global_point_keys) + 1 end_key = max(global_point_keys) + 1
@@ -915,14 +937,7 @@ class World:
for row in np.vstack((t2, spline(t2))).T: for row in np.vstack((t2, spline(t2))).T:
if row[0] in point_keys: if row[0] in point_keys:
visible = self.points[point_index][row[0]]["visible"] visible = self.points[point_index][row[0]]["visible"]
new_points[row[0]] = { new_points[row[0]] = array2point(row, visible)
"type": "interp",
"x0": int(row[1]),
"y0": int(row[2]),
"x1": int(row[3]),
"y1": int(row[4]),
"visible": visible,
}
# post points # post points
global_last = self.points[point_index][max(global_point_keys)] global_last = self.points[point_index][max(global_point_keys)]
@@ -998,6 +1013,7 @@ class World:
self.points_interpolation_enabled = not self.points_interpolation_enabled self.points_interpolation_enabled = not self.points_interpolation_enabled
if self.points_interpolation_enabled: if self.points_interpolation_enabled:
self.interpolate_thread_start() self.interpolate_thread_start()
self.interpolate_set(refresh=True)
def draw_help(self, frame): def draw_help(self, frame):
@@ -1403,7 +1419,7 @@ class World:
self.frame_raw = frame self.frame_raw = frame
if ret == True: if ret == True:
read_fails = 0 read_fails = 0
draw_wait = 200 if self.paused or (self.paused and self.point_click == 0) else 1 draw_wait = 50 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
@@ -1519,7 +1535,8 @@ class World:
elif k & 0xFF == ord("s"): # toggle crop size elif k & 0xFF == ord("s"): # toggle crop size
self.crop_click = 0 if self.crop_click == 2 else 2 self.crop_click = 0 if self.crop_click == 2 else 2
self.crop[2] = True self.crop[2] = True
elif k & 0xFF == ord("o"): # toggle point visibility (yes/occlusion/hidden) # toggle point visibility (yes/occlusion/hidden)
elif k & 0xFF == ord("o"):
if self.opts.output_points is not None: if self.opts.output_points is not None:
self.toggle_point_visibility() self.toggle_point_visibility()
elif k & 0xFF == ord("p"): # toggle points elif k & 0xFF == ord("p"): # toggle points
@@ -1550,7 +1567,7 @@ class World:
self.point_click = 0 self.point_click = 0
else: else:
self.point_index = chr(k2) self.point_index = chr(k2)
self.interpolate_set(refresh=True) self.interpolate_set(point_index=self.point_index, refresh=True)
elif k & 0xFF == ord("g"): # Go to elif k & 0xFF == ord("g"): # Go to
self.shadow_text( self.shadow_text(
frame_visu, frame_visu,
@@ -1776,7 +1793,7 @@ class TrackerGUI:
cv2.rectangle(frame, p1, p2, color, thicc, 1) cv2.rectangle(frame, p1, p2, color, thicc, 1)
cv2.imshow("tsmark - tracker", frame) cv2.imshow("tsmark - tracker", frame)
# speed up fps by 2 # speed up fps by 2
time_to_wait = 0.2 if paused else (self.marker.viewer_spf / 2 - time.time() + show_time) time_to_wait = 0.05 if paused else (self.marker.viewer_spf / 2 - time.time() + show_time)
k = cv2.waitKey(max(1, int(time_to_wait * 1000))) k = cv2.waitKey(max(1, int(time_to_wait * 1000)))
if k & 0xFF == ord("q") or k & 0xFF == 13: # accept with q or enter if k & 0xFF == ord("q") or k & 0xFF == 13: # accept with q or enter
done = True done = True