exceptions: Moved callbacks to its own location. Added VideoHandlerThread callback exception handling. Added exception tests.
This commit is contained in:
67
cvpubsubs/callbacks.py
Normal file
67
cvpubsubs/callbacks.py
Normal file
@ -0,0 +1,67 @@
|
||||
from cvpubsubs.window_sub.winctrl import WinCtrl
|
||||
import numpy as np
|
||||
|
||||
if False:
|
||||
from typing import Union
|
||||
|
||||
|
||||
def global_cv_display_callback(frame, # type: np.ndarray
|
||||
cam_id # type: Union[int, str]
|
||||
):
|
||||
from cvpubsubs.window_sub import SubscriberWindows
|
||||
"""Default callback for sending frames to the global frame dictionary.
|
||||
|
||||
:param frame: The video or image frame
|
||||
:type frame: np.ndarray
|
||||
:param cam_id: The video or image source
|
||||
:type cam_id: Union[int, str]
|
||||
"""
|
||||
SubscriberWindows.frame_dict[str(cam_id) + "frame"] = frame
|
||||
|
||||
|
||||
class function_display_callback(object): # NOSONAR
|
||||
def __init__(self, display_function, finish_function=None):
|
||||
"""Used for running arbitrary functions on pixels.
|
||||
|
||||
>>> import random
|
||||
>>> from cvpubsubs.webcam_pub import VideoHandlerThread
|
||||
>>> img = np.zeros((300, 300, 3))
|
||||
>>> def fun(array, coords, finished):
|
||||
... r,g,b = random.random()/20.0, random.random()/20.0, random.random()/20.0
|
||||
... 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: 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
|
||||
|
||||
def _run_finisher(self, frame, finished, *args, **kwargs):
|
||||
if not callable(finish_function):
|
||||
WinCtrl.quit()
|
||||
else:
|
||||
finished = finish_function(frame, Ellipsis, finished, *args, **kwargs)
|
||||
if finished:
|
||||
WinCtrl.quit()
|
||||
|
||||
def _display_internal(self, frame, cam_id, *args, **kwargs):
|
||||
finished = True
|
||||
if self.first_call:
|
||||
# return to display initial frame
|
||||
self.first_call = False
|
||||
return
|
||||
if self.looping:
|
||||
it = np.nditer(frame, flags=['multi_index'])
|
||||
while not it.finished:
|
||||
x, y, c = it.multi_index
|
||||
finished = display_function(frame, (x, y, c), finished, *args, **kwargs)
|
||||
it.iternext()
|
||||
if finished:
|
||||
self.looping = False
|
||||
_run_finisher(self, frame, finished, *args, **kwargs)
|
||||
|
||||
self.inner_function = _display_internal
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
return self.inner_function(self, *args, **kwargs)
|
Reference in New Issue
Block a user