Source code for crappy.tool.camera_config.dis_correl_config

# coding: utf-8

import tkinter as tk
from tkinter.messagebox import showerror
import logging
from multiprocessing.queues import Queue

from .camera_config_boxes import CameraConfigBoxes
from .config_tools import Box
from ...camera.meta_camera import Camera
from ..._global import OptionalModule

try:
  from PIL import Image
except (ModuleNotFoundError, ImportError):
  Image = OptionalModule("pillow")


[docs] class DISCorrelConfig(CameraConfigBoxes): """Class similar to :class:`~crappy.tool.camera_config.CameraConfig` but also allowing to select the area on which the correlation will be performed. It relies on the :class:`~crappy.tool.camera_config.config_tools.Box` tool. It is meant to be used for configuring the :class:`~crappy.blocks.DISCorrel` Block. .. versionadded:: 1.4.0 .. versionchanged:: 2.0.0 renamed from *DISConfig* to *DISCorrelConfig* """
[docs] def __init__(self, camera: Camera, log_queue: Queue, log_level: int | None, max_freq: float | None, patch: Box) -> None: """Initializes the parent class and sets the correlation Box. Args: camera: The :class:`~crappy.camera.Camera` object in charge of acquiring the images. log_queue: A :obj:`multiprocessing.Queue` for sending the log messages to the main :obj:`~logging.Logger`, only used in Windows. .. versionadded:: 2.0.0 log_level: The minimum logging level of the entire Crappy script, as an :obj:`int`. .. versionadded:: 2.0.0 max_freq: The maximum frequency this window is allowed to loop at. It is simply the ``freq`` attribute of the :class:`~crappy.blocks.Camera` Block. .. versionadded:: 2.0.0 patch: The :class:`~crappy.tool.camera_config.config_tools.Box` container that will save the information on the patch where to perform image correlation. .. versionadded:: 2.0.0 """ self._correl_box = patch self._draw_correl_box = True super().__init__(camera, log_queue, log_level, max_freq)
@property def box(self) -> Box: """Returns the :class:`~crappy.tool.camera_config.config_tools.Box` object containing the region of interest. .. versionadded:: 1.5.10 """ return self._correl_box def finish(self) -> None: """Method called when the user tries to close the configuration window. Checks that a patch was selected on the image. If not, warns the user and prevents him from exiting except with CTRL+C. .. versionadded:: 2.0.0 """ if self.box.no_points(): self.log(logging.WARNING, "No ROI selected ! Not exiting the " "configuration window") showerror('Error !', message="Please select a ROI before exiting the config " "window !\nOr hit CTRL+C to exit Crappy") return super().stop() def _set_bindings(self) -> None: """Binds the left mouse button click for drawing the box on which the correlation will be performed.""" super()._set_bindings() self._img_canvas.bind('<ButtonPress-1>', self._start_box) self._img_canvas.bind('<B1-Motion>', self._extend_box) self._img_canvas.bind('<ButtonRelease-1>', self._stop_box) def _start_box(self, event: tk.Event) -> None: """Simply saves the position of the user click, and disables the display of the current correl box.""" super()._start_box(event) self._draw_correl_box = False def _stop_box(self, _: tk.Event) -> None: """Makes sure that the selected region is valid, sets it as the new correl box, and enables the display of the correl box.""" self.log(logging.DEBUG, "Ending the selection box") # If it's just a regular click with no dragging, do nothing if self._img is None or self._select_box.no_points(): self._select_box.reset() self._draw_correl_box = True return # The sides need to be sorted before slicing numpy array y_left, y_right, x_top, x_bottom = self._select_box.sorted() # If the box is flat, resetting it if y_left == y_right or x_top == x_bottom: self._select_box.reset() self._draw_correl_box = True return # The new correl box is just the copy of the select box self._correl_box.update(self._select_box) self._select_box.reset() self._draw_correl_box = True def _draw_overlay(self) -> None: """Draws the box to use for performing correlation on top of the last acquired image. Does not draw the correl box is the user is using the selection box. """ if self._draw_correl_box: self._draw_box(self._correl_box) self._draw_box(self._select_box) def _handle_box_outside_img(self, _: Box) -> None: """If the correl box is outside the image, it means that the image size has been modified. Simply resetting the correl box then.""" self._correl_box.reset()