From f0a624fc2b1898d5e305078c345bfc52fc95d839 Mon Sep 17 00:00:00 2001 From: Guillaume Raffy Date: Mon, 6 Apr 2020 18:49:29 +0200 Subject: [PATCH] more work related to graffy/lipase#3 - the user can now use radial profile image processing through a new plugin (Radial Profile) - improved the computation of the radial profile : the profile is now normalised (no longer bigger weights for big circles) --- src/ij-plugins/Ipr/Lipase/Radial_Profile.py | 41 +++++++++++++++++++++ src/lipase/circsymdetector.py | 16 +++++--- src/lipase/imagej/ijimageengine.py | 3 +- 3 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 src/ij-plugins/Ipr/Lipase/Radial_Profile.py diff --git a/src/ij-plugins/Ipr/Lipase/Radial_Profile.py b/src/ij-plugins/Ipr/Lipase/Radial_Profile.py new file mode 100644 index 0000000..20fb184 --- /dev/null +++ b/src/ij-plugins/Ipr/Lipase/Radial_Profile.py @@ -0,0 +1,41 @@ +#@ ImagePlus (label="the input image") INPUT_IMAGE +#@ Float (label="maximal radius", value=10.0, min=0.0, max=100.0, style="slider") MAX_RADIUS + +#@output ImagePlus RADIAL_PROFILE +"""This script is supposed to be launched from fiji's jython interpreter + +This imagej plugin computes the radial profile of each pixel of the input image. The resulting profiles are stored in a single hyperstack, where the profile data are stored along the channel axis +""" + +# # note: fiji's jython doesn't support encoding keyword + +import sys +print('python version %s' % sys.version) # prints python version + +from lipase.settings import UserSettings + +from lipase.imageengine import IImageEngine, PixelType +from lipase.imagej.ijimageengine import IJImageEngine +from lipase.circsymdetector import CircularSymmetryDetector + +import ij.gui # pylint: disable=import-error +from jarray import zeros, array # pylint: disable=import-error + +def run_script(): + global INPUT_IMAGE # pylint:disable=global-variable-not-assigned + global MAX_RADIUS # pylint:disable=global-variable-not-assigned + global RADIAL_PROFILE # pylint:disable=global-variable-not-assigned + + IImageEngine.set_instance(IJImageEngine()) + + src_image = IImageEngine.get_instance().create_image(width=1, height=1, pixel_type=PixelType.U8) + src_image.ij_image = INPUT_IMAGE # pylint: disable=undefined-variable + + detector = CircularSymmetryDetector(max_radius=MAX_RADIUS) # pylint: disable=undefined-variable + radial_profiles = detector.compute_radial_profiles(src_image) + + RADIAL_PROFILE = radial_profiles.hyperstack + + +# note : when launched from fiji, __name__ doesn't have the value "__main__", as when launched from python +run_script() diff --git a/src/lipase/circsymdetector.py b/src/lipase/circsymdetector.py index ab34ed4..89e1a1a 100644 --- a/src/lipase/circsymdetector.py +++ b/src/lipase/circsymdetector.py @@ -41,7 +41,7 @@ def create_circle_image(image_size, circle_radius, circle_pos, circle_thickness, dx = x - circle_pos_x dy = y - circle_pos_y r_square = (dx * dx + dy * dy) - if r_min_square < r_square < r_max_square: + if r_min_square - 0.001 <= r_square < r_max_square: pixel_value = circle_value else: pixel_value = background_value @@ -86,11 +86,15 @@ class CircularSymmetryProjectorBase(IProjectorBase): else: if oversampling_is_handled: circle_image = oversampled_circle.resample(width=image_size, height=image_size) - # mean_value = circle_image.get_mean_value() - # num_pixels = image_size * image_size - # sum_of_pixel_values = mean_value * num_pixels + mean_value = circle_image.get_mean_value() + assert mean_value > 0.0, "unexpected mean value of this circle image : this circle might be empty, or worse, have negative values, which doesn't make sense" + print(type(mean_value)) + num_pixels = image_size * image_size + sum_of_pixel_values = mean_value * num_pixels # we want each circle to have a total weight of 1.0, regardless their radius - # circle_image.scale_values(1.0/sum_of_pixel_values) + circle_image.scale_values(1.0/sum_of_pixel_values) + + anchor_point = {'x': int(circle_pos['x']), 'y': int(circle_pos['y'])} return circle_image, anchor_point @@ -119,5 +123,5 @@ class CircularSymmetryDetector: print(type(center_of_filter)) projection = ie.filter2D(src_image, dst_type=PixelType.F32, kernel=projector, anchor=(center_of_filter['x'], center_of_filter['y'])) ie.debugger.on_image(projection, 'projection_%d' % (projector_index)) - radial_profile_image.set_image(self, projection, frame_index=0, slice_index=0, channel_index=projector_index) + radial_profile_image.set_image(projection, frame_index=0, slice_index=0, channel_index=projector_index) return radial_profile_image diff --git a/src/lipase/imagej/ijimageengine.py b/src/lipase/imagej/ijimageengine.py index 2d10acc..4ca73af 100644 --- a/src/lipase/imagej/ijimageengine.py +++ b/src/lipase/imagej/ijimageengine.py @@ -108,7 +108,8 @@ class IJImage(IImage): return image_stats.mean def scale_values(self, scale): - raise NotImplementedError() + processor = self.ij_image.getProcessor() + processor.multiply(scale) class IJHyperStack(IHyperStack):