Merge pull request #16 from SimLeek/exceptions

Exceptions
This commit is contained in:
Josh Miklos
2019-02-25 20:21:24 -07:00
committed by GitHub
5 changed files with 49 additions and 10 deletions
+1 -1
View File
@@ -1 +1 @@
__version__ = '0.5.0'
__version__ = '0.6.0'
@@ -31,8 +31,8 @@ class function_display_callback(object): # NOSONAR
... array[coords[0:2]] = (array[coords[0:2]] + [r,g,b])%1.0
>>> VideoHandlerThread(video_source=img, callbacks=function_display_callback(fun)).display()
:param display_function:
:param finish_function:
:param display_function: a function to run on the input image.
:param finish_function: a function to run on the input image when the other function finishes.
"""
self.looping = True
self.first_call = True
+14 -2
View File
@@ -4,13 +4,15 @@ import numpy as np
from cvpubsubs.webcam_pub.pub_cam import pub_cam_thread
from cvpubsubs.webcam_pub.camctrl import CamCtrl
from cvpubsubs.window_sub.winctrl import WinCtrl
if False:
from typing import Union, Tuple, Any, Callable, List, Optional
FrameCallable = Callable[[np.ndarray, int], Optional[np.ndarray]]
from cvpubsubs.webcam_pub.callbacks import global_cv_display_callback
from cvpubsubs.callbacks import global_cv_display_callback
display_callbacks = [global_cv_display_callback]
@@ -53,6 +55,7 @@ class VideoHandlerThread(threading.Thread):
self.request_size = request_size
self.high_speed = high_speed
self.fps_limit = fps_limit
self.exception_raised = None
def loop(self):
"""Continually gets frames from the video publisher, runs callbacks on them, and listens to commands."""
@@ -66,7 +69,14 @@ class VideoHandlerThread(threading.Thread):
frame = sub_cam.get(blocking=True, timeout=1.0) # type: np.ndarray
if frame is not None:
for c in self.callbacks:
frame_c = c(frame, self.cam_id)
try:
frame_c = c(frame, self.cam_id)
except Exception as e:
import traceback
CamCtrl.stop_cam(self.cam_id)
WinCtrl.quit()
self.exception_raised = e
frame_c = self.exception_raised
if frame_c is not None:
frame = frame_c
msg_owner = sub_owner.get()
@@ -93,3 +103,5 @@ class VideoHandlerThread(threading.Thread):
self.start()
SubscriberWindows(video_sources=[self.cam_id], callbacks=callbacks).loop()
self.join()
if self.exception_raised is not None:
raise self.exception_raised
+4 -2
View File
@@ -40,9 +40,9 @@ class SubscriberWindows(object):
@staticmethod
def set_global_frame_dict(name, *args):
if len(str(name)) <= 1000:
SubscriberWindows.frame_dict[str(name) + "frame"] = [*args]
SubscriberWindows.frame_dict[str(name) + "frame"] = list(args)
elif isinstance(name, np.ndarray):
SubscriberWindows.frame_dict[str(hash(str(name))) + "frame"] = [*args]
SubscriberWindows.frame_dict[str(hash(str(name))) + "frame"] = list(args)
else:
raise ValueError("Input window name too long.")
@@ -68,6 +68,8 @@ class SubscriberWindows(object):
)
def _display_frames(self, frames, win_num):
if isinstance(frames, Exception):
raise frames
for f in range(len(frames)):
# detect nested:
if isinstance(frames[f], (list, tuple)) or frames[f].dtype.num == 17 or len(frames[f].shape) > 3:
+28 -3
View File
@@ -1,8 +1,6 @@
import threading
import unittest as ut
import numpy as np
import cvpubsubs.webcam_pub as w
from cvpubsubs.window_sub import SubscriberWindows
from cvpubsubs.window_sub.winctrl import WinCtrl
@@ -61,6 +59,16 @@ class TestSubWin(ut.TestCase):
w.VideoHandlerThread(callbacks=redden_frame_print_spam).display()
def test_sub_with_callback_exception(self):
def redden_frame_print_spam(frame, cam_id):
frame[:, :, 0] = 0
frame[:, :, 2] = 1 / 0
with self.assertRaises(ZeroDivisionError) as e:
v = w.VideoHandlerThread(callbacks=redden_frame_print_spam)
v.display()
self.assertEqual(v.exception_raised, e)
def test_multi_cams_one_source(self):
def cam_handler(frame, cam_id):
SubscriberWindows.set_global_frame_dict(cam_id, frame, frame)
@@ -108,9 +116,26 @@ class TestSubWin(ut.TestCase):
v.join()
def test_nested_frames_exception(self):
def nest_frame(frame, cam_id):
frame = np.asarray([[[[[[frame + 1 / 0]]]]], [[[[[frame]]], [[[frame]]]]]])
return frame
v = w.VideoHandlerThread(callbacks=[nest_frame] + w.display_callbacks)
v.start()
with self.assertRaises(ZeroDivisionError) as e:
SubscriberWindows(window_names=[str(i) for i in range(3)],
video_sources=[str(0)]
).loop()
self.assertEqual(v.exception_raised, e)
v.join()
def test_conway_life(self):
from cvpubsubs.webcam_pub import VideoHandlerThread
from cvpubsubs.webcam_pub.callbacks import function_display_callback
from cvpubsubs.callbacks import function_display_callback
import numpy as np
img = np.zeros((50, 50, 1))
img[0:5, 0:5, :] = 1