diff --git a/src/crappy/tool/camera_config/camera_config.py b/src/crappy/tool/camera_config/camera_config.py index 9662bbee..25792f5b 100644 --- a/src/crappy/tool/camera_config/camera_config.py +++ b/src/crappy/tool/camera_config/camera_config.py @@ -112,6 +112,7 @@ def __init__(self, self._run = True self._n_loops = 0 self._max_freq = max_freq + self._got_first_img: bool = False # Settings for adjusting the behavior of the zoom self._zoom_ratio = 0.9 @@ -940,6 +941,8 @@ def _on_img_resize(self, _: Optional[tk.Event] = None) -> None: self.log(logging.DEBUG, "The image canvas was resized") + self._draw_overlay() + self._resize_img() self._display_img() self.update() @@ -1023,13 +1026,12 @@ def _update_img(self) -> None: ret = self._camera.get_image() # Flag raised if no image could be grabbed - no_img = False + no_img = ret is None # If no frame could be grabbed from the camera - if ret is None: - no_img = True + if no_img: # If it's the first call, generate error image to initialize the window - if not self._n_loops: + if not self._got_first_img: self.log(logging.WARNING, "Could not get an image from the camera, " "displaying an error image instead") ret = None, np.array(Image.open(BytesIO(resource_string( @@ -1041,6 +1043,8 @@ def _update_img(self) -> None: sleep(0.001) return + # Always set, so that the error image is only ever loaded once + self._got_first_img = True self._n_loops += 1 _, img = ret @@ -1050,6 +1054,7 @@ def _update_img(self) -> None: self.shape = img.shape self._cast_img(img) + self._draw_overlay() self._resize_img() self._calc_hist() @@ -1061,3 +1066,9 @@ def _update_img(self) -> None: self._update_pixel_value() self.update() + + def _draw_overlay(self) -> None: + """Method meant to be used by subclasses for drawing an overlay on top of + the image to display.""" + + ... diff --git a/src/crappy/tool/camera_config/camera_config_boxes.py b/src/crappy/tool/camera_config/camera_config_boxes.py index 069d47bf..4ec426b1 100644 --- a/src/crappy/tool/camera_config/camera_config_boxes.py +++ b/src/crappy/tool/camera_config/camera_config_boxes.py @@ -88,7 +88,7 @@ def _handle_box_outside_img(self, _: Box) -> None: """This method is meant to simplify the customization of the action to perform when a patch is outside the image in subclasses.""" - pass + ... def _draw_spots(self) -> None: """Simply draws every spot on top of the image.""" diff --git a/src/crappy/tool/camera_config/dic_ve_config.py b/src/crappy/tool/camera_config/dic_ve_config.py index 6b1230b6..5946a345 100644 --- a/src/crappy/tool/camera_config/dic_ve_config.py +++ b/src/crappy/tool/camera_config/dic_ve_config.py @@ -3,10 +3,6 @@ from typing import Optional from tkinter.messagebox import showerror import tkinter as tk -import numpy as np -from io import BytesIO -from pkg_resources import resource_string -from time import sleep import logging from multiprocessing.queues import Queue @@ -154,61 +150,10 @@ def _stop_box(self, _: tk.Event) -> None: # This box is not needed anymore self._select_box.reset() - def _on_img_resize(self, _: Optional[tk.Event] = None) -> None: - """Same as in the parent class except it also draws the patches on top of - the displayed image.""" + def _draw_overlay(self) -> None: + """Draws the detected spots to track on top of the last acquired image.""" - self.log(logging.DEBUG, "The image canvas was resized") - - self._draw_spots() - self._resize_img() - self._display_img() - self.update() - - def _update_img(self) -> None: - """Same as in the parent class except it also draws the patches on top of - the displayed image.""" - - self.log(logging.DEBUG, "Updating the image") - - ret = self._camera.get_image() - - # If no frame could be grabbed from the camera - if ret is None: - # If it's the first call, generate error image to initialize the window - if not self._n_loops: - self.log(logging.WARNING, "Could not get an image from the camera, " - "displaying an error image instead") - ret = None, np.array(Image.open(BytesIO(resource_string( - 'crappy', 'tool/data/no_image.png')))) - # Otherwise, just pass - else: - self.log(logging.DEBUG, "No image returned by the camera") - self.update() - sleep(0.001) - return - - self._n_loops += 1 - _, img = ret - - if img.dtype != self.dtype: - self.dtype = img.dtype - if self.shape != img.shape: - self.shape = img.shape - - self._cast_img(img) self._draw_spots() - self._resize_img() - - self._calc_hist() - self._resize_hist() - - self._display_img() - self._display_hist() - - self._update_pixel_value() - - self.update() def _handle_box_outside_img(self, box: Box) -> None: """If a patch is outside the image, warning the user and resetting the diff --git a/src/crappy/tool/camera_config/dis_correl_config.py b/src/crappy/tool/camera_config/dis_correl_config.py index da17bf95..2d5871d2 100644 --- a/src/crappy/tool/camera_config/dis_correl_config.py +++ b/src/crappy/tool/camera_config/dis_correl_config.py @@ -3,10 +3,6 @@ import tkinter as tk from tkinter.messagebox import showerror from typing import Optional -import numpy as np -from io import BytesIO -from pkg_resources import resource_string -from time import sleep import logging from multiprocessing.queues import Queue @@ -112,14 +108,7 @@ 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.""" - self.log(logging.DEBUG, "Starting the selection box") - - # If the mouse is on the canvas but not on the image, do nothing - if not self._check_event_pos(event): - return - - self._select_box.x_start, \ - self._select_box.y_start = self._coord_to_pix(event.x, event.y) + super()._start_box(event) self._draw_correl_box = False @@ -150,68 +139,16 @@ def _stop_box(self, _: tk.Event) -> None: self._draw_correl_box = True - def _on_img_resize(self, _: Optional[tk.Event] = None) -> None: - """Same as in the parent class except it also draws the select box on top - of the displayed image.""" + def _draw_overlay(self) -> None: + """Draws the box to use for performing correlation on top of the last + acquired image. - self.log(logging.DEBUG, "The image canvas was resized") - - # Do not draw the correl box if the user is creating the select box - if self._draw_correl_box: - self._draw_box(self._correl_box) - self._draw_box(self._select_box) + Does not draw the correl box is the user is using the selection box. + """ - self._resize_img() - self._display_img() - self.update() - - def _update_img(self) -> None: - """Same as in the parent class except it also draws the select box on top - of the displayed image.""" - - self.log(logging.DEBUG, "Updating the image") - - ret = self._camera.get_image() - - # If no frame could be grabbed from the camera - if ret is None: - # If it's the first call, generate error image to initialize the window - if not self._n_loops: - self.log(logging.WARNING, "Could not get an image from the camera, " - "displaying an error image instead") - ret = None, np.array(Image.open(BytesIO(resource_string( - 'crappy', 'tool/data/no_image.png')))) - # Otherwise, just pass - else: - self.log(logging.DEBUG, "No image returned by the camera") - self.update() - sleep(0.001) - return - - self._n_loops += 1 - _, img = ret - - if img.dtype != self.dtype: - self.dtype = img.dtype - if self.shape != img.shape: - self.shape = img.shape - - self._cast_img(img) - # Do not draw the correl box if the user is creating the select box if self._draw_correl_box: self._draw_box(self._correl_box) self._draw_box(self._select_box) - self._resize_img() - - self._calc_hist() - self._resize_hist() - - self._display_img() - self._display_hist() - - self._update_pixel_value() - - self.update() def _handle_box_outside_img(self, _: Box) -> None: """If the correl box is outside the image, it means that the image size has diff --git a/src/crappy/tool/camera_config/video_extenso_config.py b/src/crappy/tool/camera_config/video_extenso_config.py index cacbbe8a..b18d4198 100644 --- a/src/crappy/tool/camera_config/video_extenso_config.py +++ b/src/crappy/tool/camera_config/video_extenso_config.py @@ -3,10 +3,6 @@ import tkinter as tk from tkinter.messagebox import showerror from typing import Optional -import numpy as np -from io import BytesIO -from pkg_resources import resource_string -from time import sleep import logging from multiprocessing.queues import Queue @@ -115,10 +111,7 @@ def _create_buttons(self) -> None: """Compared with the parent class, creates an extra button for saving the original position of the spots.""" - self._update_button = tk.Button(self._sets_frame, text="Apply Settings", - command=self._update_settings) - self._update_button.pack(expand=False, fill='none', ipadx=5, ipady=5, - padx=5, pady=5, anchor='n', side='top') + super()._create_buttons() self._update_button = tk.Button(self._sets_frame, text="Save L0", command=self._save_l0) @@ -166,63 +159,14 @@ def _save_l0(self) -> None: f"Successfully saved L0 ! L0 x : {self._detector.spots.x_l0}, " f"L0 y : {self._detector.spots.y_l0}") - def _on_img_resize(self, _: Optional[tk.Event] = None) -> None: - """Same as in the parent class except it also draws the patches and the - select box on top of the displayed image.""" + def _draw_overlay(self) -> None: + """Draws the detected spots to track on top of the last acquired image. - self.log(logging.DEBUG, "The image canvas was resized") + Also draws the selection box if the user is currently drawing one. + """ self._draw_box(self._select_box) self._draw_spots() - self._resize_img() - self._display_img() - self.update() - - def _update_img(self) -> None: - """Same as in the parent class except it also draws the patches and the - select box on top of the displayed image.""" - - self.log(logging.DEBUG, "Updating the image") - - ret = self._camera.get_image() - - # If no frame could be grabbed from the camera - if ret is None: - # If it's the first call, generate error image to initialize the window - if not self._n_loops: - self.log(logging.WARNING, "Could not get an image from the camera, " - "displaying an error image instead") - ret = None, np.array(Image.open(BytesIO(resource_string( - 'crappy', 'tool/data/no_image.png')))) - # Otherwise, just pass - else: - self.log(logging.DEBUG, "No image returned by the camera") - self.update() - sleep(0.001) - return - - self._n_loops += 1 - _, img = ret - - if img.dtype != self.dtype: - self.dtype = img.dtype - if self.shape != img.shape: - self.shape = img.shape - - self._cast_img(img) - self._draw_box(self._select_box) - self._draw_spots() - self._resize_img() - - self._calc_hist() - self._resize_hist() - - self._display_img() - self._display_hist() - - self._update_pixel_value() - - self.update() def _handle_box_outside_img(self, _: Box) -> None: """If a patch is outside the image, it means that the image size has been