# 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()