Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nn interface #280

Merged
merged 16 commits into from
Jan 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 5 additions & 9 deletions sleap/gui/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ def __init__(self, labels_path: Optional[str] = None, *args, **kwargs):
self.state["show edges"] = True
self.state["edge style"] = "Line"
self.state["fit"] = False
self.state["show trails"] = False
self.state["color predicted"] = False

self._initialize_gui()
Expand Down Expand Up @@ -389,12 +388,10 @@ def prev_vid():
key="edge style",
)

add_menu_check_item(viewMenu, "show trails", "Show Trails")

add_submenu_choices(
menu=viewMenu,
title="Trail Length",
options=(10, 20, 50),
options=(0, 10, 20, 50),
key="trail_length",
)

Expand Down Expand Up @@ -823,7 +820,6 @@ def overlay_state_connect(overlay, state_key, overlay_attribute=None):
],
)

overlay_state_connect(self.overlays["trails"], "show trails", "show")
overlay_state_connect(self.overlays["trails"], "trail_length")

overlay_state_connect(self.color_manager, "palette")
Expand All @@ -838,7 +834,7 @@ def overlay_state_connect(overlay, state_key, overlay_attribute=None):
)

# Set defaults
self.state["trail_length"] = 10
self.state["trail_length"] = 0

# Emit signals for default that may have been set earlier
self.state.emit("palette")
Expand Down Expand Up @@ -984,9 +980,6 @@ def plotFrame(self, *args, **kwargs):

self.player.plot()

if self.state["fit"]:
self.player.zoomToFit()

def _after_plot_update(self, player, frame_idx, selected_inst):
"""Called each time a new frame is drawn."""

Expand All @@ -1003,6 +996,9 @@ def _after_plot_update(self, player, frame_idx, selected_inst):
if selected_inst is not None:
player.view.selectInstance(selected_inst)

if self.state["fit"]:
player.zoomToFit()

# Update related displays
self.updateStatusMessage()
self.on_data_update([UpdateTopic.on_frame])
Expand Down
2 changes: 1 addition & 1 deletion sleap/gui/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -1453,7 +1453,7 @@ def do_action(context: CommandContext, params: dict):
# Determine range that should be affected
if context.state["has_frame_range"]:
# If range is selected in seekbar, use that
frame_range = tuple(*context.state["frame_range"])
frame_range = tuple(context.state["frame_range"])
else:
# Otherwise, range is current to last frame
frame_range = (
Expand Down
4 changes: 2 additions & 2 deletions sleap/gui/overlays/tracks.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ class TrackTrailOverlay:

labels: Labels = None
player: "QtVideoPlayer" = None
trail_length: int = 10
show: bool = False
trail_length: int = 0
show: bool = True

def get_track_trails(self, frame_selection: Iterable["LabeledFrame"]):
"""Get data needed to draw track trail.
Expand Down
2 changes: 1 addition & 1 deletion sleap/gui/slider.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def visual_width(self):

def get_height(self, container_height):
if self.type == "track":
return 1.5
return 2
height = container_height
# if self.padded:
height -= self.top_pad + self.bottom_pad
Expand Down
37 changes: 30 additions & 7 deletions sleap/gui/video.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,17 @@
>>> vp.addInstance(instance=my_instance, color=(r, g, b))

"""
from collections import deque

FORCE_REQUEST_AFTER_TIME_IN_SECONDS = 1

# FORCE_REQUESTS controls whether we emit a signal to process frame requests
# if we haven't processed any for a certain amount of time.
# Usually the processing gets triggered by a timer but if the user is (e.g.)
# dragging the mouse, the timer doesn't trigger.
# FORCE_REQUESTS lets us update the frames in real time, assuming the load time
# is short enough to do that.

FORCE_REQUESTS = True


from PySide2 import QtWidgets, QtCore
Expand Down Expand Up @@ -65,10 +74,14 @@ class LoadImageWorker(QtCore.QObject):
load_queue = []
video = None
_last_process_time = 0
_force_request_wait_time = 1
_recent_load_times = None

def __init__(self, *args, **kwargs):
super(LoadImageWorker, self).__init__(*args, **kwargs)

self._recent_load_times = deque(maxlen=5)

# Connect signal to processing function so that we can add processing
# event to event queue from the request handler.
self.process.connect(self.doProcessing)
Expand All @@ -87,12 +100,21 @@ def doProcessing(self):
frame_idx = self.load_queue[-1]
self.load_queue = []

# print(f"\t{frame_idx} starting to load") # DEBUG

try:

t0 = time.time()

# Get image data
frame = self.video.get_frame(frame_idx)
except:

self._recent_load_times.append(time.time() - t0)

# Set the time to wait before forcing a load request to a little
# longer than the average time it recently took to load a frame
avg_load_time = sum(self._recent_load_times) / len(self._recent_load_times)
self._force_request_wait_time = avg_load_time * 1.2

except Exception as e:
frame = None

if frame is not None:
Expand All @@ -115,9 +137,10 @@ def request(self, frame_idx):

since_last = time.time() - self._last_process_time

if since_last > FORCE_REQUEST_AFTER_TIME_IN_SECONDS:
self._last_process_time = time.time()
self.process.emit()
if FORCE_REQUESTS:
if since_last > self._force_request_wait_time:
self._last_process_time = time.time()
self.process.emit()


class QtVideoPlayer(QWidget):
Expand Down