imcflibs.imagej.shading
Functions to work on shading correction / model generation.
1"""Functions to work on shading correction / model generation.""" 2 3import os 4 5import ij # pylint: disable-msg=import-error 6 7from ..imagej import bioformats # pylint: disable-msg=no-name-in-module 8from ..imagej import misc, projections 9from ..log import LOG as log 10from ..pathtools import gen_name_from_orig, listdir_matching 11 12 13def apply_model(imps, model, merge=True): 14 """Apply a given shading model to a list of images / stacks. 15 16 The model is supposed to be a normalized 32-bit floating point 2D image that 17 will be used as a divisor to the slices of all ImagePlus objects given. 18 19 WARNING: the operation happens in-place, i.e. the original "imps" images 20 will be modified! 21 22 Parameters 23 ---------- 24 imps : list(ij.ImagePlus) 25 A list of ImagePlus objects (e.g. separate channels of a multi-channel 26 stack image) that should be corrected for shading artefacts. 27 model : ij.ImagePlus 28 A 2D image with 32-bit float values normalized to 1.0 (i.e. no pixels 29 with higher values) to be used for dividing the input images to correct 30 for shading. 31 merge : bool, optional 32 Whether or not to combine the resulting ImagePlus objects into a single 33 multi-channel stack (default=True). 34 35 Returns 36 ------- 37 ij.ImagePlus or list(ij.ImagePlus) 38 The merged ImagePlus with all channels, or the original list of stacks 39 with the shading-corrected image planes. 40 """ 41 log.debug("Applying shading correction...") 42 calc = ij.plugin.ImageCalculator() 43 for i, stack in enumerate(imps): 44 log.debug("Processing channel %i...", i) 45 calc.run("Divide stack", stack, model) 46 47 if not merge: 48 return imps 49 50 log.debug("Merging shading-corrected channels...") 51 merger = ij.plugin.RGBStackMerge() 52 merged_imp = merger.mergeChannels(imps, False) 53 return merged_imp 54 55 56def correct_and_project(filename, path, model, proj, fmt): 57 """Apply a shading correction to an image and create a projection. 58 59 In case the target file for the shading corrected image already exists, 60 nothing is done - neither the shading correction is re-created nor any 61 projections will be done (independent on whether the latter one already 62 exist or not). 63 64 Parameters 65 ---------- 66 filename : str 67 The full path to a multi-channel image stack. 68 path : str 69 The full path to a directory for storing the results. Will be created in 70 case it doesn't exist yet. Existing files will be overwritten. 71 model : ij.ImagePlus or None 72 A 32-bit floating point image to be used as the shading model. If model 73 is None, no shading correction will be applied. 74 proj : str 75 A string describing the projections to be created. Use 'None' for not 76 creating any projections, 'ALL' to do all supported ones. 77 fmt : str 78 The file format suffix to be used for the results and projections, e.g. 79 '.ics' for ICS2 etc. See the Bio-Formats specification for details. 80 81 Returns 82 ------- 83 (bool, bool) 84 A tuple of booleans indicating whether a shading correction has been 85 applied and whether projections were created. The latter depends on 86 both, the requested projections as well as the image type (e.g. it can 87 be False even if projections were requested, but the image) 88 """ 89 target = gen_name_from_orig(path, filename, "", fmt) 90 if os.path.exists(target): 91 log.info("Found shading corrected file, not re-creating: %s", target) 92 return False, False 93 94 if not os.path.exists(path): 95 os.makedirs(path) 96 97 imps = bioformats.import_image(filename, split_c=True) 98 ret_corr = False 99 if model is not None: 100 log.debug("Applying shading correction on [%s]...", filename) 101 imp = apply_model(imps, model) 102 bioformats.export_using_orig_name(imp, path, filename, "", fmt, True) 103 # imps needs to be updated with the new (=merged) stack: 104 imps = [imp] 105 ret_corr = True 106 107 if proj == "None": 108 projs = [] 109 elif proj == "ALL": 110 projs = ["Average", "Maximum"] 111 else: 112 projs = [proj] 113 for imp in imps: 114 ret_proj = projections.create_and_save(imp, projs, path, filename, fmt) 115 imp.close() 116 117 log.debug("Done processing [%s].", os.path.basename(filename)) 118 return ret_corr, ret_proj 119 120 121def process_folder(path, suffix, outpath, model_file, fmt): 122 """Run shading correction and projections on an entire folder. 123 124 Parameters 125 ---------- 126 path : str 127 The input folder to be scanned for images to be processed. 128 suffix : str 129 The file name suffix of the files to be processed. 130 outpath : str 131 The output folder where results will be stored. Existing files will be 132 overwritten. 133 model_file : str 134 The full path to a normalized 32-bit shading model image. If set to '-' 135 or 'NONE', no shading correction will be applied, i.e. only the 136 projection step will have an effect. 137 fmt : str 138 The file format suffix for storing the results. 139 """ 140 matching_files = listdir_matching(path, suffix, fullpath=True) 141 process_files(matching_files, outpath, model_file, fmt) 142 143 144def process_files(files, outpath, model_file, fmt): 145 """Run shading correction and projections on a list of files. 146 147 Parameters 148 ---------- 149 files : list(str) 150 The files to be processed, as a list of strings with the full path. 151 outpath : str 152 The output folder where results will be stored. Existing files will be 153 overwritten. 154 model_file : str 155 The full path to a normalized 32-bit shading model image. If set to '-' 156 or 'NONE', no shading correction will be applied, i.e. only the 157 projection step will have an effect. 158 fmt : str 159 The file format suffix for storing the results. 160 """ 161 log.info("Running shading correction and projections on %s files...", len(files)) 162 163 if model_file.upper() in ["-", "NONE"]: 164 model = None 165 else: 166 model = ij.IJ.openImage(model_file) 167 # the model needs to be shown, otherwise the IJ.run() call ignores it 168 try: 169 model.show() 170 canvas = model.getCanvas() 171 for _ in range(5): 172 # we have to show it, but we can make it smaller: 173 canvas.zoomOut(100, 100) 174 except AttributeError: 175 misc.error_exit("Opening shading model [%s] failed!" % model_file) 176 177 for in_file in files: 178 correct_and_project(in_file, outpath, model, "ALL", fmt) 179 180 if model: 181 model.close()
14def apply_model(imps, model, merge=True): 15 """Apply a given shading model to a list of images / stacks. 16 17 The model is supposed to be a normalized 32-bit floating point 2D image that 18 will be used as a divisor to the slices of all ImagePlus objects given. 19 20 WARNING: the operation happens in-place, i.e. the original "imps" images 21 will be modified! 22 23 Parameters 24 ---------- 25 imps : list(ij.ImagePlus) 26 A list of ImagePlus objects (e.g. separate channels of a multi-channel 27 stack image) that should be corrected for shading artefacts. 28 model : ij.ImagePlus 29 A 2D image with 32-bit float values normalized to 1.0 (i.e. no pixels 30 with higher values) to be used for dividing the input images to correct 31 for shading. 32 merge : bool, optional 33 Whether or not to combine the resulting ImagePlus objects into a single 34 multi-channel stack (default=True). 35 36 Returns 37 ------- 38 ij.ImagePlus or list(ij.ImagePlus) 39 The merged ImagePlus with all channels, or the original list of stacks 40 with the shading-corrected image planes. 41 """ 42 log.debug("Applying shading correction...") 43 calc = ij.plugin.ImageCalculator() 44 for i, stack in enumerate(imps): 45 log.debug("Processing channel %i...", i) 46 calc.run("Divide stack", stack, model) 47 48 if not merge: 49 return imps 50 51 log.debug("Merging shading-corrected channels...") 52 merger = ij.plugin.RGBStackMerge() 53 merged_imp = merger.mergeChannels(imps, False) 54 return merged_imp
Apply a given shading model to a list of images / stacks.
The model is supposed to be a normalized 32-bit floating point 2D image that will be used as a divisor to the slices of all ImagePlus objects given.
WARNING: the operation happens in-place, i.e. the original "imps" images will be modified!
Parameters
- imps (list(ij.ImagePlus)): A list of ImagePlus objects (e.g. separate channels of a multi-channel stack image) that should be corrected for shading artefacts.
- model (ij.ImagePlus): A 2D image with 32-bit float values normalized to 1.0 (i.e. no pixels with higher values) to be used for dividing the input images to correct for shading.
- merge (bool, optional): Whether or not to combine the resulting ImagePlus objects into a single multi-channel stack (default=True).
Returns
- ij.ImagePlus or list(ij.ImagePlus): The merged ImagePlus with all channels, or the original list of stacks with the shading-corrected image planes.
57def correct_and_project(filename, path, model, proj, fmt): 58 """Apply a shading correction to an image and create a projection. 59 60 In case the target file for the shading corrected image already exists, 61 nothing is done - neither the shading correction is re-created nor any 62 projections will be done (independent on whether the latter one already 63 exist or not). 64 65 Parameters 66 ---------- 67 filename : str 68 The full path to a multi-channel image stack. 69 path : str 70 The full path to a directory for storing the results. Will be created in 71 case it doesn't exist yet. Existing files will be overwritten. 72 model : ij.ImagePlus or None 73 A 32-bit floating point image to be used as the shading model. If model 74 is None, no shading correction will be applied. 75 proj : str 76 A string describing the projections to be created. Use 'None' for not 77 creating any projections, 'ALL' to do all supported ones. 78 fmt : str 79 The file format suffix to be used for the results and projections, e.g. 80 '.ics' for ICS2 etc. See the Bio-Formats specification for details. 81 82 Returns 83 ------- 84 (bool, bool) 85 A tuple of booleans indicating whether a shading correction has been 86 applied and whether projections were created. The latter depends on 87 both, the requested projections as well as the image type (e.g. it can 88 be False even if projections were requested, but the image) 89 """ 90 target = gen_name_from_orig(path, filename, "", fmt) 91 if os.path.exists(target): 92 log.info("Found shading corrected file, not re-creating: %s", target) 93 return False, False 94 95 if not os.path.exists(path): 96 os.makedirs(path) 97 98 imps = bioformats.import_image(filename, split_c=True) 99 ret_corr = False 100 if model is not None: 101 log.debug("Applying shading correction on [%s]...", filename) 102 imp = apply_model(imps, model) 103 bioformats.export_using_orig_name(imp, path, filename, "", fmt, True) 104 # imps needs to be updated with the new (=merged) stack: 105 imps = [imp] 106 ret_corr = True 107 108 if proj == "None": 109 projs = [] 110 elif proj == "ALL": 111 projs = ["Average", "Maximum"] 112 else: 113 projs = [proj] 114 for imp in imps: 115 ret_proj = projections.create_and_save(imp, projs, path, filename, fmt) 116 imp.close() 117 118 log.debug("Done processing [%s].", os.path.basename(filename)) 119 return ret_corr, ret_proj
Apply a shading correction to an image and create a projection.
In case the target file for the shading corrected image already exists, nothing is done - neither the shading correction is re-created nor any projections will be done (independent on whether the latter one already exist or not).
Parameters
- filename (str): The full path to a multi-channel image stack.
- path (str): The full path to a directory for storing the results. Will be created in case it doesn't exist yet. Existing files will be overwritten.
- model (ij.ImagePlus or None): A 32-bit floating point image to be used as the shading model. If model is None, no shading correction will be applied.
- proj (str): A string describing the projections to be created. Use 'None' for not creating any projections, 'ALL' to do all supported ones.
- fmt (str): The file format suffix to be used for the results and projections, e.g. '.ics' for ICS2 etc. See the Bio-Formats specification for details.
Returns
- (bool, bool): A tuple of booleans indicating whether a shading correction has been applied and whether projections were created. The latter depends on both, the requested projections as well as the image type (e.g. it can be False even if projections were requested, but the image)
122def process_folder(path, suffix, outpath, model_file, fmt): 123 """Run shading correction and projections on an entire folder. 124 125 Parameters 126 ---------- 127 path : str 128 The input folder to be scanned for images to be processed. 129 suffix : str 130 The file name suffix of the files to be processed. 131 outpath : str 132 The output folder where results will be stored. Existing files will be 133 overwritten. 134 model_file : str 135 The full path to a normalized 32-bit shading model image. If set to '-' 136 or 'NONE', no shading correction will be applied, i.e. only the 137 projection step will have an effect. 138 fmt : str 139 The file format suffix for storing the results. 140 """ 141 matching_files = listdir_matching(path, suffix, fullpath=True) 142 process_files(matching_files, outpath, model_file, fmt)
Run shading correction and projections on an entire folder.
Parameters
- path (str): The input folder to be scanned for images to be processed.
- suffix (str): The file name suffix of the files to be processed.
- outpath (str): The output folder where results will be stored. Existing files will be overwritten.
- model_file (str): The full path to a normalized 32-bit shading model image. If set to '-' or 'NONE', no shading correction will be applied, i.e. only the projection step will have an effect.
- fmt (str): The file format suffix for storing the results.
145def process_files(files, outpath, model_file, fmt): 146 """Run shading correction and projections on a list of files. 147 148 Parameters 149 ---------- 150 files : list(str) 151 The files to be processed, as a list of strings with the full path. 152 outpath : str 153 The output folder where results will be stored. Existing files will be 154 overwritten. 155 model_file : str 156 The full path to a normalized 32-bit shading model image. If set to '-' 157 or 'NONE', no shading correction will be applied, i.e. only the 158 projection step will have an effect. 159 fmt : str 160 The file format suffix for storing the results. 161 """ 162 log.info("Running shading correction and projections on %s files...", len(files)) 163 164 if model_file.upper() in ["-", "NONE"]: 165 model = None 166 else: 167 model = ij.IJ.openImage(model_file) 168 # the model needs to be shown, otherwise the IJ.run() call ignores it 169 try: 170 model.show() 171 canvas = model.getCanvas() 172 for _ in range(5): 173 # we have to show it, but we can make it smaller: 174 canvas.zoomOut(100, 100) 175 except AttributeError: 176 misc.error_exit("Opening shading model [%s] failed!" % model_file) 177 178 for in_file in files: 179 correct_and_project(in_file, outpath, model, "ALL", fmt) 180 181 if model: 182 model.close()
Run shading correction and projections on a list of files.
Parameters
- files (list(str)): The files to be processed, as a list of strings with the full path.
- outpath (str): The output folder where results will be stored. Existing files will be overwritten.
- model_file (str): The full path to a normalized 32-bit shading model image. If set to '-' or 'NONE', no shading correction will be applied, i.e. only the projection step will have an effect.
- fmt (str): The file format suffix for storing the results.