Beispiel #1
0
 def make_window(self):
     """ """
     self.window_main = CameraExperimentWindow(experiment=self)
     self.window_main.construct_ui()
     self.window_main.show()
     self.restore_window_state()
     self.initialize_plots()
Beispiel #2
0
class CameraVisualExperiment(VisualExperiment):
    """General class for Experiment that need to handle a camera.
    It implements a view of frames from the camera in the control GUI, and the
    respective parameters.
    For debugging it can be used with a video read from file with the
    VideoFileSource class.

    Parameters
    ----------

    Returns
    -------

    """

    def __init__(self, *args, camera, camera_queue_mb=100, **kwargs):
        """
        :param video_file: if not using a camera, the video file
        file for the test input
        :param kwargs:
        """
        super().__init__(*args, **kwargs)
        if camera.get("video_file", None) is None:
            self.camera = CameraSource(
                camera["type"],
                rotation=camera.get("rotation", 0),
                downsampling=camera.get("downsampling", 1),
                roi=camera.get("roi", (-1, -1, -1, -1)),
                max_mbytes_queue=camera_queue_mb,
                camera_params=camera.get("camera_params", dict()),
            )
            self.camera_state = CameraControlParameters(tree=self.dc)
        else:
            self.camera = VideoFileSource(
                camera["video_file"],
                rotation=camera.get("rotation", 0),
                max_mbytes_queue=camera_queue_mb,
            )
            self.camera_state = VideoControlParameters(tree=self.dc)

        self.acc_camera_framerate = FramerateQueueAccumulator(
            self,
            queue=self.camera.framerate_queue,
            goal_framerate=camera.get("min_framerate", None),
            name="camera",  # TODO implement no goal
        )

        # New parameters are sent with GUI timer:
        self.gui_timer.timeout.connect(self.send_gui_parameters)
        self.gui_timer.timeout.connect(self.acc_camera_framerate.update_list)

    def reset(self):
        super().reset()
        self.acc_camera_framerate.reset()

    def initialize_plots(self):
        super().initialize_plots()

    def send_gui_parameters(self):
        self.camera.control_queue.put(self.camera_state.params.changed_values())
        self.camera_state.params.acknowledge_changes()

    def start_experiment(self):
        """ """
        self.go_live()
        super().start_experiment()

    def make_window(self):
        """ """
        self.window_main = CameraExperimentWindow(experiment=self)
        self.window_main.construct_ui()
        self.window_main.show()
        self.restore_window_state()
        self.initialize_plots()

    def go_live(self):
        """ """
        sys.excepthook = self.excepthook
        self.camera.start()

    def wrap_up(self, *args, **kwargs):
        """

        Parameters
        ----------
        *args :
            
        **kwargs :
            

        Returns
        -------

        """
        self.gui_timer.stop()
        super().wrap_up(*args, **kwargs)
        self.camera.kill_event.set()

        for q in [self.camera.frame_queue]:
            q.clear()

        self.camera.join()

    def excepthook(self, exctype, value, tb):
        """

        Parameters
        ----------
        exctype :
            
        value :
            
        tb :
            

        Returns
        -------

        """
        traceback.print_tb(tb)
        print("{0}: {1}".format(exctype, value))
        self.camera.kill_event.set()
        self.camera.join()
Beispiel #3
0
 def make_window(self):
     """ """
     self.window_main = CameraExperimentWindow(experiment=self)
     self.window_main.show()
Beispiel #4
0
class CameraVisualExperiment(VisualExperiment):
    """
    General class for Experiment that need to handle a camera.
    It implements a view of frames from the camera in the control GUI, and the respective parameters.
    For debugging it can be used with a video read from file with the VideoFileSource class.
    """
    def __init__(self,
                 *args,
                 camera: dict,
                 camera_queue_mb: int = 100,
                 recording: Optional[Dict[str, Any]] = None,
                 **kwargs) -> None:
        """
        Parameters
        ----------
        camera
            dictionary containing the parameters for the camera setup (i.e. for offline processing it would contain
            an entry 'video_file' with the path to the video).
        camera_queue_mb
            the maximum size of frames that are kept at once, if the limit is exceeded, frames will be dropped.
        recording
            dictionary containing the parameters for the recording (i.e. to save to an mp4 file, add the 'extension'
            entry with the 'mp4' value). If None, no recording is performed.
        """
        super().__init__(*args, **kwargs)
        if camera.get("video_file", None) is None:
            self.camera = CameraSource(
                camera["type"],
                rotation=camera.get("rotation", 0),
                downsampling=camera.get("downsampling", 1),
                roi=camera.get("roi", (-1, -1, -1, -1)),
                max_mbytes_queue=camera_queue_mb,
                camera_params=camera.get("camera_params", dict()),
            )
            self.camera_state = CameraControlParameters(tree=self.dc)
        else:
            self.camera = VideoFileSource(
                camera["video_file"],
                rotation=camera.get("rotation", 0),
                max_mbytes_queue=camera_queue_mb,
            )
            self.camera_state = VideoControlParameters(tree=self.dc)

        self.acc_camera_framerate = FramerateQueueAccumulator(
            self,
            queue=self.camera.framerate_queue,
            goal_framerate=camera.get("min_framerate", None),
            name="camera",  # TODO implement no goal
        )

        # New parameters are sent with GUI timer:
        self.gui_timer.timeout.connect(self.send_gui_parameters)
        self.gui_timer.timeout.connect(self.acc_camera_framerate.update_list)

        self.recording = recording
        if recording is not None:
            self._setup_recording(
                kbit_framerate=recording.get("kbit_rate", 1000),
                extension=recording["extension"],
            )

    def reset(self) -> None:
        super().reset()
        self.acc_camera_framerate.reset()

    def initialize_plots(self) -> None:
        super().initialize_plots()

    def send_gui_parameters(self) -> None:
        self.camera.control_queue.put(
            self.camera_state.params.changed_values())
        self.camera_state.params.acknowledge_changes()

    def start_experiment(self) -> None:
        """ """
        self.go_live()
        super().start_experiment()

    def start_protocol(self) -> None:
        """
        Starts the recording if the recording parameters are set.
        """
        if self.recording is not None:
            # Slight work around, the problem is in when set_id() is updated.
            # See issue #71.
            p = Path()
            fb = p.joinpath(self.folder_name,
                            self.current_timestamp.strftime("%H%M%S") + "_")
            self.dc.add_static_data(fb, "recording/filename")
            self._start_recording(fb)

        super().start_protocol()

    def end_protocol(self, save: bool = True) -> None:
        """
        Stops the recording if the recording parameters are set.
        """
        if self.recording is not None:
            self._stop_recording()

        super().end_protocol(save=save)

    def make_window(self) -> None:
        """ """
        self.window_main = CameraExperimentWindow(experiment=self)
        self.window_main.construct_ui()
        self.window_main.show()
        self.restore_window_state()
        self.initialize_plots()

    def go_live(self) -> None:
        """ """
        sys.excepthook = self.excepthook
        self.camera.start()

    def wrap_up(self, *args, **kwargs) -> None:
        self.gui_timer.stop()
        super().wrap_up(*args, **kwargs)
        self.camera.kill_event.set()

        for q in [self.camera.frame_queue]:
            q.clear()

        self.camera.join()

    def _setup_frame_dispatcher(self,
                                recording_event: Event = None
                                ) -> DispatchProcess:
        """
        Creates a dispatcher that handles the frames of the camera. It will trigger the recording (i.e. stop it) using
        the given 'recording_event' event.

        Parameters
        ----------
        recording_event
            The event used for recording (if relevant).
        """
        return DispatchProcess(self.camera.frame_queue, self.camera.kill_event,
                               recording_event)

    def _setup_recording(self,
                         kbit_framerate: int = 1000,
                         extension: str = "mp4") -> None:
        """
        Does the necessary setup before performing the recording, such as creating events, setting up the dispatcher
        (via _setup_frame_dispatcher) and initialising the VideoWriter.

        Parameters
        ----------
        kbit_framerate
            the byte rate at which the video is encoded.
        extension
            the extension used at the end of the video file.
        """
        self.recording_event = Event()
        self.reset_event = Event()
        self.finish_event = Event()

        self.frame_dispatcher = self._setup_frame_dispatcher(
            self.recording_event)
        self.frame_dispatcher.start()

        if extension == "h5":
            self.frame_recorder = H5VideoWriter(
                input_queue=self.frame_dispatcher.frame_copy_queue,
                recording_event=self.recording_event,
                reset_event=self.reset_event,
                finish_event=self.finish_event,
                log_format=self.log_format,
            )
        else:
            self.frame_recorder = StreamingVideoWriter(
                input_queue=self.frame_dispatcher.frame_copy_queue,
                recording_event=self.recording_event,
                reset_event=self.reset_event,
                finish_event=self.finish_event,
                kbit_rate=kbit_framerate,
                log_format=self.log_format,
            )

        self.frame_recorder.start()

    def _start_recording(self, filename: str) -> None:
        """
        Pushes the filename to the queue and sets the recording event in order to start the recording.

        Parameters
        ----------
        filename
            a unique identifier that will be added to the video file.
        """
        self.frame_recorder.filename_queue.put(filename)
        self.recording_event.set()

    def _stop_recording(self) -> None:
        """
        Stops the recording by clearing the recording event.
        """
        self.recording_event.clear()

    def _finish_recording(self) -> None:
        """
        Finishes the recording process and joins the frame recorder.
        """
        self.frame_recorder.finish_event.set()
        self.frame_recorder.join()

    def excepthook(self, exctype, value, tb) -> None:
        if self.recording is not None:
            self._finish_recording()

        traceback.print_tb(tb)
        print("{0}: {1}".format(exctype, value))
        self.camera.kill_event.set()
        self.camera.join()
Beispiel #5
0
class CameraExperiment(Experiment):
    """General class for Experiment that need to handle a camera.
    It implements a view of frames from the camera in the control GUI, and the
    respective parameters.
    For debugging it can be used with a video read from file with the
    VideoFileSource class.

    Parameters
    ----------

    Returns
    -------

    """
    def __init__(self, *args, camera_config, camera_queue_mb=100, **kwargs):
        """
        :param video_file: if not using a camera, the video file
        file for the test input
        :param kwargs:
        """
        if camera_config.get("video_file", None) is None:
            self.camera = CameraSource(
                camera_config["type"],
                rotation=camera_config.get("rotation", 0),
                downsampling=camera_config.get("downsampling", 1),
                max_mbytes_queue=camera_queue_mb,
            )
        else:
            self.camera = VideoFileSource(
                camera_config["video_file"],
                rotation=camera_config["rotation"],
                max_mbytes_queue=camera_queue_mb,
            )

        self.camera_control_params = CameraControlParameters()

        self.gui_timer = QTimer()
        self.gui_timer.setSingleShot(False)

        super().__init__(*args, **kwargs)

    def start_experiment(self):
        """ """
        self.go_live()
        super().start_experiment()

    def make_window(self):
        """ """
        self.window_main = CameraExperimentWindow(experiment=self)
        self.window_main.show()

    def go_live(self):
        """ """
        self.gui_timer.start(1000 // 60)
        sys.excepthook = self.excepthook
        self.camera.start()

    def wrap_up(self, *args, **kwargs):
        """

        Parameters
        ----------
        *args :
            
        **kwargs :
            

        Returns
        -------

        """
        super().wrap_up(*args, **kwargs)
        self.camera.kill_event.set()
        self.camera.terminate()
        print("Camera process terminated")
        self.gui_timer.stop()

    def excepthook(self, exctype, value, tb):
        """

        Parameters
        ----------
        exctype :
            
        value :
            
        tb :
            

        Returns
        -------

        """
        traceback.print_tb(tb)
        print("{0}: {1}".format(exctype, value))
        self.camera.kill_event.set()
        self.camera.terminate()