|
|
|
|
@@ -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]["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]["visible"] = POINT_VISIBILITY[0]
|
|
|
|
|
self.interpolate_set(self.point_index, self.nr)
|
|
|
|
|
|
|
|
|
|
def toggle_point_visibility(self):
|
|
|
|
|
@@ -814,7 +813,7 @@ class World:
|
|
|
|
|
return True
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def interpolate_set(self, point_index=None, nr=None):
|
|
|
|
|
def interpolate_set(self, point_index=None, nr=None, refresh=False):
|
|
|
|
|
|
|
|
|
|
if point_index is None:
|
|
|
|
|
point_index = self.point_index
|
|
|
|
|
@@ -823,6 +822,11 @@ class World:
|
|
|
|
|
if not point_index in self.points_interpolation_required:
|
|
|
|
|
self.points_interpolation_required[point_index] = []
|
|
|
|
|
self.points_interpolation_required[point_index].append(nr)
|
|
|
|
|
if refresh:
|
|
|
|
|
# refresh all points
|
|
|
|
|
if point_index in self.points:
|
|
|
|
|
self.points_interpolation_required[point_index].extend(list(self.points[point_index].keys()))
|
|
|
|
|
|
|
|
|
|
if not self.interpolate_thread_alive():
|
|
|
|
|
print("ERROR: Interpolator thread is not running!")
|
|
|
|
|
self.interpolate_thread_start()
|
|
|
|
|
@@ -837,6 +841,7 @@ class World:
|
|
|
|
|
if point_index is None:
|
|
|
|
|
point_index = self.point_index
|
|
|
|
|
if not point_index in self.points:
|
|
|
|
|
self.points_interpolation_required[point_index] = []
|
|
|
|
|
return
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
|
|
@@ -844,13 +849,25 @@ class World:
|
|
|
|
|
return {"x0": x0, "y0": y0, "x1": x1, "y1": y1, "type": t, "visible": visible, "age": age}
|
|
|
|
|
|
|
|
|
|
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 tryadd(s, key, l):
|
|
|
|
|
try:
|
|
|
|
|
s.add(l[key])
|
|
|
|
|
except IndexError:
|
|
|
|
|
pass
|
|
|
|
|
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:
|
|
|
|
|
seed_keys = (
|
|
|
|
|
@@ -866,6 +883,10 @@ class World:
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
key = list(self.points[point_index].keys())[0]
|
|
|
|
|
vals = self.points[point_index][key]
|
|
|
|
|
@@ -881,40 +902,28 @@ class World:
|
|
|
|
|
global_point_keys = list(sorted(list(self.points[point_index].keys())))
|
|
|
|
|
|
|
|
|
|
if len(seed_keys) > 0:
|
|
|
|
|
point_keys = set()
|
|
|
|
|
point_indexes = []
|
|
|
|
|
min_seed = min(seed_keys)
|
|
|
|
|
max_seed = max(seed_keys)
|
|
|
|
|
min_found = False
|
|
|
|
|
max_found = False
|
|
|
|
|
first_seed = None
|
|
|
|
|
for pi, nr in enumerate(global_point_keys):
|
|
|
|
|
if not min_found:
|
|
|
|
|
min_index = pi
|
|
|
|
|
if not max_found:
|
|
|
|
|
max_index = pi
|
|
|
|
|
if nr >= min_seed:
|
|
|
|
|
min_found = True
|
|
|
|
|
if nr <= max_seed:
|
|
|
|
|
tryadd(point_keys, pi, global_point_keys)
|
|
|
|
|
|
|
|
|
|
if nr >= min_seed and nr <= max_seed:
|
|
|
|
|
point_indexes.append(pi)
|
|
|
|
|
if nr > min_seed and first_seed is None:
|
|
|
|
|
first_seed = pi
|
|
|
|
|
point_indexes.append(pi)
|
|
|
|
|
if nr > max_seed:
|
|
|
|
|
max_found = True
|
|
|
|
|
break
|
|
|
|
|
if min_found:
|
|
|
|
|
for shift in range(-3, 0):
|
|
|
|
|
tryadd(point_keys, min_index + shift, global_point_keys)
|
|
|
|
|
if max_found:
|
|
|
|
|
for shift in range(2):
|
|
|
|
|
tryadd(point_keys, max_index + shift, global_point_keys)
|
|
|
|
|
else:
|
|
|
|
|
for shift in range(-3, -1):
|
|
|
|
|
tryadd(point_keys, len(global_point_keys) + shift, global_point_keys)
|
|
|
|
|
|
|
|
|
|
point_keys = list(sorted(list(point_keys)))
|
|
|
|
|
if len(point_indexes) == 0:
|
|
|
|
|
point_indexes.append(pi)
|
|
|
|
|
min_index = max(0, min(point_indexes) - 3)
|
|
|
|
|
max_index = min(len(global_point_keys) - 1, max(point_indexes) + 3)
|
|
|
|
|
point_keys = [global_point_keys[pi] for pi in range(min_index, max_index + 1)]
|
|
|
|
|
else:
|
|
|
|
|
point_keys = global_point_keys
|
|
|
|
|
|
|
|
|
|
xyxy = np.array([point2array(self.points[point_index][k]) for k in point_keys]).T
|
|
|
|
|
spline = PchipInterpolator(point_keys, xyxy, axis=1)
|
|
|
|
|
xywh = np.array([point2array(self.points[point_index][k]) for k in point_keys]).T
|
|
|
|
|
spline = PchipInterpolator(point_keys, xywh, axis=1)
|
|
|
|
|
start_key = min(global_point_keys)
|
|
|
|
|
end_key = max(global_point_keys) + 1
|
|
|
|
|
|
|
|
|
|
@@ -928,14 +937,7 @@ class World:
|
|
|
|
|
for row in np.vstack((t2, spline(t2))).T:
|
|
|
|
|
if row[0] in point_keys:
|
|
|
|
|
visible = self.points[point_index][row[0]]["visible"]
|
|
|
|
|
new_points[row[0]] = {
|
|
|
|
|
"type": "interp",
|
|
|
|
|
"x0": int(row[1]),
|
|
|
|
|
"y0": int(row[2]),
|
|
|
|
|
"x1": int(row[3]),
|
|
|
|
|
"y1": int(row[4]),
|
|
|
|
|
"visible": visible,
|
|
|
|
|
}
|
|
|
|
|
new_points[row[0]] = array2point(row, visible)
|
|
|
|
|
|
|
|
|
|
# post points
|
|
|
|
|
global_last = self.points[point_index][max(global_point_keys)]
|
|
|
|
|
@@ -988,7 +990,7 @@ class World:
|
|
|
|
|
|
|
|
|
|
def interpolate_points_in_thread(self):
|
|
|
|
|
|
|
|
|
|
self.points_interpolation_frequency = 1
|
|
|
|
|
self.points_interpolation_frequency = 0.5
|
|
|
|
|
|
|
|
|
|
while True:
|
|
|
|
|
if self.points_interpolation_thread_exit:
|
|
|
|
|
@@ -998,6 +1000,8 @@ class World:
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
for point_index in self.points_interpolation_required:
|
|
|
|
|
if self.points_interpolation_thread_exit:
|
|
|
|
|
return
|
|
|
|
|
if self.get_interpolation_required(point_index):
|
|
|
|
|
self.interpolate_points(point_index)
|
|
|
|
|
|
|
|
|
|
@@ -1009,6 +1013,7 @@ class World:
|
|
|
|
|
self.points_interpolation_enabled = not self.points_interpolation_enabled
|
|
|
|
|
if self.points_interpolation_enabled:
|
|
|
|
|
self.interpolate_thread_start()
|
|
|
|
|
self.interpolate_set(refresh=True)
|
|
|
|
|
|
|
|
|
|
def draw_help(self, frame):
|
|
|
|
|
|
|
|
|
|
@@ -1249,7 +1254,7 @@ class World:
|
|
|
|
|
)
|
|
|
|
|
if not self.points[index][key].get("visible", "NA") in POINT_VISIBILITY:
|
|
|
|
|
self.points[index][key]["visible"] = POINT_VISIBILITY[0]
|
|
|
|
|
self.interpolate_set(index, key)
|
|
|
|
|
self.interpolate_set(index, refresh=True)
|
|
|
|
|
print(f"Loaded points with index: {index}")
|
|
|
|
|
self.point_index = None
|
|
|
|
|
|
|
|
|
|
@@ -1414,7 +1419,7 @@ class World:
|
|
|
|
|
self.frame_raw = frame
|
|
|
|
|
if ret == True:
|
|
|
|
|
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:
|
|
|
|
|
self.read_next = False
|
|
|
|
|
@@ -1530,7 +1535,8 @@ class World:
|
|
|
|
|
elif k & 0xFF == ord("s"): # toggle crop size
|
|
|
|
|
self.crop_click = 0 if self.crop_click == 2 else 2
|
|
|
|
|
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:
|
|
|
|
|
self.toggle_point_visibility()
|
|
|
|
|
elif k & 0xFF == ord("p"): # toggle points
|
|
|
|
|
@@ -1561,6 +1567,7 @@ class World:
|
|
|
|
|
self.point_click = 0
|
|
|
|
|
else:
|
|
|
|
|
self.point_index = chr(k2)
|
|
|
|
|
self.interpolate_set(point_index=self.point_index, refresh=True)
|
|
|
|
|
elif k & 0xFF == ord("g"): # Go to
|
|
|
|
|
self.shadow_text(
|
|
|
|
|
frame_visu,
|
|
|
|
|
@@ -1786,7 +1793,7 @@ class TrackerGUI:
|
|
|
|
|
cv2.rectangle(frame, p1, p2, color, thicc, 1)
|
|
|
|
|
cv2.imshow("tsmark - tracker", frame)
|
|
|
|
|
# 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)))
|
|
|
|
|
if k & 0xFF == ord("q") or k & 0xFF == 13: # accept with q or enter
|
|
|
|
|
done = True
|
|
|
|
|
|