mirror of
https://github.com/EyeTrackVR/EyeTrackVR.git
synced 2025-11-04 14:39:42 +08:00
feat: show bitrate, fps, latency in tracking mode
This commit is contained in:
parent
2efa3c3589
commit
61637442c6
@ -53,6 +53,7 @@ class Camera:
|
|||||||
self.last_frame_time = time.time()
|
self.last_frame_time = time.time()
|
||||||
self.frame_number = 0
|
self.frame_number = 0
|
||||||
self.fps = 0
|
self.fps = 0
|
||||||
|
self.bps = 0
|
||||||
self.start = True
|
self.start = True
|
||||||
self.buffer = b''
|
self.buffer = b''
|
||||||
|
|
||||||
@ -128,6 +129,7 @@ class Camera:
|
|||||||
raise RuntimeError("Problem while getting frame")
|
raise RuntimeError("Problem while getting frame")
|
||||||
frame_number = self.wired_camera.get(cv2.CAP_PROP_POS_FRAMES)
|
frame_number = self.wired_camera.get(cv2.CAP_PROP_POS_FRAMES)
|
||||||
self.fps = self.wired_camera.get(cv2.CAP_PROP_FPS)
|
self.fps = self.wired_camera.get(cv2.CAP_PROP_FPS)
|
||||||
|
self.bps = image.nbytes
|
||||||
if should_push:
|
if should_push:
|
||||||
self.push_image_to_queue(image, frame_number, self.fps)
|
self.push_image_to_queue(image, frame_number, self.fps)
|
||||||
except:
|
except:
|
||||||
@ -156,10 +158,11 @@ class Camera:
|
|||||||
return jpeg
|
return jpeg
|
||||||
|
|
||||||
def get_serial_camera_picture(self, should_push):
|
def get_serial_camera_picture(self, should_push):
|
||||||
if self.serial_connection is None:
|
conn = self.serial_connection
|
||||||
|
if conn is None:
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
if self.serial_connection.in_waiting:
|
if conn.in_waiting:
|
||||||
jpeg = self.get_next_jpeg_frame()
|
jpeg = self.get_next_jpeg_frame()
|
||||||
if jpeg:
|
if jpeg:
|
||||||
# Create jpeg frame from byte string
|
# Create jpeg frame from byte string
|
||||||
@ -169,9 +172,9 @@ class Camera:
|
|||||||
return
|
return
|
||||||
# Discard the serial buffer. This is due to the fact that it
|
# 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.
|
# may build up some outdated frames. A bit of a workaround here tbh.
|
||||||
if self.serial_connection.in_waiting > 32768:
|
if conn.in_waiting >= 32768:
|
||||||
print(f"{Fore.CYAN}[INFO] Discarding the serial buffer ({self.serial_connection.in_waiting} bytes{Fore.RESET}")
|
print(f"{Fore.CYAN}[INFO] Discarding the serial buffer ({conn.in_waiting} bytes){Fore.RESET}")
|
||||||
self.serial_connection.reset_input_buffer()
|
conn.reset_input_buffer()
|
||||||
self.buffer = b''
|
self.buffer = b''
|
||||||
# Calculate the fps.
|
# Calculate the fps.
|
||||||
current_frame_time = time.time()
|
current_frame_time = time.time()
|
||||||
@ -179,13 +182,13 @@ class Camera:
|
|||||||
self.last_frame_time = current_frame_time
|
self.last_frame_time = current_frame_time
|
||||||
if delta_time > 0:
|
if delta_time > 0:
|
||||||
self.fps = 1 / delta_time
|
self.fps = 1 / delta_time
|
||||||
# print(f'FPS: {int(self.fps)}')
|
self.bps = len(jpeg) / delta_time
|
||||||
self.frame_number = self.frame_number + 1
|
self.frame_number = self.frame_number + 1
|
||||||
if should_push:
|
if should_push:
|
||||||
self.push_image_to_queue(image, self.frame_number, self.fps)
|
self.push_image_to_queue(image, self.frame_number, self.fps)
|
||||||
except Exception:
|
except Exception:
|
||||||
print(f"{Fore.YELLOW}[WARN] Serial capture source problem, assuming camera disconnected, waiting for reconnect.{Fore.RESET}")
|
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
|
self.camera_status = CameraState.DISCONNECTED
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -208,7 +211,7 @@ class Camera:
|
|||||||
dsrdtr=False,
|
dsrdtr=False,
|
||||||
rtscts=False)
|
rtscts=False)
|
||||||
# Set explicit buffer size for serial.
|
# 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}")
|
print(f"{Fore.CYAN}[INFO] ETVR Serial Tracker device connected on {port}{Fore.RESET}")
|
||||||
self.serial_connection = conn
|
self.serial_connection = conn
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import PySimpleGUI as sg
|
import PySimpleGUI as sg
|
||||||
from config import EyeTrackConfig
|
from config import EyeTrackConfig
|
||||||
from config import EyeTrackSettingsConfig
|
from config import EyeTrackSettingsConfig
|
||||||
|
from collections import deque
|
||||||
from threading import Event, Thread
|
from threading import Event, Thread
|
||||||
from eye_processor import EyeProcessor, EyeInfoOrigin
|
from eye_processor import EyeProcessor, EyeInfoOrigin
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
@ -24,6 +25,8 @@ class CameraWidget:
|
|||||||
self.gui_save_tracking_button = f"-SAVETRACKINGBUTTON{widget_id}-"
|
self.gui_save_tracking_button = f"-SAVETRACKINGBUTTON{widget_id}-"
|
||||||
self.gui_tracking_layout = f"-TRACKINGLAYOUT{widget_id}-"
|
self.gui_tracking_layout = f"-TRACKINGLAYOUT{widget_id}-"
|
||||||
self.gui_tracking_image = f"-IMAGE{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_output_graph = f"-OUTPUTGRAPH{widget_id}-"
|
||||||
self.gui_restart_calibration = f"-RESTARTCALIBRATION{widget_id}-"
|
self.gui_restart_calibration = f"-RESTARTCALIBRATION{widget_id}-"
|
||||||
self.gui_stop_calibration = f"-STOPCALIBRATION{widget_id}-"
|
self.gui_stop_calibration = f"-STOPCALIBRATION{widget_id}-"
|
||||||
@ -46,6 +49,35 @@ class CameraWidget:
|
|||||||
else:
|
else:
|
||||||
raise RuntimeError("\033[91m[WARN] Cannot have a camera widget represent both eyes!\033[0m")
|
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 = [
|
self.roi_layout = [
|
||||||
[
|
[
|
||||||
sg.Graph(
|
sg.Graph(
|
||||||
@ -82,6 +114,8 @@ class CameraWidget:
|
|||||||
[
|
[
|
||||||
sg.Text("Mode:", background_color='#424042'),
|
sg.Text("Mode:", background_color='#424042'),
|
||||||
sg.Text("Calibrating", key=self.gui_mode_readout, 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(
|
# sg.Checkbox(
|
||||||
# "Circle crop:",
|
# "Circle crop:",
|
||||||
# default=self.config.gui_circular_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.x0, self.y0 = None, None
|
||||||
self.x1, self.y1 = None, None
|
self.x1, self.y1 = None, None
|
||||||
self.figure = None
|
self.figure = None
|
||||||
self.is_mouse_up = True
|
self.is_mouse_up = True
|
||||||
self.in_roi_mode = False
|
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):
|
def started(self):
|
||||||
return not self.cancellation_event.is_set()
|
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
|
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 == "":
|
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_mode_readout].update("Waiting for camera address")
|
||||||
window[self.gui_roi_message].update(visible=False)
|
window[self.gui_roi_message].update(visible=False)
|
||||||
@ -275,6 +296,8 @@ class CameraWidget:
|
|||||||
window[self.gui_mode_readout].update("Calibration")
|
window[self.gui_mode_readout].update("Calibration")
|
||||||
else:
|
else:
|
||||||
window[self.gui_mode_readout].update("Tracking")
|
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:
|
if self.in_roi_mode:
|
||||||
try:
|
try:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user