Skip to content

Commit

Permalink
Merge remote-tracking branch 'official/main' into focus-branch
Browse files Browse the repository at this point in the history
  • Loading branch information
SnuffSocket committed Oct 25, 2024
2 parents e6a27a1 + 1cba6d3 commit d956170
Show file tree
Hide file tree
Showing 16 changed files with 92 additions and 59 deletions.
3 changes: 3 additions & 0 deletions BabbleApp/Locale/English/locale.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@
"error.frame": "Problem while getting frame",
"error.size": "Size of frames to display are of unequal sizes",
"error.capture": "Frame capture issue detected",
"error.winmm": "Failed to load winmm",
"warn.frameDrop": "Frame drop. Corrupted JPEG",
"warn.captureProblem": "Capture source problem, assuming camera disconnected, waiting for reconnect",
"warn.serialCapture": "Serial capture source problem, assuming camera disconnected, waiting for reconnect",
"warn.backpressure1": "CAPTURE QUEUE BACKPRESSURE OF",
"warn.backpressure2": "CHECK FOR CRASH OR TIMING ISSUES IN ALGORITHM",
"warn.oneEuroValues": "OneEuroFilter values must be a legal number",
"warn.timerRes": "Failed to set timer resolution:",
"info.moveToTrackingMode": "Moving to tracking mode",
"info.moveToROIMode": "Moving to ROI mode",
"info.setROI": "Set ROI",
Expand All @@ -55,6 +57,7 @@
"info.enterCaptureTwo": "not found, retrying...",
"info.exitCaptureThread": "Exiting capture thread",
"info.exitTrackingThread": "Exiting tracking thread",
"info.serialCapture": "Failed to get serial picture",
"log.info": "INFO",
"log.warn": "WARN",
"log.error": "ERROR",
Expand Down
3 changes: 3 additions & 0 deletions BabbleApp/Locale/OwO/locale.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@
"error.frame": "Problem while getting frame",
"error.size": "Size of frames to display are of unequal sizes",
"error.capture": "Frame capture issue detected",
"error.winmmDll": "Failed to load winmm",
"warn.frameDrop": "Frame drop. Corrupted JPEG",
"warn.captureProblem": "Capture source problem, assuming camera disconnected, waiting for reconnect",
"warn.serialCapture": "Serial capture source problem, assuming camera disconnected, waiting for reconnect",
"warn.backpressure1": "CAPTURE QUEUE BACKPRESSURE OF",
"warn.backpressure2": "CHECK FOR CRASH OR TIMING ISSUES IN ALGORITHM",
"warn.oneEuroValues": "OneEuroFilter values must be a legal number",
"warn.timerRes": "Faiwed to set timew wesowution:",
"info.moveToTrackingMode": "Moving to tracking mode",
"info.moveToROIMode": "Moving to ROI mode",
"info.setROI": "Set ROI",
Expand All @@ -55,6 +57,7 @@
"info.enterCaptureTwo": "not found, retrying...",
"info.exitCaptureThread": "Exiting capture thread",
"info.exitTrackingThread": "Exiting tracking thread",
"info.serialCapture": "Fawled to gwet seiewal pictower 3:",
"log.info": "INFO",
"log.warn": "WARN",
"log.error": "ERROR",
Expand Down
3 changes: 3 additions & 0 deletions BabbleApp/Locale/Pirate Speak/locale.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@
"error.frame": "Problem while getting frame",
"error.size": "Size of frames to display are of unequal sizes",
"error.capture": "Frame capture issue detected",
"error.winmmDll": "Failed to load winmm",
"warn.frameDrop": "Frame drop. Corrupted JPEG",
"warn.captureProblem": "Capture source problem, assuming camera disconnected, waiting for reconnect",
"warn.serialCapture": "Serial capture source problem, assuming camera disconnected, waiting for reconnect",
"warn.backpressure1": "CAPTURE QUEUE BACKPRESSURE OF",
"warn.backpressure2": "CHECK FOR CRASH OR TIMING ISSUES IN ALGORITHM",
"warn.oneEuroValues": "OneEuroFilter values must be a legal number",
"warn.timerRes": "We be failin' to set th' timer resolution:",
"info.moveToTrackingMode": "Moving to tracking mode",
"info.moveToROIMode": "Moving to ROI mode",
"info.setROI": "Set ROI",
Expand All @@ -55,6 +57,7 @@
"info.enterCaptureTwo": "not found, retrying...",
"info.exitCaptureThread": "Exiting capture thread",
"info.exitTrackingThread": "Exiting tracking thread",
"info.serialCapture": "Failed to get serial piccure, matey!",
"log.info": "INFO",
"log.warn": "WARN",
"log.error": "ERROR",
Expand Down
2 changes: 1 addition & 1 deletion BabbleApp/babble_model_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@


def run_model(self):
if self.runtime == "ONNX" or self.runtime == "Default (ONNX)":
if self.runtime in ("ONNX", "Default (ONNX)"):
frame = cv2.resize(self.current_image_gray, (256, 256))
frame = transforms.to_tensor(frame)
frame = transforms.unsqueeze(frame, 0)
Expand Down
6 changes: 5 additions & 1 deletion BabbleApp/babble_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,14 @@ def __init__(
self.calibrate_config = np.empty((1, 45))
self.min_max_array = np.empty((2, 45))

ort.disable_telemetry_events()
self.opts = ort.SessionOptions()
self.opts.inter_op_num_threads = 1
self.opts.intra_op_num_threads = settings.gui_inference_threads
self.opts.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
if self.runtime == "ONNX" or self.runtime == "Default (ONNX)": # ONNX
self.opts.add_session_config_entry("session.intra_op.allow_spinning", "0") # ~3% savings worth ~6ms avg latency. Not noticeable at 60fps?
self.opts.enable_mem_pattern = False
if self.runtime in ("ONNX", "Default (ONNX)"): # ONNX
if self.use_gpu:
provider = "DmlExecutionProvider"
else:
Expand Down
22 changes: 20 additions & 2 deletions BabbleApp/babbleapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import queue
import requests
import threading
from ctypes import windll, c_int
from babble_model_loader import *
from camera_widget import CameraWidget
from config import BabbleConfig
Expand All @@ -33,8 +34,14 @@
from utils.misc_utils import EnsurePath, is_nt, bg_color_highlight, bg_color_clear
from lang_manager import LocaleStringManager as lang

winmm = None

if is_nt:
from winotify import Notification
try:
winmm = windll.winmm
except OSError:
print(f'\033[91m[{lang._instance.get_string("log.error")}] {lang._instance.get_string("error.winmm")}.\033[0m')
os.system("color") # init ANSI color

# Random environment variable to speed up webcam opening on the MSMF backend.
Expand All @@ -54,6 +61,15 @@
page_url = "https://github.com/SummerSigh/ProjectBabble/releases/latest"
appversion = "Babble v2.0.6 Alpha"

def timerResolution(toggle):
if winmm != None:
if toggle:
rc = c_int(winmm.timeBeginPeriod(1))
if rc.value != 0:
# TIMEERR_NOCANDO = 97
print(f'\033[93m[{lang._instance.get_string("log.warn")}] {lang._instance.get_string("warn.timerRes")} {rc.value}\033[0m')
else:
winmm.timeEndPeriod(1)

def main():
EnsurePath()
Expand Down Expand Up @@ -110,6 +126,7 @@ def main():
print(
f'[{lang._instance.get_string("log.info")}] {lang._instance.get_string("babble.noInternet")}.'
)
timerResolution(True)
# Check to see if we have an ROI. If not, bring up ROI finder GUI.

# Spawn worker threads
Expand Down Expand Up @@ -216,10 +233,10 @@ def main():
# GUI Render loop
while True:
# First off, check for any events from the GUI
event, values = window.read(timeout=2)
event, values = window.read(timeout=30)

# If we're in either mode and someone hits q, quit immediately
if event == "Exit" or event == sg.WIN_CLOSED:
if event in ("Exit", sg.WIN_CLOSED):
for (
cam
) in (
Expand All @@ -236,6 +253,7 @@ def main():
if ROSC:
osc_receiver.shutdown()
osc_receiver_thread.join()
timerResolution(False)
print(
f'\033[94m[{lang._instance.get_string("log.info")}] {lang._instance.get_string("babble.exit")}\033[0m'
)
Expand Down
24 changes: 19 additions & 5 deletions BabbleApp/camera.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import cv2
from cv2.typing import *
import numpy as np
import queue
import serial
Expand All @@ -13,6 +14,7 @@
from enum import Enum

WAIT_TIME = 0.1
MAX_RESOLUTION: int = 600

# Serial communication protocol:
# header-begin (2 bytes)
Expand All @@ -25,9 +27,9 @@


class CameraState(Enum):
CONNECTING = 0
CONNECTED = 1
DISCONNECTED = 2
CONNECTING: int = 0
CONNECTED: int = 1
DISCONNECTED: int = 2


class Camera:
Expand All @@ -41,7 +43,6 @@ def __init__(
camera_output_outgoing: "queue.Queue(maxsize=2)",
settings: BabbleSettingsConfig,
):
self.current_capture_sourc = None
self.camera_status = CameraState.CONNECTING
self.config = config
self.settings = settings
Expand Down Expand Up @@ -304,6 +305,19 @@ def start_serial_connection(self, port):
)
self.camera_status = CameraState.DISCONNECTED

def clamp_max_res(self, image: MatLike) -> MatLike:
shape = image.shape
max_value = np.max(shape)
if max_value > MAX_RESOLUTION:
scale: float = MAX_RESOLUTION/max_value
width: int = int(shape[1] * scale)
height: int = int(shape[0] * scale)
image = cv2.resize(image, (width, height))

return image
else: return image


def push_image_to_queue(self, image, frame_number, fps):
# If there's backpressure, just yell. We really shouldn't have this unless we start getting
# some sort of capture event conflict though.
Expand All @@ -312,5 +326,5 @@ def push_image_to_queue(self, image, frame_number, fps):
print(
f'{Fore.YELLOW}[{lang._instance.get_string("log.warn")}] {lang._instance.get_string("warn.backpressure1")} {qsize}. {lang._instance.get_string("warn.backpressure2")}{Fore.RESET}'
)
self.camera_output_outgoing.put((image, frame_number, fps))
self.camera_output_outgoing.put((self.clamp_max_res(image), frame_number, fps))
self.capture_event.clear()
38 changes: 20 additions & 18 deletions BabbleApp/camera_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import PySimpleGUI as sg
import cv2
from babble_processor import BabbleProcessor, CamInfoOrigin
from camera import Camera, CameraState
from camera import Camera, CameraState, MAX_RESOLUTION
from config import BabbleConfig
from osc import Tab
from utils.misc_utils import (
Expand All @@ -15,6 +15,7 @@
get_camera_index_by_name,
bg_color_highlight,
bg_color_clear,
is_valid_int_input
)
from lang_manager import LocaleStringManager as lang

Expand Down Expand Up @@ -63,7 +64,7 @@ def __init__(self, widget_id: Tab, main_config: BabbleConfig, osc_queue: Queue):
self.capture_event = Event()
self.capture_queue = Queue(maxsize=2)
self.roi_queue = Queue(maxsize=2)
self.image_queue = Queue(maxsize=500)
self.image_queue = Queue(maxsize=500) # This is needed to prevent the UI from freezing during widget changes.

self.babble_cnn = BabbleProcessor(
self.config,
Expand Down Expand Up @@ -101,9 +102,9 @@ def __init__(self, widget_id: Tab, main_config: BabbleConfig, osc_queue: Queue):
],
[
sg.Graph(
(640, 480),
(0, 480),
(640, 0),
(MAX_RESOLUTION, MAX_RESOLUTION),
(0, MAX_RESOLUTION),
(MAX_RESOLUTION, 0),
key=self.gui_roi_selection,
drag_submits=True,
enable_events=True,
Expand Down Expand Up @@ -134,14 +135,14 @@ def __init__(self, widget_id: Tab, main_config: BabbleConfig, osc_queue: Queue):
key=self.gui_restart_calibration,
button_color=button_color,
tooltip=lang._instance.get_string("camera.startCalibrationTooltip"),
disabled=True,
disabled=not self.settings_config.use_calibration,
),
sg.Button(
lang._instance.get_string("camera.stopCalibration"),
key=self.gui_stop_calibration,
button_color=button_color,
tooltip=lang._instance.get_string("camera.startCalibrationTooltip"),
disabled=True,
disabled=not self.settings_config.use_calibration,
),
],
[
Expand Down Expand Up @@ -212,6 +213,7 @@ def __init__(self, widget_id: Tab, main_config: BabbleConfig, osc_queue: Queue):
key=self.gui_camera_addr,
tooltip=lang._instance.get_string("camera.cameraAddressTooltip"),
enable_events=True,
size=(20,0),
),
sg.Button(
lang._instance.get_string("camera.refreshCameraList"),
Expand Down Expand Up @@ -323,11 +325,11 @@ def render(self, window, event, values):
if any(x in str(value) for x in ports):
self.config.capture_source = value
else:
cam = get_camera_index_by_name(
value
) # Set capture_source to the UVC index. Otherwise treat value like an ipcam if we return none
cam = get_camera_index_by_name(value) # Set capture_source to the UVC index. Otherwise treat value like an ipcam if we return none
if cam != None:
self.config.capture_source = get_camera_index_by_name(value)
self.config.capture_source = cam
elif is_valid_int_input(value):
self.config.capture_source = int(value)
else:
self.config.capture_source = value
except ValueError:
Expand Down Expand Up @@ -394,11 +396,11 @@ def render(self, window, event, values):
if self.settings_config.use_calibration == True:
window[self.gui_restart_calibration].update(disabled=False)
window[self.gui_stop_calibration].update(disabled=False)
print({lang._instance.get_string("info.enabled")})
print(f'[{lang._instance.get_string("log.info")}] {lang._instance.get_string("info.enabled")}')
else:
window[self.gui_restart_calibration].update(disabled=True)
window[self.gui_stop_calibration].update(disabled=True)
print(lang._instance.get_string("algoritm.disabled"))
print(f'[{lang._instance.get_string("log.info")}] {lang._instance.get_string("info.disabled")}')

if event == "{}+UP".format(self.gui_roi_selection):
# Event for mouse button up in ROI mode
Expand All @@ -423,20 +425,20 @@ def render(self, window, event, values):

if event == self.gui_autoroi:
print(lang._instance.get_string("info.setROI"))
output = self.babble_cnn.get_framesize()
output = self.maybe_image[0].shape
self.config.roi_window_x = 0
self.config.roi_window_y = 0
self.config.roi_window_w = output[0]
self.config.roi_window_h = output[1]
self.config.roi_window_w = output[1]
self.config.roi_window_h = output[0]
self.main_config.save()

if event == self.gui_refresh_button:
print(
f'\033[94m[{lang._instance.get_string("log.info")}] {lang._instance.get_string("info.refreshedCameraList")}\033[0m'
)
self.camera_list = list_camera_names()
print(self.camera_list)
window[self.gui_camera_addr].update(values=self.camera_list)
#print(self.camera_list)
window[self.gui_camera_addr].update(values=self.camera_list,size=(20,0))

if event == self.gui_restart_calibration:
if (
Expand Down
17 changes: 2 additions & 15 deletions BabbleApp/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,31 +64,19 @@ def load():
EnsurePath()

if not os.path.exists(CONFIG_FILE_NAME):
print(
f'[{lang._instance.get_string("log.info")}] {lang._instance.get_string("config.noSettingsFile")}'
)
return BabbleConfig()
try:
with open(CONFIG_FILE_NAME, "r") as settings_file:
return BabbleConfig(**json.load(settings_file))
except json.JSONDecodeError:
print(
f'[{lang._instance.get_string("log.info")}] {lang._instance.get_string("config.failedToLoadSettings")}'
)
load_config = None
if os.path.exists(BACKUP_CONFIG_FILE_NAME):
try:
with open(BACKUP_CONFIG_FILE_NAME, "r") as settings_file:
load_config = BabbleConfig(**json.load(settings_file))
print(
f'[{lang._instance.get_string("log.info")}] {lang._instance.get_string("config.usingBackupSettings")}'
)
except json.JSONDecodeError:
pass
if load_config is None:
print(
f'[{lang._instance.get_string("log.info")}] {lang._instance.get_string("config.usingBaseSettings")}'
)
load_config = BabbleConfig()
return load_config

Expand All @@ -103,11 +91,10 @@ def save(self):
BabbleConfig(**json.load(settings_file))
shutil.copy(CONFIG_FILE_NAME, BACKUP_CONFIG_FILE_NAME)
# print("Backed up settings files.") # Comment out because it's too loud.
except shutil.SameFileError:
pass
except json.JSONDecodeError:
# No backup because the saved settings file is broken.
pass
with open(CONFIG_FILE_NAME, "w") as settings_file:
json.dump(obj=self.dict(), fp=settings_file, indent=2)
print(
f'[{lang._instance.get_string("log.info")}] {lang._instance.get_string("config.saved")}.'
)
2 changes: 1 addition & 1 deletion BabbleApp/general_settings_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,4 +336,4 @@ def render(self, window, event, values):
if changed:
self.main_config.save()

self.osc_queue.put((Tab.SETTINGS))
self.osc_queue.put(Tab.SETTINGS)
Loading

0 comments on commit d956170

Please sign in to comment.