started the abstraction of the image processing engine so that the lipase image processing can be executed without imagej if it's deemed to slow in the end.
This commit is contained in:
parent
b7b1f81fa7
commit
7994afd01a
|
@ -0,0 +1,61 @@
|
|||
"""An image engine implements image processing operators and an abstract image format.
|
||||
|
||||
Using these abstract classes allows the user to write image processing code that can run with various different image engines (eg imagej or opencv).
|
||||
"""
|
||||
|
||||
import abc
|
||||
|
||||
ABC = abc.ABCMeta('ABC', (object,), {})
|
||||
|
||||
|
||||
class IImage(ABC):
|
||||
|
||||
@abc.abstractmethod
|
||||
def width(self):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def height(self):
|
||||
pass
|
||||
|
||||
|
||||
class IImageEngine(ABC):
|
||||
"""
|
||||
The active image processor.
|
||||
|
||||
As there should only be one image engine instance at any given time, this class is implemented as a singleton
|
||||
"""
|
||||
|
||||
# Here will be the instance stored.
|
||||
__instance = None
|
||||
|
||||
@staticmethod
|
||||
def set_instance(image_engine):
|
||||
"""Change the active image_engine.
|
||||
|
||||
:param IImageEngine image_engine:
|
||||
"""
|
||||
IImageEngine.__instance = image_engine
|
||||
|
||||
@staticmethod
|
||||
def get_instance():
|
||||
"""Static access method."""
|
||||
assert IImageEngine.__instance is not None
|
||||
return IImageEngine.__instance
|
||||
|
||||
@abc.abstractmethod
|
||||
def save_as_tiff(self, image, out_file_path):
|
||||
"""
|
||||
:param IImage image:
|
||||
:param str out_file_path: eg './white_estimate.tiff'
|
||||
"""
|
||||
|
||||
|
||||
@abc.abstractmethod
|
||||
def compute_max(self, images_file_path):
|
||||
"""Compute for each pixel position the maximum at this position in all input images.
|
||||
|
||||
:param list(str) images_file_path:
|
||||
:rtype IImage:
|
||||
"""
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
"""Image processing using imagej.
|
||||
"""
|
||||
|
||||
from imageengine import IImage, IImageEngine
|
||||
from ij import IJ
|
||||
from ij.plugin import ImageCalculator
|
||||
|
||||
class IJImage(IImage):
|
||||
|
||||
def __init__(self, image_engine, ij_image):
|
||||
"""
|
||||
:param IJImageEngine image_engine:
|
||||
:param ImagePlus ij_image:
|
||||
"""
|
||||
self.image_engine = image_engine
|
||||
self.ij_image = ij_image
|
||||
|
||||
def width(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def height(self):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class IJImageEngine(IImageEngine):
|
||||
|
||||
def missing(self):
|
||||
pass
|
||||
|
||||
def save_as_tiff(self, image, out_file_path):
|
||||
IJ.saveAsTiff(image.ij_image, out_file_path)
|
||||
|
||||
def compute_max(self, images_file_path):
|
||||
"""Computes for each pixel position the maximum at this position in all input images.
|
||||
|
||||
:param list(str) images_file_path:
|
||||
:rtype IJmage:
|
||||
"""
|
||||
assert len(images_file_path) > 1
|
||||
max_image = IJ.openImage(images_file_path[0])
|
||||
print('max_image', max_image)
|
||||
|
||||
for image_file_path in images_file_path[2:-1]:
|
||||
other_image = IJ.openImage(image_file_path)
|
||||
print('other_image', other_image)
|
||||
ic = ImageCalculator()
|
||||
ic.run("max", max_image, other_image)
|
||||
print('max_image', max_image)
|
||||
return max_image
|
|
@ -3,7 +3,8 @@
|
|||
from ij import IJ
|
||||
from ij.plugin import ImageCalculator
|
||||
from catalog import ImageCatalog, Sequence
|
||||
|
||||
from imageengine import IImageEngine
|
||||
from imagej.ijimageengine import IJImageEngine, IJImage
|
||||
|
||||
def imagej_run_image_command(image, command, options):
|
||||
"""performs the given imagej command on the given image
|
||||
|
@ -21,23 +22,8 @@ def imagej_run_image_command(image, command, options):
|
|||
|
||||
|
||||
def compute_max(images_file_path):
|
||||
"""Computes for each pixel position the maximum at this position in all input images.
|
||||
|
||||
:param list(str) images_file_path:
|
||||
:rtype ImagePlus:
|
||||
"""
|
||||
assert len(images_file_path) > 1
|
||||
max_image = IJ.openImage(images_file_path[0])
|
||||
print('max_image', max_image)
|
||||
|
||||
for image_file_path in images_file_path[2:-1]:
|
||||
other_image = IJ.openImage(image_file_path)
|
||||
print('other_image', other_image)
|
||||
ic = ImageCalculator()
|
||||
ic.run("max", max_image, other_image)
|
||||
print('max_image', max_image)
|
||||
return max_image
|
||||
|
||||
image_engine = IJImageEngine()
|
||||
return image_engine.compute_max(images_file_path)
|
||||
|
||||
def replace_border(image, band_width):
|
||||
"""Overwrites the outer band of the image by duplicating the value of the pixels that touch this outer band
|
||||
|
@ -87,6 +73,10 @@ def perform_gray_morphology(image, operator, structuring_element_shape, structur
|
|||
class WhiteEstimator(object):
|
||||
|
||||
def __init__(self, open_size, close_size, average_size):
|
||||
"""
|
||||
:param int open_size: the diameter of the structuring element used to perform mathematical morphology's opening operator (in pixels)
|
||||
:param int close_size: the diameter of the structuring element used to perform mathematical morphology's closing operator (in pixels)
|
||||
"""
|
||||
self.open_size = open_size
|
||||
self.close_size = close_size
|
||||
self.average_size = average_size
|
||||
|
@ -238,8 +228,9 @@ class InteractiveWhiteEstimator(WhiteEstimator):
|
|||
def find_white_reference_image(white_estimate, white_z_stack):
|
||||
"""Find the white reference Image among a z stack of reference image the most correlated to the white image estimated from a serie of acquisition.
|
||||
|
||||
:param Image white_estimate:
|
||||
:param IImage white_estimate:
|
||||
:param Sequence white_z_stack:
|
||||
:param IImageEngine image_engine: the image processor to use
|
||||
% this function is specific of Telemos images (DISCO line SOLEIL)
|
||||
% acquired using micromanager software linked to imageJ
|
||||
|
||||
|
@ -333,14 +324,17 @@ def find_white_reference_image(white_estimate, white_z_stack):
|
|||
raise NotImplementedError()
|
||||
|
||||
|
||||
def test_preprocessing():
|
||||
def test_preprocessing(raw_images_root_path):
|
||||
"""Test preprocessing."""
|
||||
catalog = ImageCatalog('/Users/graffy/ownCloud/ipr/lipase/raw-images')
|
||||
IImageEngine.set_instance(IJImageEngine())
|
||||
catalog = ImageCatalog(raw_images_root_path)
|
||||
sequence = catalog.sequences['res_soleil2018/GGH/GGH_2018_cin2_phiG_I_327_vis_-40_1/Pos2']
|
||||
white_estimator = WhiteEstimator(open_size=75, close_size=75, average_size=75)
|
||||
white_estimator = WhiteEstimator(open_size=3, close_size=3, average_size=3)
|
||||
white_estimate = white_estimator.estimate_white([sequence], ['DM300_327-353_fluo'])
|
||||
find_white_reference_image(white_estimate, sequence.get_white())
|
||||
|
||||
# find_white_reference_image(white_estimate, sequence.get_white())
|
||||
print(white_estimate)
|
||||
IImageEngine.get_instance().save_as_tiff( IJImage( IImageEngine.get_instance(), white_estimate ), './white_estimate.tiff' )
|
||||
print('end')
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_preprocessing()
|
||||
|
|
|
@ -14,20 +14,13 @@ print('python version %s' % sys.version) # prints python version
|
|||
sys.path.append(lipase_src_root_path) # necessary if run from fiji as script otherwise jython fails to find lipase's modules such as catalog
|
||||
|
||||
from ij import IJ
|
||||
from lipase import Lipase, ImageLogger
|
||||
# from lipase import Lipase, ImageLogger
|
||||
from catalog import ImageCatalog
|
||||
from preprocessing import WhiteEstimator
|
||||
from preprocessing import test_preprocessing
|
||||
|
||||
def run_script():
|
||||
catalog = ImageCatalog(raw_images_root_path) # eg '/Users/graffy/ownCloud/ipr/lipase/raw-images'
|
||||
lipase = Lipase(catalog, debugger=ImageLogger())
|
||||
sequence = catalog.sequences['res_soleil2018/GGH/GGH_2018_cin2_phiG_I_327_vis_-40_1/Pos2']
|
||||
# white_estimator = WhiteEstimator(open_size=75, close_size=75, average_size=75)
|
||||
white_estimator = WhiteEstimator(open_size=3, close_size=3, average_size=3)
|
||||
white_estimate = white_estimator.estimate_white([sequence], ['DM300_327-353_fluo'])
|
||||
print(white_estimate)
|
||||
IJ.saveAsTiff(white_estimate, './white_estimate.tiff')
|
||||
print('end')
|
||||
test_preprocessing(raw_images_root_path) # eg '/Users/graffy/ownCloud/ipr/lipase/raw-images'
|
||||
|
||||
# note : when launched from fiji, __name__ doesn't have the value "__main__", as when launched from python
|
||||
run_script()
|
||||
|
|
Loading…
Reference in New Issue