From bc3f7acd7f46fb39e76824b10184a6232d1519ab Mon Sep 17 00:00:00 2001 From: Adrian Tschan Date: Wed, 9 Oct 2024 12:35:32 +0000 Subject: [PATCH 1/3] Add upper and lower quantile rescaling to calculate_registration_image_based.py for more robust registration --- fractal_tasks_core/__FRACTAL_MANIFEST__.json | 12 +++++++++ .../calculate_registration_image_based.py | 25 +++++++++++++++++++ tests/tasks/test_registration.py | 8 ++++++ 3 files changed, 45 insertions(+) diff --git a/fractal_tasks_core/__FRACTAL_MANIFEST__.json b/fractal_tasks_core/__FRACTAL_MANIFEST__.json index 2060e3179..fd3d01268 100644 --- a/fractal_tasks_core/__FRACTAL_MANIFEST__.json +++ b/fractal_tasks_core/__FRACTAL_MANIFEST__.json @@ -1123,6 +1123,18 @@ "title": "Method", "description": "Method to use for image registration. The available methods are `phase_cross_correlation` (scikit-image package, works for 2D & 3D) and \"chi2_shift\" (image_registration package, only works for 2D images)." }, + "lower_rescale_quantile": { + "default": 0.0, + "title": "Lower Rescale Quantile", + "type": "number", + "description": "Lower quantile for rescaling the image intensities before applying registration. Can be helpful to deal with image artifacts. Default is 0." + }, + "upper_rescale_quantile": { + "default": 0.99, + "title": "Upper Rescale Quantile", + "type": "number", + "description": "Upper quantile for rescaling the image intensities before applying registration. Can be helpful to deal with image artifacts. Default is 0.99." + }, "roi_table": { "default": "FOV_ROI_table", "title": "Roi Table", diff --git a/fractal_tasks_core/tasks/calculate_registration_image_based.py b/fractal_tasks_core/tasks/calculate_registration_image_based.py index 0cb618c94..9fcacee95 100755 --- a/fractal_tasks_core/tasks/calculate_registration_image_based.py +++ b/fractal_tasks_core/tasks/calculate_registration_image_based.py @@ -21,6 +21,7 @@ import zarr from pydantic import validate_call from skimage.registration import phase_cross_correlation +from skimage.exposure import rescale_intensity from fractal_tasks_core.channels import get_channel_from_image_zarr from fractal_tasks_core.channels import OmeroChannel @@ -77,6 +78,8 @@ def calculate_registration_image_based( # Core parameters wavelength_id: str, method: RegistrationMethod = RegistrationMethod.PHASE_CROSS_CORRELATION, + lower_rescale_quantile: float = 0.0, + upper_rescale_quantile: float = 0.99, roi_table: str = "FOV_ROI_table", level: int = 2, ) -> None: @@ -102,6 +105,12 @@ def calculate_registration_image_based( are `phase_cross_correlation` (scikit-image package, works for 2D & 3D) and "chi2_shift" (image_registration package, only works for 2D images). + lower_rescale_quantile: Lower quantile for rescaling the image + intensities before applying registration. Can be helpful + to deal with image artifacts. Default is 0. + upper_rescale_quantile: Upper quantile for rescaling the image + intensities before applying registration. Can be helpful + to deal with image artifacts. Default is 0.99. roi_table: Name of the ROI table over which the task loops to calculate the registration. Examples: `FOV_ROI_table` => loop over the field of views, `well_ROI_table` => process the whole well as @@ -247,6 +256,22 @@ def calculate_registration_image_based( compute=compute, ) + # Rescale the images + img_ref = rescale_intensity( + img_ref, + in_range=( + np.quantile(img_ref, lower_rescale_quantile), + np.quantile(img_ref, upper_rescale_quantile), + ), + ) + img_acq_x = rescale_intensity( + img_acq_x, + in_range=( + np.quantile(img_acq_x, lower_rescale_quantile), + np.quantile(img_acq_x, upper_rescale_quantile), + ), + ) + ############## # Calculate the transformation ############## diff --git a/tests/tasks/test_registration.py b/tests/tasks/test_registration.py index 4e0bd659f..2b357314f 100755 --- a/tests/tasks/test_registration.py +++ b/tests/tasks/test_registration.py @@ -237,6 +237,8 @@ def test_multiplexing_registration( tmp_path, monkeypatch: MonkeyPatch, method: str, + lower_rescale_quantile: float = 0.0, + upper_rescale_quantile: float = 0.99, # Given the test data, only implemented per FOV roi_table="FOV_ROI_table", ): @@ -348,6 +350,8 @@ def test_multiplexing_registration( init_args=image["init_args"], wavelength_id="A01_C01", method=method, + lower_rescale_quantile=lower_rescale_quantile, + upper_rescale_quantile=upper_rescale_quantile, roi_table=roi_table, ) @@ -438,6 +442,8 @@ def test_multiplexing_registration_3d( tmp_path, monkeypatch: MonkeyPatch, method: str, + lower_rescale_quantile: float = 0.0, + upper_rescale_quantile: float = 0.99, # Given the test data, only implemented per FOV roi_table="FOV_ROI_table", ): @@ -526,6 +532,8 @@ def test_multiplexing_registration_3d( init_args=image["init_args"], wavelength_id="A01_C01", method=method, + lower_rescale_quantile=lower_rescale_quantile, + upper_rescale_quantile=upper_rescale_quantile, roi_table=roi_table, ) pytest.skip( From b3f45b4c809175458d904e311bfc0e77a544e142 Mon Sep 17 00:00:00 2001 From: jluethi Date: Thu, 10 Oct 2024 13:33:38 +0200 Subject: [PATCH 2/3] Fix import order --- fractal_tasks_core/tasks/calculate_registration_image_based.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fractal_tasks_core/tasks/calculate_registration_image_based.py b/fractal_tasks_core/tasks/calculate_registration_image_based.py index 9fcacee95..6bb783662 100755 --- a/fractal_tasks_core/tasks/calculate_registration_image_based.py +++ b/fractal_tasks_core/tasks/calculate_registration_image_based.py @@ -20,8 +20,8 @@ import numpy as np import zarr from pydantic import validate_call -from skimage.registration import phase_cross_correlation from skimage.exposure import rescale_intensity +from skimage.registration import phase_cross_correlation from fractal_tasks_core.channels import get_channel_from_image_zarr from fractal_tasks_core.channels import OmeroChannel From 82e57c5375956f6413d236742b152dbd2cf241e7 Mon Sep 17 00:00:00 2001 From: jluethi Date: Thu, 10 Oct 2024 13:35:51 +0200 Subject: [PATCH 3/3] Update Changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9c434c02..064c52fd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ **Note**: Numbers like (\#123) point to closed Pull Requests on the fractal-tasks-core repository. +# 1.3.2 +* Tasks: + * Add percentile-based rescaling to calculate registration task to make it more robust (\#848) * Dependencies: * Relax pandas constraint to `<2`. * Relax torch constraint to `<=3.0.0`.