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)
This commit is contained in:
parent
4daf2bfe91
commit
f0a624fc2b
|
@ -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()
|
|
@ -41,7 +41,7 @@ def create_circle_image(image_size, circle_radius, circle_pos, circle_thickness,
|
||||||
dx = x - circle_pos_x
|
dx = x - circle_pos_x
|
||||||
dy = y - circle_pos_y
|
dy = y - circle_pos_y
|
||||||
r_square = (dx * dx + dy * dy)
|
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
|
pixel_value = circle_value
|
||||||
else:
|
else:
|
||||||
pixel_value = background_value
|
pixel_value = background_value
|
||||||
|
@ -86,11 +86,15 @@ class CircularSymmetryProjectorBase(IProjectorBase):
|
||||||
else:
|
else:
|
||||||
if oversampling_is_handled:
|
if oversampling_is_handled:
|
||||||
circle_image = oversampled_circle.resample(width=image_size, height=image_size)
|
circle_image = oversampled_circle.resample(width=image_size, height=image_size)
|
||||||
# mean_value = circle_image.get_mean_value()
|
mean_value = circle_image.get_mean_value()
|
||||||
# num_pixels = image_size * image_size
|
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"
|
||||||
# sum_of_pixel_values = mean_value * num_pixels
|
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
|
# 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'])}
|
anchor_point = {'x': int(circle_pos['x']), 'y': int(circle_pos['y'])}
|
||||||
return circle_image, anchor_point
|
return circle_image, anchor_point
|
||||||
|
@ -119,5 +123,5 @@ class CircularSymmetryDetector:
|
||||||
print(type(center_of_filter))
|
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']))
|
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))
|
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
|
return radial_profile_image
|
||||||
|
|
|
@ -108,7 +108,8 @@ class IJImage(IImage):
|
||||||
return image_stats.mean
|
return image_stats.mean
|
||||||
|
|
||||||
def scale_values(self, scale):
|
def scale_values(self, scale):
|
||||||
raise NotImplementedError()
|
processor = self.ij_image.getProcessor()
|
||||||
|
processor.multiply(scale)
|
||||||
|
|
||||||
|
|
||||||
class IJHyperStack(IHyperStack):
|
class IJHyperStack(IHyperStack):
|
||||||
|
|
Loading…
Reference in New Issue