Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter Images #52

Merged
merged 10 commits into from
Aug 13, 2024
26 changes: 23 additions & 3 deletions brainglobe_registration/registration_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from napari.utils.notifications import show_error
from napari.viewer import Viewer
from pytransform3d.rotations import active_matrix_from_angle
from qtpy.QtWidgets import QPushButton, QTabWidget
from qtpy.QtWidgets import QCheckBox, QPushButton, QTabWidget
from skimage.segmentation import find_boundaries
from skimage.transform import rescale

Expand All @@ -33,6 +33,7 @@
adjust_napari_image_layer,
calculate_rotated_bounding_box,
check_atlas_installed,
filter_plane,
find_layer_index,
get_image_layer_names,
open_parameter_file,
Expand Down Expand Up @@ -141,6 +142,9 @@
self._on_default_file_selection_change
)

self.filter_checkbox = QCheckBox("Filter Images")
self.filter_checkbox.setChecked(False)

self.run_button = QPushButton("Run")
self.run_button.clicked.connect(self._on_run_button_click)
self.run_button.setEnabled(False)
Expand Down Expand Up @@ -176,6 +180,9 @@
self.add_widget(
self.parameters_tab, widget_title="Advanced Settings (optional)"
)

self.add_widget(self.filter_checkbox, collapsible=False)

self.add_widget(self.run_button, collapsible=False)

self.layout().itemAt(1).widget().collapse(animate=False)
Expand Down Expand Up @@ -276,9 +283,22 @@

current_atlas_slice = self._viewer.dims.current_step[0]

if self.filter_checkbox.isChecked():
atlas_layer = filter_plane(

Check warning on line 287 in brainglobe_registration/registration_widget.py

View check run for this annotation

Codecov / codecov/patch

brainglobe_registration/registration_widget.py#L287

Added line #L287 was not covered by tests
self._atlas_data_layer.data[
current_atlas_slice, :, :

Check warning on line 289 in brainglobe_registration/registration_widget.py

View check run for this annotation

Codecov / codecov/patch

brainglobe_registration/registration_widget.py#L289

Added line #L289 was not covered by tests
].compute()
)
moving_image_layer = filter_plane(self._moving_image.data)

Check warning on line 292 in brainglobe_registration/registration_widget.py

View check run for this annotation

Codecov / codecov/patch

brainglobe_registration/registration_widget.py#L292

Added line #L292 was not covered by tests
else:
atlas_layer = self._atlas_data_layer.data[

Check warning on line 294 in brainglobe_registration/registration_widget.py

View check run for this annotation

Codecov / codecov/patch

brainglobe_registration/registration_widget.py#L294

Added line #L294 was not covered by tests
current_atlas_slice, :, :
]
moving_image_layer = self._moving_image.data

result, parameters, registered_annotation_image = run_registration(
self._atlas_data_layer.data[current_atlas_slice, :, :],
self._moving_image.data,
atlas_layer,
moving_image_layer,

Check warning on line 301 in brainglobe_registration/registration_widget.py

View check run for this annotation

Codecov / codecov/patch

brainglobe_registration/registration_widget.py#L301

Added line #L301 was not covered by tests
self._atlas_annotations_layer.data[current_atlas_slice, :, :],
self.transform_selections,
)
Expand Down
79 changes: 79 additions & 0 deletions brainglobe_registration/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from brainglobe_utils.qtpy.dialog import display_info
from pytransform3d.rotations import active_matrix_from_angle
from qtpy.QtWidgets import QWidget
from scipy.ndimage import gaussian_filter
from skimage import morphology


def adjust_napari_image_layer(
Expand Down Expand Up @@ -175,3 +177,80 @@
"brainglobe-atlasapi</a> or <a href='https://brainglobe.info/"
"tutorials/manage-atlases-in-GUI.html'>brainrender-napari</a>",
)


def filter_plane(img_plane):
"""
saarah815 marked this conversation as resolved.
Show resolved Hide resolved
Apply a set of filter to the plane (typically to avoid overfitting details
in the image during registration)
The filter is composed of a despeckle filter using opening and a pseudo
flatfield filter

Originally from: [https://github.com/brainglobe/brainreg/blob/main
/brainreg/core/utils/preprocess.py]

Parameters
----------
img_plane : np.array
A 2D array to filter

Returns
-------
np.array
Filtered image
"""

img_plane = despeckle_by_opening(img_plane)
img_plane = pseudo_flatfield(img_plane)
return img_plane

Check warning on line 205 in brainglobe_registration/utils/utils.py

View check run for this annotation

Codecov / codecov/patch

brainglobe_registration/utils/utils.py#L203-L205

Added lines #L203 - L205 were not covered by tests


def despeckle_by_opening(img_plane, radius=2):
"""
Despeckle the image plane using a grayscale opening operation

Originally from: [https://github.com/brainglobe/brainreg/blob/main
/brainreg/core/utils/preprocess.py]

Parameters
----------
img_plane : np.array
The image to filter

radius: int
The radius of the opening kernel

Returns
-------
np.array
The despeckled image
"""
kernel = morphology.disk(radius)
morphology.opening(img_plane, out=img_plane, footprint=kernel)
return img_plane

Check warning on line 230 in brainglobe_registration/utils/utils.py

View check run for this annotation

Codecov / codecov/patch

brainglobe_registration/utils/utils.py#L228-L230

Added lines #L228 - L230 were not covered by tests


def pseudo_flatfield(img_plane, sigma=5):
"""
Pseudo flat field filter implementation using a de-trending by a
heavily gaussian filtered copy of the image.

Originally from: [https://github.com/brainglobe/brainreg/blob/main
/brainreg/core/utils/preprocess.py]

Parameters
----------
img_plane : np.array
The image to filter

sigma : int
The sigma of the gaussian filter applied to the
image used for de-trending

Returns
-------
np.array
The pseudo flat field filtered image
"""
filtered_img = gaussian_filter(img_plane, sigma)
return img_plane / (filtered_img + 1)

Check warning on line 256 in brainglobe_registration/utils/utils.py

View check run for this annotation

Codecov / codecov/patch

brainglobe_registration/utils/utils.py#L255-L256

Added lines #L255 - L256 were not covered by tests
Loading