feat: show bitrate, fps, latency in tracking mode

This commit is contained in:
Sebastian Fitt 2023-04-29 15:48:29 +02:00
parent 2efa3c3589
commit 61637442c6
2 changed files with 63 additions and 37 deletions

View File

@ -53,6 +53,7 @@ class Camera:
self.last_frame_time = time.time()
self.frame_number = 0
self.fps = 0
self.bps = 0
self.start = True
self.buffer = b''
@ -128,6 +129,7 @@ class Camera:
raise RuntimeError("Problem while getting frame")
frame_number = self.wired_camera.get(cv2.CAP_PROP_POS_FRAMES)
self.fps = self.wired_camera.get(cv2.CAP_PROP_FPS)
self.bps = image.nbytes
if should_push:
self.push_image_to_queue(image, frame_number, self.fps)
except:
@ -156,10 +158,11 @@ class Camera:
return jpeg
def get_serial_camera_picture(self, should_push):
if self.serial_connection is None:
conn = self.serial_connection
if conn is None:
return
try:
if self.serial_connection.in_waiting:
if conn.in_waiting:
jpeg = self.get_next_jpeg_frame()
if jpeg:
# Create jpeg frame from byte string
@ -169,9 +172,9 @@ class Camera:
return
# Discard the serial buffer. This is due to the fact that it
# may build up some outdated frames. A bit of a workaround here tbh.
if self.serial_connection.in_waiting > 32768:
print(f"{Fore.CYAN}[INFO] Discarding the serial buffer ({self.serial_connection.in_waiting} bytes{Fore.RESET}")
self.serial_connection.reset_input_buffer()
if conn.in_waiting >= 32768:
print(f"{Fore.CYAN}[INFO] Discarding the serial buffer ({conn.in_waiting} bytes){Fore.RESET}")
conn.reset_input_buffer()
self.buffer = b''
# Calculate the fps.
current_frame_time = time.time()
@ -179,13 +182,13 @@ class Camera:
self.last_frame_time = current_frame_time
if delta_time > 0:
self.fps = 1 / delta_time
# print(f'FPS: {int(self.fps)}')
self.bps = len(jpeg) / delta_time
self.frame_number = self.frame_number + 1
if should_push:
self.push_image_to_queue(image, self.frame_number, self.fps)
except Exception:
print(f"{Fore.YELLOW}[WARN] Serial capture source problem, assuming camera disconnected, waiting for reconnect.{Fore.RESET}")
self.serial_connection.close()
conn.close()
self.camera_status = CameraState.DISCONNECTED
pass
@ -208,7 +211,7 @@ class Camera:
dsrdtr=False,
rtscts=False)
# Set explicit buffer size for serial.
conn.set_buffer_size(rx_size = 65536, tx_size = 65536)
conn.set_buffer_size(rx_size = 32768, tx_size = 32768)
print(f"{Fore.CYAN}[INFO] ETVR Serial Tracker device connected on {port}{Fore.RESET}")
self.serial_connection = conn

View File

@ -1,6 +1,7 @@
import PySimpleGUI as sg
from config import EyeTrackConfig
from config import EyeTrackSettingsConfig
from collections import deque
from threading import Event, Thread
from eye_processor import EyeProcessor, EyeInfoOrigin
from enum import Enum
@ -24,6 +25,8 @@ class CameraWidget:
self.gui_save_tracking_button = f"-SAVETRACKINGBUTTON{widget_id}-"
self.gui_tracking_layout = f"-TRACKINGLAYOUT{widget_id}-"
self.gui_tracking_image = f"-IMAGE{widget_id}-"
self.gui_tracking_fps = f"-TRACKINGFPS{widget_id}-"
self.gui_tracking_bps = f"-TRACKINGBPS{widget_id}-"
self.gui_output_graph = f"-OUTPUTGRAPH{widget_id}-"
self.gui_restart_calibration = f"-RESTARTCALIBRATION{widget_id}-"
self.gui_stop_calibration = f"-STOPCALIBRATION{widget_id}-"
@ -46,6 +49,35 @@ class CameraWidget:
else:
raise RuntimeError("\033[91m[WARN] Cannot have a camera widget represent both eyes!\033[0m")
self.cancellation_event = Event()
# Set the event until start is called, otherwise we can block if shutdown is called.
self.cancellation_event.set()
self.capture_event = Event()
self.capture_queue = Queue()
self.roi_queue = Queue()
self.image_queue = Queue()
self.ransac = EyeProcessor(
self.config,
self.settings_config,
self.cancellation_event,
self.capture_event,
self.capture_queue,
self.image_queue,
self.eye_id,
)
self.camera_status_queue = Queue()
self.camera = Camera(
self.config,
0,
self.cancellation_event,
self.capture_event,
self.camera_status_queue,
self.capture_queue,
)
self.roi_layout = [
[
sg.Graph(
@ -82,6 +114,8 @@ class CameraWidget:
[
sg.Text("Mode:", background_color='#424042'),
sg.Text("Calibrating", key=self.gui_mode_readout, background_color='#424042'),
sg.Text("", key=self.gui_tracking_fps, background_color='#424042'),
sg.Text("", key=self.gui_tracking_bps, background_color='#424042'),
# sg.Checkbox(
# "Circle crop:",
# default=self.config.gui_circular_crop,
@ -123,40 +157,23 @@ class CameraWidget:
],
]
self.cancellation_event = Event()
# Set the event until start is called, otherwise we can block if shutdown is called.
self.cancellation_event.set()
self.capture_event = Event()
self.capture_queue = Queue()
self.roi_queue = Queue()
self.image_queue = Queue()
self.ransac = EyeProcessor(
self.config,
self.settings_config,
self.cancellation_event,
self.capture_event,
self.capture_queue,
self.image_queue,
self.eye_id,
)
self.camera_status_queue = Queue()
self.camera = Camera(
self.config,
0,
self.cancellation_event,
self.capture_event,
self.camera_status_queue,
self.capture_queue,
)
self.x0, self.y0 = None, None
self.x1, self.y1 = None, None
self.figure = None
self.is_mouse_up = True
self.in_roi_mode = False
self.movavg_fps_queue = deque(maxlen=120)
self.movavg_bps_queue = deque(maxlen=120)
def _movavg_fps(self, next_fps):
self.movavg_fps_queue.append(next_fps)
fps = round(sum(self.movavg_fps_queue) / len(self.movavg_fps_queue))
millisec = round((1 / fps if fps else 0) * 1000)
return f"{fps} Fps {millisec} ms"
def _movavg_bps(self, next_bps):
self.movavg_bps_queue.append(next_bps)
return f"{sum(self.movavg_bps_queue) / len(self.movavg_bps_queue) * 0.001 * 0.001 * 8:.3f} Mbps"
def started(self):
return not self.cancellation_event.is_set()
@ -261,6 +278,10 @@ class CameraWidget:
needs_roi_set = self.config.roi_window_h <= 0 or self.config.roi_window_w <= 0
# TODO: Refactor if statements below...
window[self.gui_tracking_fps].update('')
window[self.gui_tracking_bps].update('')
if self.config.capture_source is None or self.config.capture_source == "":
window[self.gui_mode_readout].update("Waiting for camera address")
window[self.gui_roi_message].update(visible=False)
@ -275,6 +296,8 @@ class CameraWidget:
window[self.gui_mode_readout].update("Calibration")
else:
window[self.gui_mode_readout].update("Tracking")
window[self.gui_tracking_fps].update(self._movavg_fps(self.camera.fps))
window[self.gui_tracking_bps].update(self._movavg_bps(self.camera.bps))
if self.in_roi_mode:
try: