"""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 def imagej_run_image_command(image, command, options): """performs the given imagej command on the given image :param ImagePlus image: :param str command: imagej command (eg "Gray Morphology") :param str options: imagej options (eg "radius=1 type=square operator=open") wrapper around IJ.run (https://imagej.nih.gov/ij/developer/api/ij/IJ.html#run-ij.ImagePlus-java.lang.String-java.lang.String-) which raises an exception on error """ IJ.run(image, command, options) error_message = IJ.getErrorMessage() if error_message is not None: raise Exception('The command "%s" with options "%s" failed because of the following error : %s' % (command, options, error_message)) 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 IJImage: """ 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 IJImage(self, max_image) def perform_gray_morphology(self, image, operator, structuring_element_shape, structuring_element_radius): """ :param IJImage image: :param str operator: eg 'open' :param str structuring_element_shape: eg 'square' :param int structuring_element_radius: """ assert operator not in ['fast open', 'fast erode'], "as of 13/09/2019, fast operators such as 'fast erode' seem broken in fiji (the resulting image is not at all similar to their slow equivalent)" processor = image.ij_image.getProcessor() convert_to_byte = False if processor.getBitDepth() != 8: convert_to_byte = True min_value = processor.getMin() max_value = processor.getMax() print("warning: downgrading image to byte as imagej's Gray Morphology processing doesn't handle 16bit images (range=[%d, %d])" % (min_value, max_value)) do_scaling = True image.ij_image.setProcessor(processor.convertToByte(do_scaling)) print("before gray morphology") assert structuring_element_radius < 11, "the radius of the structuring element is too big (%d); using it with Fiji's 'Gray Morphology' tool would result in very long computations." % structuring_element_radius imagej_run_image_command(image.ij_image, "Gray Morphology", "radius=%d type=%s operator=%s" % (structuring_element_radius, structuring_element_shape, operator)) print("after gray morphology") def replace_border(self, image, band_width): raise NotImplementedError() return image