lipase/lipase.py

234 lines
9.1 KiB
Python
Raw Normal View History

# encoding: utf8
# A Jython script with parameters.
# It is the duty of the scripting framework to harvest
# the 'name' parameter from the user, and then display
# the 'greeting' output parameter, based on its type.
from ij import IJ # pylint: disable=import-error
from ij import ImagePlus # pylint: disable=import-error
from ij.process import ByteProcessor # pylint: disable=import-error
from ij.process import ImageStatistics
from ij.plugin import ImageCalculator
from ij.plugin import ZProjector
from ij import WindowManager
from catalog import Sequence, ImageCatalog
import preprocessing
# greeting = "Hello, " + name + "!"
# image prefix :
# AF
# blé : coupes de blé
# CA : coupe d'amande
# FE : feuille d'épinard
# GGH : globule gras humain
# CRF chloroplastes de feuille d'épinard
# OL : oléosome
# DARK : dark
# white :
#
# - cin1 : cinétique 1
# phiG_40x_1 : cinétique avant et après injection enzyme gastrique
# phiG_40x_Zstack20um_1 : stack
# 0mn : on commence à enregistrer et on attend 10mn (pour le bleaching) -> phiG_40x_1
# 10mn : debut injection phase gastrique (poussée)
# 13mn : la phase gastrique (le petit tuyau contient 20ul) arrive dans la cellule d'un coup (1 nanol)
# 15mn : on arrête l'injection
# 50mn : on fait un stack -> phiG_40x_Zstack20um_1
# 51mn : début d'injection phase intestinale (poussée) -> phiG_I_40x_1
# x mn : on arrête l'injection
# 90mn : on fait un stack -> phiG_I_40x_Zstack20um_1
# - cin2 : autre échantillon similaire à cin1
# - cond[5678] : condition non réalistes
class IImageProcessingDebugger(object):
def __init__(self):
pass
def on_image(self, image, image_id):
'''
:param ImagePlus image:
:param str image_id:
'''
pass
class NullDebugger(IImageProcessingDebugger):
def __init__(self):
IImageProcessingDebugger.__init__(self)
def on_image(self, image, image_id):
pass
class ImageLogger(IImageProcessingDebugger):
def __init__(self):
IImageProcessingDebugger.__init__(self)
def on_image(self, image, image_id):
# todo : WindowManager
image.show()
class Lipase(object):
def __init__(self, catalog, debugger=NullDebugger()):
'''
:param IImageProcessingDebugger im_proc_debugger:
'''
self.catalog = catalog
self.debugger = debugger
def get_image_median_value(self, src_image):
'''
:param ImagePlus src_image:
'''
# https://imagej.nih.gov/ij/developer/api/ij/process/ImageStatistics.html
stats = ImageStatistics.getStatistics(src_image.getProcessor(), ImageStatistics.MEDIAN, None)
# print(stats)
# print(stats.pixelCount)
return stats.median
def get_image_mean_value(self, src_image):
'''
:param ImagePlus src_image:
'''
# https://imagej.nih.gov/ij/developer/api/ij/process/ImageStatistics.html
stats = ImageStatistics.getStatistics(src_image.getProcessor(), ImageStatistics.MEAN, None)
# print(stats)
# print(stats.pixelCount)
return stats.mean
def test_get_image_median_value(self):
image_file_path = '/Users/graffy/ownCloud/ipr/lipase/raw-images/res_soleil2018/GGH/GGH_2018_cin2_phiG_I_327_vis_-40_1/Pos0/img_000000000_DM300_327-353_fluo_000.tif'
image = IJ.openImage(image_file_path)
median_value = self.get_image_median_value(image)
print('median value : %d' % median_value)
def find_depth_index(self, src_image, white_sequence):
''' finds in the image sequence white_sequence the image that correlates the best to src_image
:param ImagePlus src_image:
:param Sequence white_sequence:
'''
self.debugger.on_image(src_image, 'src_image')
white_sequence.open_in_imagej()
print('image type : ', src_image.getType())
src_median_value = self.get_image_median_value(src_image)
normalized_src_processor = src_image.getProcessor().convertToFloat()
normalized_src_processor.multiply(1.0 / src_median_value)
best_diff = None
best_z_index = None
for z_index in range(white_sequence.num_slices):
white_image_file_path = white_sequence.get_image_file_path(channel_index=0, frame_index=0, z_index=z_index)
white_image = IJ.openImage(white_image_file_path)
# self.debugger.on_image(white_image, 'white_image')
white_median_value = self.get_image_median_value(white_image)
# white_to_src_factor = 1.0 / float(white_median_value)
normalized_white_processor = white_image.getProcessor().convertToFloat()
normalized_white_processor.multiply(1.0 / float(white_median_value))
normalized_src = ImagePlus() # IJ.openImage("http://imagej.nih.gov/ij/images/boats.gif")
normalized_src.setProcessor(normalized_src_processor)
# print(imp1)
normalized_white = ImagePlus() # IJ.openImage("http://imagej.nih.gov/ij/images/bridge.gif")
normalized_white.setProcessor(normalized_white_processor)
# print(imp2)
ic = ImageCalculator()
difference_image = ic.run("sub create float", normalized_src, normalized_white)
# self.debugger.on_image(imp3, 'diff')
# self.debugger.on_image(normalized_white, 'normalized_white')
# self.debugger.on_image(difference_image, 'difference_image')
# imp2mat = ImagePlusMatConverter()
# white_mat = imp2mat.toMat(white_image.getProcessor())
# white_mat = imread(white_image_file_path)
# print(white_image)
sqdiff_image = ic.run("mul create float", difference_image, difference_image)
mean_sqdiff = self.get_image_mean_value(sqdiff_image)
print('difference : ', mean_sqdiff)
if best_diff is None or mean_sqdiff < best_diff:
best_diff = mean_sqdiff
best_z_index = z_index
return best_z_index
def compute_sequence_median_image(self, sequence, channel_id='DM300_nofilter_vis'):
''' computes for each pixel its median value along time, so that in the end we have a single image that only shows structures (things that don't move such as the traps)
:param Sequence sequence:
:param str channel_id:
'''
stack = sequence.as_stack(channel_id)
projector = ZProjector()
median_image = projector.run(stack, 'median')
# pixel_value_along_time = ByteProcessor.createProcessor(stack.getDepth(), 1)
return median_image
def extract_background(self, sequence):
channel_id = 'DM300_nofilter_vis'
sequence.as_stack(channel_id).show()
background_image = self.compute_sequence_median_image(sequence, channel_id)
background_image.show()
return background_image
def estimate_white(self, sequence, channel_id):
return preprocessing.estimate_white([sequence], [channel_id], dark=None)
def process_sequence(self, sequence_id):
'''
:param str sequence_id:
'''
raise NotImplementedError()
def test_find_white():
raw_images_root = '/Users/graffy/ownCloud/ipr/lipase/raw-images'
catalog = ImageCatalog(raw_images_root)
print(catalog)
# catalog.sequences['GGH_2018_cin2_phiG_I_327_vis_-40_1/Pos0'].open_in_imagej()
# catalog.sequences['res_soleil2018/GGH/GGH_2018_cin2_phiG_I_327_vis_-40_1/Pos2'].open_in_imagej()
# catalog.sequences['DARK_40X_60min_1 im pae min_1/Pos0'].open_in_imagej()
# catalog.sequences['white_24112018_1/Pos0'].open_in_imagej()
lipase = Lipase(catalog, debugger=ImageLogger())
sequence = lipase.catalog.sequences['res_soleil2018/GGH/GGH_2018_cin2_phiG_I_327_vis_-40_1/Pos2']
white_seq = sequence.get_white()
channel_index = sequence.get_channel_index('DM300_327-353_fluo')
src_image_file_path = sequence.get_image_file_path(channel_index=channel_index, frame_index=0, z_index=0)
src_image = IJ.openImage(src_image_file_path)
# src_image = IJ.openImage(src_image_file_path)
depth_index = lipase.find_depth_index(src_image, white_seq)
def run_script():
test_find_white()
if False:
lipase = Lipase(ImageCatalog('/Users/graffy/ownCloud/ipr/lipase/raw-images'), debugger=ImageLogger())
lipase.process_sequence('res_soleil2018/GGH/GGH_2018_cin2_phiG_I_327_vis_-40_1/Pos2')
if False:
sequence = lipase.catalog.sequences['GGH_2018_cin2_phiG_I_327_vis_-40_1/Pos0']
src_image_file_path = sequence.get_image_file_path(channel_index=sequence.get_channel_index('DM300_327-353_fluo'), frame_index=3)
src_image = IJ.openImage(src_image_file_path) # pylint: disable=unused-variable
# dark_image = IJ.openImage(raw_images_root + '/GGH_2018_cin2_phiG_I_327_vis_-40_1/Pos0/img_000000000_DM300_327-353_fluo_000.tif')
# src_image.show()
# assert src_image
# If a Jython script is run, the variable __name__ contains the string '__main__'.
# If a script is loaded as module, __name__ has a different value.
if __name__ in ['__builtin__', '__main__']:
run_script()
# test_get_image_median_value()