class PaintDisplay(OpenCvDisplay): def __init__(self, source): super().__init__(source) self.mouse_event: Buffer[MouseEvent] = Buffer( EventBasedMouseHandler.MOUSE_EVENT) self.reset_calibration = Output( ProjectorDriver2d.RESET_CALIBRATION_TRIGGER) self.clear_canvas = Output('trigger.clear_canvas') self._menu = Menu([ Label('Menu'), Button('Calibrate', self.calibrate), Button('Clear Canvas', self.clear), ], position=(1, 0)) def calibrate(self): self.reset_calibration.push(None) def clear(self): self.clear_canvas.push(None) def draw(self, surface: pygame.Surface) -> List[MouseRegion]: regions = super().draw(surface) self._menu.handle_mouse_events(self.mouse_event.values) regions += self._menu.draw(surface) return regions
class SampleSource(BareComponent): def __init__(self): self.output = Output('sample') def push(self, value): self.output.push(value)
class LabelSource(BareComponent): def __init__(self): self.output = Output('label') def push_label(self, label: str): self.output.push(label)
class SquareFilter(EventDrivenComponent): def __init__(self, input_, output): self.input = Latest(input_, trigger=True) self.output = Output(output) async def process(self): self.output.push(self.input.value**2)
class ItemSource(BareComponent): def __init__(self): self.output = Output('item_source') def push_item(self, item): self.output.push(item)
def __init__(self, input_key: str, output_key: str): self.input: Latest[Frame] = Latest(key=input_key, trigger=True) self.keyboard: Buffer[KeyboardEvent] = Buffer(key=EventBasedKeyboardHandler.KEYBOARD_EVENT) self.output: Output[Frame] = Output(key=output_key) self.debug_output: Output[Frame] = Output(key=OPENCV_FRAME_EVENT) self._horizontal_flip_enabled = True self._vertical_flip_enabled = False
def __init__(self, layout: KeyboardLayout): """ :param layout: Use layout created by the `layout_from_args` method of the `KeyboardConfigurator` created for that concrete `KeyboardHandler` """ super().__init__(layout) self.keyboard = Output(self.KEYBOARD_EVENT) self.text = Output(self.KEYBOARD_EVENT) self.capture_trigger = Latest(self.CAPTURE_TEXT_TRIGGER)
def __init__(self, game): self.game = game self.node = 'start' self.selection = 0 self.keyboard = Buffer(EventBasedKeyboardHandler.KEYBOARD_EVENT, trigger=True) # type: Buffer[KeyboardEvent] self.text = Output('text') self.choices = Output('choices')
class SquareFilter(IteratingComponent): target_fps = 10 def __init__(self, input_, output): self.input = Latest(input_) self.output = Output(output) async def process(self): if self.input.updated: self.output.push(self.input.value**2)
class Labeler(EventDrivenComponent): def __init__(self): self.item_source = Buffer('item_source', trigger=True) self.label = Latest('label') self.output = Output('sink') async def process(self): for item in self.item_source.values: self.output.push(item + self.label.value)
def __init__(self): self.source = Latest('source', trigger=True) # type: Latest[Frame] self.people = Latest('people') # type: Latest[List[Person]] self.output = Output('display') self.debug = Output(event.OPENCV_FRAME_EVENT) self.mouse = Buffer( EventBasedMouseHandler.MOUSE_EVENT) # type: Buffer[MouseEvent] self.mouse_move = LatestBy( EventBasedMouseHandler.MOUSE_MOVEMENT, lambda m: m.region.name) # type: LatestBy[MouseMovement]
class TriggerComponent(IteratingComponent): def __init__(self) -> None: super().__init__() self.output = Output('trigger') @property def target_fps(self) -> int: return 1 async def process(self) -> None: self.output.push(None)
class SampleSubComponent(SubComponent): def __init__(self): self.input = Buffer('sample', trigger=True) self.output = Output('sample') self.log = [] def push(self, value): self.output.push(value) def do_something(self): self.log += self.input.values
class SampleSource(IteratingComponent): target_fps = 10 def __init__(self, data, name='sample'): self.output = Output(name) self.data = data.copy() async def process(self): try: self.output.push(self.data.pop(0)) except IndexError: self.logger.warning('End of data reached')
def __init__(self, config: VideoSourceConfig, key: str = 'source'): """ :param config: Can be generated via `VideoSourceConfigurator` :param key: Event key of video output """ self._path = config.path self._target_fps = config.fps self.output = Output(key) self.debug_output = Output(event.OPENCV_FRAME_EVENT) self._executor = ThreadPoolExecutor(max_workers=1) self._resolution = config.resolution self._resolution_verified = False self._capture: cv2.VideoCapture = None
def __init__(self, source, projector, debug): self._background: cv2.BackgroundSubtractor = cv2.createBackgroundSubtractorMOG2( ) self._calibration_cycle_i = 0 self._initialize_pattern() self.source: Latest[Frame] = Latest(source, trigger=True) self.projector = Output(projector) if debug: self.debug = Output(event.OPENCV_FRAME_EVENT) else: self.debug = None self._last_calibrated = 0 self._transformation_matrix = None
def __init__(self, source): super().__init__(source) self.mouse_event: Buffer[MouseEvent] = Buffer( EventBasedMouseHandler.MOUSE_EVENT) self.reset_calibration = Output( ProjectorDriver2d.RESET_CALIBRATION_TRIGGER) self.clear_canvas = Output('trigger.clear_canvas') self._menu = Menu([ Label('Menu'), Button('Calibrate', self.calibrate), Button('Clear Canvas', self.clear), ], position=(1, 0))
class MyKeyboardHandler(KeyboardHandler): ACTIONS = [ Action('enter', ['RETURN']), ] def __init__(self, layout: KeyboardLayout): super().__init__(layout) self.state = Output('state') self.name = Output('name') self._name = 'World' def key_down(self, action: str) -> None: self.state.push('input') self.capture_text('name', self._name) def key_up(self, action: str) -> None: pass def process(self) -> None: pass def text_capture_completed(self, capture_id: str, text: str): self._name = text self.name.push(self._name) self.state.push('hello') def text_capture_update(self, capture_id: str, text: str): self.name.push(text)
class FaceDetector(EventDrivenComponent): FACE_CASCADE = os.path.join(cv2.data.haarcascades, 'haarcascade_frontalface_default.xml') def __init__(self): self.source: Latest[Frame] = Latest('source', trigger=True) self.face_cascade = cv2.CascadeClassifier(self.FACE_CASCADE) self.output = Output('faces') async def process(self): if not self.source.value: return faces = await run_in_executor(self._detect_faces, self.source.value.image) self.output.push(faces) def _detect_faces(self, image): return self.face_cascade.detectMultiScale(image, 1.3, 5)
def __new__(cls, *args, **kwargs): if cls.__name__ not in cls.__count: cls.__count[cls.__name__] = 0 __instance = super().__new__(cls) __instance._numeric_id = cls.__count[cls.__name__] __instance.logger = logwood.get_logger(__instance.id) __instance.__shutdown = Output(SHUTDOWN_EVENT) cls.__count[cls.__name__] += 1 return __instance
class GameController(EventDrivenComponent): def __init__(self, game): self.game = game self.node = 'start' self.selection = 0 self.keyboard = Buffer(EventBasedKeyboardHandler.KEYBOARD_EVENT, trigger=True) # type: Buffer[KeyboardEvent] self.text = Output('text') self.choices = Output('choices') async def setup(self): self._publish_state() async def process(self): changed = False choices = self.game[self.node]['choices'] for event in self.keyboard.values: if event.active: if event.action == 'up' and self.selection > 0: self.selection -= 1 changed = True elif event.action == 'down' and self.selection + 1 < len( choices): self.selection += 1 changed = True elif event.action == 'choose' and len(choices): choice = choices[self.selection] self.node = choice['goto'] self.selection = 0 changed = True if changed: self._publish_state() def _publish_state(self): node = self.game[self.node] self.text.push(node['text']) choices = [{ 'text': choice['text'], 'selected': i == self.selection } for i, choice in enumerate(node['choices'])] self.choices.push(choices)
class PaintController(EventDrivenComponent): COLOR = (0, 255, 0) BG_COLOR = (0, 0, 0) THICKNESS = 4 def __init__(self): self.source = Latest('source', trigger=True) # type: Latest[Frame] self.output = Output('display') self.overlay = Output('overlay') self.mouse_movement = Buffer( EventBasedMouseHandler.MOUSE_MOVEMENT, trigger=True) # type: Buffer[MouseMovement] self.clear_canvas = Latest('trigger.clear_canvas', trigger=True) self.debug = Output(event.OPENCV_FRAME_EVENT) self._canvas = None self._last_position = None async def process(self): if not self.source.value: return if self.clear_canvas.updated: self._canvas = None if self._canvas is None: self._canvas = np.zeros(self.source.value.image.shape, dtype='uint8') for e in self.mouse_movement.values: if e.region.name in ['display', 'VideoSource0' ] and e.buttons[MouseButton.LEFT]: if self._last_position: cv2.line(self._canvas, self._last_position, e.restored_position, self.COLOR, self.THICKNESS) self._last_position = e.restored_position elif e.region.name in ['display', 'VideoSource0' ] and e.buttons[MouseButton.RIGHT]: if self._last_position: cv2.line(self._canvas, self._last_position, e.restored_position, self.BG_COLOR, self.THICKNESS) self._last_position = e.restored_position else: self._last_position = None output = self.source.value.image.copy() mask = (self._canvas > 0).any(-1) output[mask, :] = self._canvas[mask, :] output_frame = Frame(output, 'display') self.output.push(output_frame) self.debug.push(output_frame) overlay_frame = Frame(self._canvas, 'overlay') self.overlay.push(overlay_frame) self.debug.push(overlay_frame)
def __init__( self, source: str, overlay: str, projector: str = 'projector', config: ProjectorDriver2dConfiguration = ProjectorDriver2dConfiguration( )): """ :param source: Key of the video stream input. Needs to provide events with `Frame` payload. :param overlay: Key of the overlay input. Needs to provide events with `Frame` payload. :param projector: Key of projector output. `Frame` events are pushed to this output. :param config: Can be generated via `ProjectorDriver2dConfigurator` """ self._calibrator = _ProjectorCalibrator2d(source, projector, config.debug) super().__init__([self._calibrator]) self.overlay: Latest[Frame] = Latest(overlay, trigger=True) self.projector = Output(projector) self.reset = Latest(self.RESET_CALIBRATION_TRIGGER, trigger=True) self._calibration_started = False
class PersonDetector(EventDrivenComponent): def __init__(self): self.source = Latest('source', trigger=True) # type: Latest[Frame] self._hog = cv2.HOGDescriptor() self._hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector()) self.output = Output('people') async def process(self): rects, weights = await run_in_executor(self._detect) people = [ Person(*rect, weight) for rect, weight in zip(rects, weights) ] self.output.push(people) def _detect(self): step_size = int(self.source.value.width / 200) scale = 1.5 padding = 16 return self._hog.detectMultiScale(self.source.value.image, winStride=(step_size, step_size), scale=scale, padding=(padding, padding), useMeanshiftGrouping=True)
class PersonDisplay(EventDrivenComponent): RECT_COLOR = (255, 0, 0) HIGHLIGHTED_RECT_COLOR = (255, 255, 0) RECT_THICKNESS = 2 def __init__(self): self.source = Latest('source', trigger=True) # type: Latest[Frame] self.people = Latest('people') # type: Latest[List[Person]] self.output = Output('display') self.debug = Output(event.OPENCV_FRAME_EVENT) self.mouse = Buffer( EventBasedMouseHandler.MOUSE_EVENT) # type: Buffer[MouseEvent] self.mouse_move = LatestBy( EventBasedMouseHandler.MOUSE_MOVEMENT, lambda m: m.region.name) # type: LatestBy[MouseMovement] async def process(self): image = self.source.value.image.copy() if self.people.value: for p in self.people.value: if self._contains_mouse_pointer(p): color = self.HIGHLIGHTED_RECT_COLOR else: color = self.RECT_COLOR cv2.rectangle(image, (p.x, p.y), (p.x + p.w, p.y + p.h), color, self.RECT_THICKNESS) frame = Frame(image, 'display') self.output.push(frame) self.debug.push(frame) def _contains_mouse_pointer(self, person: Person) -> bool: if not self.mouse_move.value_dict.get('display', None): return False x, y = self.mouse_move.value_dict['display'].restored_position return person.x <= x <= person.x + person.w and person.y <= y <= person.y + person.h
def __init__(self): self.source = Latest('source', trigger=True) # type: Latest[Frame] self.output = Output('display') self.overlay = Output('overlay') self.mouse_movement = Buffer( EventBasedMouseHandler.MOUSE_MOVEMENT, trigger=True) # type: Buffer[MouseMovement] self.clear_canvas = Latest('trigger.clear_canvas', trigger=True) self.debug = Output(event.OPENCV_FRAME_EVENT) self._canvas = None self._last_position = None
def __init__(self): self.source: Latest[Frame] = Latest('source', trigger=True) self.face_cascade = cv2.CascadeClassifier(self.FACE_CASCADE) self.output = Output('faces')
def __init__(self): self.source: Latest[Frame] = Latest('source', trigger=True) self.faces = Latest('faces') self.output: Output[Frame] = Output('terminator') self.debug_output: Output[Frame] = Output(OPENCV_FRAME_EVENT)
def __init__(self, input_, output): self.input = Latest(input_) self.output = Output(output)
def __init__(self, data, name='sample'): self.output = Output(name) self.data = data.copy()