diff --git a/graxpert/deconvolution.py b/graxpert/deconvolution.py index 7dbda1e..db51a4e 100644 --- a/graxpert/deconvolution.py +++ b/graxpert/deconvolution.py @@ -1,5 +1,6 @@ import copy import logging + import numpy as np import onnxruntime as ort @@ -10,7 +11,10 @@ def deconvolve(image, ai_path, strength, psfsize, batch_size=4, window_size=512, stride=448, progress=None, ai_gpu_acceleration=True): print("Starting deconvolution") - strength = 0.95 * strength # TODO : strenght of exactly 1.0 brings no results, to fix + strength = 0.95 * strength # TODO : strenght of exactly 1.0 brings no results, to fix + psfsize = np.clip((psfsize / 2.355 - 1.0) / 5.0, 0.05, 0.95) + + logging.info(f"Calculated normalized PSFsize value: {psfsize}") if batch_size < 1: logging.info(f"mapping batch_size of {batch_size} to 1") @@ -22,7 +26,8 @@ def deconvolve(image, ai_path, strength, psfsize, batch_size=4, window_size=512, logging.info(f"mapping batch_size of {batch_size} to {2 ** (batch_size).bit_length() // 2}") batch_size = 2 ** (batch_size).bit_length() // 2 # map batch_size to power of two - input = copy.deepcopy(image) + if batch_size >= 4 and image.shape[-1] == 3: + batch_size = batch_size // 4 num_colors = image.shape[-1] @@ -48,14 +53,6 @@ def deconvolve(image, ai_path, strength, psfsize, batch_size=4, window_size=512, output = copy.deepcopy(image) - # _min = np.min(image, axis=(0, 1)) - # image = image - _min + 1e-5 - # image = np.log(image) - - # _mean = np.mean(image, axis=(0, 1)) - # _std = np.std(image, axis=(0, 1)) - # image = (image - _mean) / _std * 0.1 - providers = get_execution_providers_ordered(ai_gpu_acceleration) session = ort.InferenceSession(ai_path, providers=providers) @@ -93,7 +90,7 @@ def cancel_listener(event): x = stride * i y = stride * j - tile = image[x: x + window_size, y: y + window_size, :] + tile = image[x : x + window_size, y : y + window_size, :] _min = np.min(tile, axis=(0, 1)) tile = tile - _min + 1e-5 @@ -115,7 +112,6 @@ def cancel_listener(event): input_tiles = np.array(input_tiles) input_tiles = np.moveaxis(input_tiles, -1, 1) input_tiles = np.reshape(input_tiles, [input_tiles.shape[0] * num_colors, 1, window_size, window_size]) - # input_tiles_with_strenght = np.concatenate([input_tiles, np.full_like(input_tiles, strength)], axis=1) output_tiles = [] sigma = np.full(shape=(input_tiles.shape[0], 1), fill_value=psfsize, dtype=np.float32) @@ -156,11 +152,9 @@ def cancel_listener(event): logging.info(f"Progress: {p}%") last_progress = p - output = output[offset: H + offset, offset: W + offset, :] + output = output[offset : H + offset, offset : W + offset, :] output = np.clip(output, 0.0, 1.0) - # output = strength * output + (1 - strength) * input - eventbus.remove_listener(AppEvents.CANCEL_PROCESSING, cancel_listener) logging.info("Finished deconvolution") diff --git a/graxpert/main.py b/graxpert/main.py index 799cc8a..26cf395 100644 --- a/graxpert/main.py +++ b/graxpert/main.py @@ -261,7 +261,7 @@ def main(): help='Number of image tiles which Graxpert will denoise in parallel. Be careful: increasing this value might result in out-of-memory errors. Valid Range: 1..32, default: "4"', ) - deconv_obj_parser = argparse.ArgumentParser("GraXpert Deconvolution Object", parents=[parser], description="GraXpert, the astronomical denoising tool") + deconv_obj_parser = argparse.ArgumentParser("GraXpert Deconvolution Object", parents=[parser], description="GraXpert, the astronomical deconvolution tool") deconv_obj_parser.add_argument( "-ai_version", "--ai_version", diff --git a/graxpert/preferences.py b/graxpert/preferences.py index e7c3831..32443ce 100644 --- a/graxpert/preferences.py +++ b/graxpert/preferences.py @@ -44,7 +44,7 @@ class Prefs: denoise_ai_version: AnyStr = None graxpert_version: AnyStr = graxpert_version deconvolution_strength: float = 0.5 - deconvolution_psfsize: float = 0.3 + deconvolution_psfsize: float = 5.0 denoise_strength: float = 0.5 ai_batch_size: int = 4 ai_gpu_acceleration: bool = True diff --git a/graxpert/ui/left_menu.py b/graxpert/ui/left_menu.py index 80cdaaa..b7a503a 100644 --- a/graxpert/ui/left_menu.py +++ b/graxpert/ui/left_menu.py @@ -232,8 +232,8 @@ def __init__(self, parent, **kwargs): self.deconvolution_strength.trace_add("write", lambda a, b, c: eventbus.emit(AppEvents.DECONVOLUTION_STRENGTH_CHANGED, {"deconvolution_strength": self.deconvolution_strength.get()})) self.deconvolution_psfsize = tk.DoubleVar() - self.deconvolution_strength.set(graxpert.prefs.deconvolution_psfsize) - self.deconvolution_strength.trace_add("write", lambda a, b, c: eventbus.emit(AppEvents.DECONVOLUTION_PSFSIZE_CHANGED, {"deconvolution_psfsize": self.deconvolution_psfsize.get()})) + self.deconvolution_psfsize.set(graxpert.prefs.deconvolution_psfsize) + self.deconvolution_psfsize.trace_add("write", lambda a, b, c: eventbus.emit(AppEvents.DECONVOLUTION_PSFSIZE_CHANGED, {"deconvolution_psfsize": self.deconvolution_psfsize.get()})) self.create_children() self.setup_layout() @@ -259,12 +259,12 @@ def create_children(self): self.tt_load = tooltip.Tooltip(self.deconvolution_button, text=tooltip.deconvolution_text) self.deconvolution_strength_slider = ValueSlider( - self.sub_frame, width=default_label_width, variable_name=_("Deconvolution Strength"), variable=self.deconvolution_strength, min_value=0.0, max_value=1.0, precision=2 + self.sub_frame, width=default_label_width, variable_name=_("Deconvolution Strength"), variable=self.deconvolution_strength, min_value=0.0, max_value=1.0, precision=1 ) tooltip.Tooltip(self.deconvolution_strength_slider, text=tooltip.deconvolution_strength_text) self.deconvolution_psfsize_slider = ValueSlider( - self.sub_frame, width=default_label_width, variable_name=_("Blur PSF Size"), variable=self.deconvolution_psfsize, min_value=0.0, max_value=1.0, precision=2 + self.sub_frame, width=default_label_width, variable_name=_("Image FHWM (in pixels)"), variable=self.deconvolution_psfsize, min_value=0.0, max_value=14.0, precision=1 ) tooltip.Tooltip(self.deconvolution_psfsize_slider, text=tooltip.deconvolution_psfsize_text)