Skip to content

Commit fe793f2

Browse files
authored
Merge pull request #120 from dfgHiatus/feat/post-pr-cleanup
feat(PR) Cleanup files for Post-PR mergers
2 parents bb011fd + f7391dc commit fe793f2

File tree

3 files changed

+33
-21
lines changed

3 files changed

+33
-21
lines changed

BabbleApp/camera.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,12 @@ def run(self):
143143
self.cv2_camera is None
144144
or not self.cv2_camera.isOpened()
145145
or self.camera_status == CameraState.DISCONNECTED
146-
#or get_camera_index_by_name(self.config.capture_source) != self.current_capture_source
147-
or self.config.capture_source != self.current_capture_source
146+
or get_camera_index_by_name(self.config.capture_source) != self.current_capture_source
148147
):
149148
if self.vft_camera is not None:
150149
self.vft_camera.close()
151150
self.device_is_vft = False
152-
151+
153152
print(self.error_message.format(self.config.capture_source))
154153
# This requires a wait, otherwise we can error and possible screw up the camera
155154
# firmware. Fickle things.
@@ -221,7 +220,7 @@ def get_camera_picture(self, should_push):
221220
return
222221
self.frame_number = self.frame_number + 1
223222
elif self.cv2_camera is not None and self.cv2_camera.isOpened():
224-
ret, image = self.cv2_camera.read() # MJPEG Stream reconnects are currently limited by the hard coded 30 second timeout time on VideoCapture.read(). We can get around this by recompiling OpenCV or using a custom MJPEG stream imp.
223+
ret, image = self.cv2_camera.read() # MJPEG Stream reconnects are currently limited by the hard coded 30 second timeout time on VideoCapture.read(). We can get around this by recompiling OpenCV or using a custom MJPEG stream imp.
225224
if ret and image is not None:
226225
if not ret:
227226
if not self.http:
@@ -366,4 +365,4 @@ def push_image_to_queue(self, image, frame_number, fps):
366365
f'{Fore.YELLOW}[{lang._instance.get_string("log.warn")}] {lang._instance.get_string("warn.backpressure1")} {qsize}. {lang._instance.get_string("warn.backpressure2")}{Fore.RESET}'
367366
)
368367
self.camera_output_outgoing.put((self.clamp_max_res(image), frame_number, fps))
369-
self.capture_event.clear()
368+
self.capture_event.clear()

BabbleApp/camera_widget.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def __init__(self, widget_id: Tab, main_config: BabbleConfig, osc_queue: Queue):
6262
self.capture_event = Event()
6363
self.capture_queue = Queue(maxsize=2)
6464
self.roi_queue = Queue(maxsize=2)
65-
self.image_queue = Queue(maxsize=500) # This is needed to prevent the UI from freezing during widget changes.
65+
self.image_queue = Queue(maxsize=500) # This is needed to prevent the UI from freezing during widget changes.
6666

6767
self.babble_cnn = BabbleProcessor(
6868
self.config,
@@ -285,7 +285,7 @@ def start(self):
285285
# self.babble_landmark_thread.start()
286286
self.camera_thread = Thread(target=self.camera.run)
287287
self.camera_thread.start()
288-
288+
289289

290290
def stop(self):
291291
# If we're not running yet, bail
@@ -322,7 +322,7 @@ def render(self, window, event, values):
322322
if any(x in str(value) for x in ports):
323323
self.config.capture_source = value
324324
else:
325-
if is_valid_int_input(value):
325+
if is_valid_int_input(value):
326326
self.config.capture_source = int(value)
327327
else:
328328
self.config.capture_source = value
@@ -422,7 +422,7 @@ def render(self, window, event, values):
422422
if self.maybe_image is None:
423423
# Skip rendering or use a default/placeholder image
424424
return # Or handle appropriately
425-
425+
426426
output = self.maybe_image[0].shape
427427
self.config.roi_window_x = 0
428428
self.config.roi_window_y = 0

BabbleApp/utils/misc_utils.py

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import typing
21
import serial
32
import serial.tools.list_ports
43
import sys
@@ -10,13 +9,15 @@
109
import subprocess
1110
import sounddevice as sd
1211
import soundfile as sf
12+
import contextlib
1313

1414
bg_color_highlight = "#424042"
1515
bg_color_clear = "#242224"
1616

1717
onnx_providers = [
1818
"DmlExecutionProvider",
1919
"CUDAExecutionProvider",
20+
"CoreMLExecutionProvider",
2021
"CPUExecutionProvider",
2122
]
2223

@@ -34,7 +35,7 @@ def is_valid_float_input(value):
3435
def is_valid_int_input(value):
3536
# Allow empty string, negative sign, or an integer number
3637
return bool(re.match(r"^-?\d*$", value))
37-
38+
3839
def list_camera_names():
3940
cam_list = graph.get_input_devices()
4041
cam_names = []
@@ -43,21 +44,34 @@ def list_camera_names():
4344
cam_names = cam_names + list_serial_ports()
4445
return cam_names
4546

47+
@contextlib.contextmanager
48+
def suppress_stderr():
49+
"""Context manager to suppress stderr (used for OpenCV warnings)."""
50+
with open(os.devnull, 'w') as devnull:
51+
old_stderr_fd = os.dup(2)
52+
os.dup2(devnull.fileno(), 2)
53+
try:
54+
yield
55+
finally:
56+
os.dup2(old_stderr_fd, 2)
57+
os.close(old_stderr_fd)
58+
4659
def list_cameras_opencv():
4760
"""Use OpenCV to check available cameras by index (fallback for Linux/macOS)"""
4861
index = 0
4962
arr = []
50-
while True:
51-
cap = cv2.VideoCapture(index)
52-
if not cap.read()[0]:
53-
break
54-
else:
55-
arr.append(f"/dev/video{index}")
56-
cap.release()
57-
index += 1
63+
with suppress_stderr(): # tell OpenCV not to throw "cannot find camera" while we probe for cameras
64+
while True:
65+
cap = cv2.VideoCapture(index)
66+
if not cap.read()[0]:
67+
cap.release()
68+
break
69+
else:
70+
arr.append(f"/dev/video{index}")
71+
cap.release()
72+
index += 1
5873
return arr
5974

60-
6175
def is_uvc_device(device):
6276
"""Check if the device is a UVC video device (not metadata)"""
6377
try:
@@ -174,4 +188,3 @@ def playSound(file):
174188
def ensurePath():
175189
if os.path.exists(os.path.join(os.getcwd(), "BabbleApp")):
176190
os.chdir(os.path.join(os.getcwd(), "BabbleApp"))
177-

0 commit comments

Comments
 (0)