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