visibility toggle change

This commit is contained in:
q
2025-08-18 13:53:35 +03:00
parent c1fe758b87
commit 6d2f5189b7
2 changed files with 72 additions and 45 deletions

View File

@@ -19,6 +19,15 @@ VIDEO_COPY = "-c:v copy".split(" ")
EXT_COMPRESS = ".mpeg"
PLUGIN_FOLDER = os.path.expanduser("~/.config/tsmark/plugins")
COLOR_PREPOST = (0, 128, 128)
COLOR_KEY = (60, 205, 60)
COLOR_KEY_OCCLUDED = (60, 96, 60)
COLOR_INTERP = (192, 0, 192)
COLOR_INTERP_OCCLUDED = (128, 0, 128)
COLOR_HIDDEN = (60, 60, 60)
COLOR_NONE = (255, 255, 255)
POINT_VISIBILITY = ("yes", "occluded", "hidden")
class Marker:
def __init__(self, opts):
@@ -178,7 +187,7 @@ class Marker:
cv2.circle(frame, (p_pos, bar_middle), 3, (32, 32, 32), -1)
for ts in self.points[self.point_index]:
p_pos = int(self.bar_start + ts / self.frames * (self.bar_end - self.bar_start))
color = (60, 205, 60) if self.points[self.point_index][ts]["visible"] == 1 else (96, 96, 96)
color = self.get_point_color(self.points[self.point_index][ts])
cv2.circle(frame, (p_pos, bar_middle), 1, color, -1)
cv2.line(
@@ -255,14 +264,9 @@ class Marker:
current = self.get_interpolated_point(index=index)
if current["type"] in ("pre", "post"):
continue
color = (0, 192, 192)
if current["type"] == "key":
color = (60, 205, 60)
if current["type"] == "interp":
color = (192, 0, 192)
if current["visible"] == 0:
color = (96, 96, 96)
if current["visible"] == "hidden":
continue
color = self.get_point_color(current)
cv2.circle(frame, (current["cx"], current["cy"]), 10, (0, 0, 0), 2)
cv2.circle(frame, (current["cx"], current["cy"]), 10, color, 1)
self.shadow_text(
@@ -295,13 +299,7 @@ class Marker:
try:
current = self.get_interpolated_point()
if current["type"] is not None:
color = (0, 192, 192)
if current["type"] == "key":
color = (60, 205, 60)
if current["type"] == "interp":
color = (192, 0, 192)
if current["visible"] == 0:
color = (96, 96, 96)
color = self.get_point_color(current)
cv2.rectangle(
frame,
@@ -318,7 +316,7 @@ class Marker:
po = self.get_interpolated_point(p)
history.append([po["cx"], po["cy"]])
history = np.array(history, np.int32).reshape((-1, 1, 2))
cv2.polylines(frame, [history], False, (192, 0, 192), 1)
cv2.polylines(frame, [history], False, COLOR_INTERP, 1)
except KeyError:
print(current, self.nr)
@@ -329,7 +327,7 @@ class Marker:
try:
current = self.get_point()
if current["x0"] is not None:
cv2.circle(frame, (current["cx"], current["cy"]), 13, (60, 205, 60), 2)
cv2.circle(frame, (current["cx"], current["cy"]), 13, COLOR_KEY, 2)
except KeyError:
pass
except IndexError:
@@ -372,13 +370,12 @@ class Marker:
ip = self.get_interpolated_point()
if ip["type"] is None:
return
{"x0": None, "y0": None, "x1": None, "y1": None, "cx": None, "cy": None, "visible": 0, "type": None}
self.points[self.point_index][self.nr] = {
"x0": ip["x0"],
"y0": ip["y0"],
"x1": ip["x1"],
"y1": ip["y1"],
"visible": 1,
"visible": POINT_VISIBILITY[0],
}
self.interpolate_points()
except Exception:
@@ -413,7 +410,7 @@ class Marker:
"cy": None,
"w": None,
"h": None,
"visible": 0,
"visible": None,
}
def get_interpolated_point(self, nr=None, index=None):
@@ -441,7 +438,7 @@ class Marker:
"y1": None,
"cx": None,
"cy": None,
"visible": 0,
"visible": None,
"type": None,
"age": None,
}
@@ -451,13 +448,13 @@ class Marker:
if self.point_click == 1 and self.point_index in self.points:
for nr in range(self.frames):
ip = self.get_interpolated_point(nr=nr)
if ip["type"] == "interp" and ip["visible"] == 1:
if ip["type"] == "interp" and ip["visible"] == POINT_VISIBILITY[0]:
self.points[self.point_index][nr] = {
"x0": ip["x0"],
"y0": ip["y0"],
"x1": ip["x1"],
"y1": ip["y1"],
"visible": 1,
"visible": POINT_VISIBILITY[0],
}
self.interpolate_points()
@@ -492,7 +489,7 @@ class Marker:
"y0": y,
"x1": min(self.video_res[0] - 1, x + w),
"y1": min(self.video_res[1] - 1, y + h),
"visible": 1,
"visible": POINT_VISIBILITY[0],
}
if position == "br":
self.points[self.point_index][self.nr] = {
@@ -500,7 +497,7 @@ class Marker:
"y0": max(0, y - h),
"x1": x,
"y1": y,
"visible": 1,
"visible": POINT_VISIBILITY[0],
}
if position == "c":
self.points[self.point_index][self.nr] = {
@@ -508,12 +505,12 @@ class Marker:
"y0": max(0, int(y - h / 2)),
"x1": min(self.video_res[0] - 1, int(x + w / 2)),
"y1": min(self.video_res[1] - 1, int(y + h / 2)),
"visible": 1,
"visible": POINT_VISIBILITY[0],
}
else:
# not a new point
self.points[self.point_index][self.nr]["visible"] = 1
self.points[self.point_index][self.nr]["visible"] = POINT_VISIBILITY[0]
if position == "c":
current = self.points[self.point_index][self.nr]
w = abs(current["x1"] - current["x0"])
@@ -523,7 +520,7 @@ class Marker:
"y0": max(0, int(y - h / 2)),
"x1": min(self.video_res[0] - 1, int(x + w / 2)),
"y1": min(self.video_res[1] - 1, int(y + h / 2)),
"visible": 1,
"visible": POINT_VISIBILITY[0],
}
elif position == "tl":
self.points[self.point_index][self.nr]["x0"] = x
@@ -564,7 +561,7 @@ 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"] = 1
self.points[self.point_index][self.nr]["visible"] = POINT_VISIBILITY[0]
self.interpolate_points()
@@ -579,7 +576,15 @@ class Marker:
if curr_point["x0"] is None:
self.add_message("Not in point frame (green)")
return
self.points[self.point_index][self.nr]["visible"] = 1 - self.points[self.point_index][self.nr]["visible"]
try:
new_index = (1 + POINT_VISIBILITY.index(self.points[self.point_index][self.nr]["visible"])) % len(
POINT_VISIBILITY
)
except (ValueError, KeyError):
new_index = 0
self.points[self.point_index][self.nr]["visible"] = POINT_VISIBILITY[new_index]
self.interpolate_points()
def track_point(self):
@@ -658,7 +663,6 @@ 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"]]
if not point_index in self.points:
@@ -777,6 +781,28 @@ class World:
parts = int(100 * (frame / self.fps))
return time.strftime("%H:%M:%S", time.gmtime(seconds)) + ".%02d" % (parts)
def get_point_color(self, point):
t = point.get("type", "key")
v = point.get("visible", "yes")
if v == "hidden":
return COLOR_HIDDEN
if t == "key":
if v == "yes":
return COLOR_KEY
if v == "occluded":
return COLOR_KEY_OCCLUDED
if t == "interp":
if v == "yes":
return COLOR_INTERP
if v == "occluded":
return COLOR_INTERP_OCCLUDED
if t in ("post", "pre"):
return COLOR_PREPOST
return COLOR_NONE
def get_help(self):
return """Keyboard help:
@@ -799,7 +825,7 @@ class World:
Bounding box editor:
p toggle bounding box drawing. enter any key as index.
o toggle object is occluded
o toggle object is visible/occluded/hidden
x toggle (delete) key frame
r convert interpolated points to points (no undo!)
mouse left: set top-left corner of box
@@ -810,9 +836,11 @@ class World:
t start optical flow tracker
m start plugin (if defined)
Color codes:
green keyframe
purple interpolated frame
gray object is occluded
green |keypoint
purple |interpolated
darker tone |occluded key/interpolated
yellow |post / pre points
gray |point is hidden
"""
@@ -923,7 +951,8 @@ class World:
self.points[index][key]["x1"], self.points[index][key]["y1"] = self.original_to_visual(
(self.points[index][key]["x1"], self.points[index][key]["y1"])
)
if not self.points[index][key].get("visible", "NA") in POINT_VISIBILITY:
self.points[index][key]["visible"] = POINT_VISIBILITY[0]
self.interpolate_points()
print(f"Loaded points with index: {index}")
self.point_index = None
@@ -1201,14 +1230,12 @@ 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 (occlusion)
if self.opts.output_points is None:
continue
self.toggle_point_visibility()
elif k & 0xFF == ord("o"): # toggle point visibility (yes/occlusion/hidden)
if self.opts.output_points is not None:
self.toggle_point_visibility()
elif k & 0xFF == ord("p"): # toggle points
if self.opts.output_points is None:
continue
self.point_click = 1 - self.point_click
if self.opts.output_points is not None:
self.point_click = 1 - self.point_click
if self.point_click == 1:
self.shadow_text(
frame_visu,
@@ -1494,5 +1521,5 @@ class TrackerGUI:
"y0": tracked[i][1],
"x1": tracked[i][0] + tracked[i][2],
"y1": tracked[i][1] + tracked[i][3],
"visible": 1,
"visible": POINT_VISIBILITY[0],
}