Image Pipe¶
Pipeline building solution for 4D biological microscopy
Description:¶
This project is still in development. Initially started as a tool for Ruan, Zhou et al, Nature 2017, this pipeline has since grown to allow arbitrary pipeline construction based on a set of primitive functions and abstractions (pipe, tiling, per-segment processing, etc…).
This project is currently in alpha development, hence poorly documented, sparsely tested and prone to rapid changes.
Basic installation:
> pip install imagepipe
or:
> pip install git+https://github.com/chiffa/Image_pipe.git
The documentation is available on readthedocs.
Project is housed at GitHub. For any issues please refer to GitHub issue tracker.
Usage Guides:¶
Dev log:¶
This is a general library for image processing¶
Logic in the¶
Logic layers: 1. Traversal 2. Matching of the images to different channels 3. Segmentation of a. Mitochondria b. Cells 4. Retrieval of descriptors each surface/volume 5. Classification of a surface/volume a. with respect to the signal intensity => Cell death b. with respect to the geometry i. Area, skeleton, => fragmented mitochondria or not 6. Re-hashing of the file names in order to extract time-stamp 7. Perform time-line tracing and statistics calculation
DEBUG: output the graphical representation of what has been done by different cell
Desired code:¶
# Attach the debuger
set.debugger(dump_location = "./verification/", layers={"layer1":12, })
# point to the source folder
set.source_folder("xxxx")
# map a pattern in the name to a color channel
input.images = set.color_pattern({"_1465":"green", "_2660":"red"})
intermediate.cells = pipeline.step.add(segment.cells(input.images["green"], binary=True), debugger=layer1)
intermediate.cells = pipeline.step.add(remove outliers(intermediate.cells, "green"), debugger=layer2)
intermediate.cells = pipeline.step.add(remove outliers(intermediate.cells, "red"), debugger=layer2)
intermediate.granules = pipeline.step.add(segment.granules(intermediate.cells, "green"), debugger=layer3)
intermediate.mitochondriae = pipeline.step.add(segment.threshold(intermediate.cells, "red"), debugger=layer3)
colocalization = pipeline.step.add(colocalization.first_in_second(granules, mitochondriae), debugger=layer3)
anti_colocalization = pipeline.step.add(colocalization.first_in_second(granules, not(mitochondriae)), debugger=layer3)
pipeline.save.pattern(input.image.shorcode, colocalization, anti_colocalization)
save.location("final_table.csv")
pipeline.run()
Remarks:¶
In fact, we don’t really need an explicit pipeline class to assem ble the pipeline. We use intermediate variables within the user class in order `to stitch the pipeline and store the intermediate processes. We can as well plug the debug process to get the function debug output as it goes.
Unless we are using yield
statements, in which case the pipeline
would be performing processing ticks.
Idea - separate the namespaces that are logical in the context of the analysis
In order to avoid the generator once-consumed property, use multiple pass-through objects in dicts. That will also make it for an easy debugging in the end
Formalism:¶
Can we replace the in_channel, out_channel, log_channel with actual bindings to the variables? Right now, we are using an explicit dict for scope passing - could we rather use the function names?
What I am trying is basically to make flow control explicit by using an assembly-line model. The sort-coming is that I am using words, so I am using a lot Python interpreter errors and IDEs power.
A way around it is to hack the pipeline in the same manner as the guy who wrote hy (py-lisp)
Sub-segmentation¶
As of now, the mechanics of our method are operation only on the full image frames. If we want to segment the image for the analysis any further, for instance in order to perform cell-specific processing, would need to: - have a sencond generator wrapping / unwrapping routine - second-level dictionary store in the dict. Basically a
The second generator is basically a wrapper around the generator wrapper to execute the same instruction over a generator of generators, where the inner generator is processed by the generator wrapper logic, whereas the outer is processed by the second layer of wrapping
=> That’s basically a double generator_wrapper, but that cannot support the expected dims because a dict is being passed. => We actually just need the outer wrapper, the inner can be just the generator wrapper
Registering Run:¶
As of now, it is pretty trivial to get the current revision from git and the source/dump locations of all the elements. to get the replicability within the pipeline.
Possible usages:¶
- Assembly of generator-based sub-pipes
- Assembly of input-output chains and then wrapping them into pipe
Organization:¶
- Core functions => Non-wrapped, testable
- Pipeline logic => Generator-wrapped, ready for assembly; wrappers
- Pre-assembled filters
- It is all to be imported into the actual field and
From the usage¶
- we definitely need a pipeline assembly - it is too easy to forget the pipe redirections between the generators
- it is a bit frustrating to be unable to add elementary modifications to channels when they are injected
- protection against dims mismatch is good and saves some time
- the fact that stack trace returns nothing informative is definitely a minus
Reformulation¶
A pretty clear way of dealing with it is to re-write to get rid of the wrappers and reduce it all to a main for loop with embedded for sub-loops. Nitty-gritty details: - splitter needs to be a generator, returning values we want to use in the end - secondary namespace - point/tile/summarize
Audit:¶
- Word audit trail explaining what function does?
- Image binding into the final rendering frame?
API documentation:¶
imagepipe package¶
Subpackages¶
imagepipe.tools package¶
Submodules¶
imagepipe.tools.helpers module¶
-
exception
imagepipe.tools.helpers.
PipeArgError
¶ Bases:
exceptions.ValueError
-
imagepipe.tools.helpers.
list_not_string
(argument)¶ function that checks if a list is not a string
credits: http://stackoverflow.com/questions/1055360/how-to-tell-a-variable-is-iterable-but-not-a-string
Parameters: argument – Returns:
-
imagepipe.tools.helpers.
safe_dir_create
(path)¶
-
imagepipe.tools.helpers.
tiff_stack_2_np_arr
(tiff_location)¶ Loads the image from the tiff stack to a 3D numpy array
Parameters: tiff_location – Returns:
Module contents¶
Submodules¶
imagepipe.core_functions module¶
-
imagepipe.core_functions.
doublewrap
(f)¶ a decorator decorator, allowing the decorator to be used as: @decorator(with, arguments, and=kwargs) or @decorator
-
imagepipe.core_functions.
for_each
(outer_generator, embedded_transformer, inside, **kwargs)¶
-
imagepipe.core_functions.
generator_wrapper
(*args, **kwargs)¶
-
imagepipe.core_functions.
pad_skipping_iterator
(secondary_namespace)¶
-
imagepipe.core_functions.
paint_from_mask
(outer_generator, based_on, in_anchor, out_channel=None)¶
-
imagepipe.core_functions.
splitter
(outer_generator, to, sources, mask)¶ Creates a secondary namespace by using mask as a pad to conserve only certain segments in sources
Parameters: - outer_generator –
- to –
- sources –
- mask –
Returns:
-
imagepipe.core_functions.
tile_from_mask
(outer_generator, based_on, in_anchor, out_channel=None)¶
imagepipe.debug_renders module¶
imagepipe.density_plot module¶
-
imagepipe.density_plot.
better2D_desisty_plot
(xdat, ydat, thresh=3, bins=(100, 100))¶
imagepipe.iterate_and_check_img_files module¶
-
imagepipe.iterate_and_check_img_files.
iterate_and_check_img
(filename)¶
imagepipe.raw_functions module¶
This module contains raw function definitions that can be either used directly or wrapped and then assembled in pipelines
-
imagepipe.raw_functions.
agreeing_skeletons
(float_surface, mito_labels)¶ Calculates agreeing skeletonization by both median and morphological skeletons
Parameters: - float_surface – float volume on which we need to calculate the values
- mito_labels – labels that will be skeletonized
Returns:
-
imagepipe.raw_functions.
average_qualifying_value_per_region
(region_labels, image_2d, qualifying_mask)¶ Calculates average qualifying value per region of interest
Parameters: - region_labels –
- image_2d –
- qualifying_mask –
Returns: np.array list of average values, 2d pad of average values
-
imagepipe.raw_functions.
binarize_2d
(float_surface, cutoff_type='static', mcc_cutoff=None)¶ Performs a 2d binarization based on several possible methods
Parameters: - float_surface –
- cutoff_type – [‘otsu’, ‘local_otsu’, ‘static’, ‘log-otsu”]. Local Otsu is done with 5px mask
- mcc_cutoff – is cutoff_type is ‘static’, this will be the cutoff threshold
Returns: binary labels
-
imagepipe.raw_functions.
binarize_3d
(floats_volume, cutoff)¶ Performs a 3d binarization
Parameters: - floats_volume –
- cutoff –
Returns:
-
imagepipe.raw_functions.
classify_fragmentation_for_mitochondria
(label_mask, skeletons)¶ Performs mitochondria fragmentation based off the labels mask and skeletons mask
Parameters: - label_mask –
- skeletons –
Returns:
-
imagepipe.raw_functions.
clear_based_on_2d_mask
(stack, mask)¶ Sets to 0 in 3d everything covered by the mask along the z axis
Parameters: - stack – 3d image stack
- mask –
Returns:
-
imagepipe.raw_functions.
detect_upper_outliers
(value_list)¶ Performs upper outlier detection based on the extreme value distribution intuition. Works best with over 15 data elements
Parameters: value_list – Returns: positions of non-outliers, baseline curve of sorted averages, error margins
-
imagepipe.raw_functions.
exclude_region
(exclusion_mask, base_image, _dilation=5)¶ Excludes the region where exclusion_mask is true from the base image.
Parameters: - exclusion_mask –
- base_image –
- _dilation – if set to anything other than 0, would perform a morphological dilation using this parameter value as size on the exclusion mask
Returns:
-
imagepipe.raw_functions.
f_2d_stack_2d_filter
(_2d_stack, _2d_filter)¶ helper function to apply the 2d filter to a 2d image while creating an image copy
Parameters: - _2d_stack –
- _2d_filter –
Returns:
-
imagepipe.raw_functions.
f_3d_stack_2d_filter
(_3d_stack, _2d_filter)¶ helper function to apply 2d filter to a 3d image along the z axis
Parameters: - _3d_stack –
- _2d_filter –
Returns:
-
imagepipe.raw_functions.
filter_labels
(labels, binary_mask, min_feature_size=10)¶ Applies the binary mask to labels, than filters out all the labels with feature size less than min_feature_size
Parameters: - labels –
- binary_mask –
- min_feature_size –
Returns:
-
imagepipe.raw_functions.
gamma_stabilize
(image, alpha_clean=5, floor_method='min')¶ Normalizes the luma curve. floor intensity becomes 0 and max allowed by the bit number - 1
Parameters: - image –
- alpha_clean – size of features that would be removed if surrounded by a majority of
- floor_method – [‘min’, ‘1q’, ‘5p’, ‘median’] method of setting the floor intensity. 1q is first quartile, 1p is the first percentile
Returns:
-
imagepipe.raw_functions.
improved_watershed
(binary_base, intensity, expected_separation=10)¶ Improved watershed method that takes in account minimum intensity as well as minimal size of separation between the elements
Parameters: - binary_base – support for watershedding
- intensity – intensity value used to exclude watershed points with too low of intensity
- expected_separation – expected minimal separation (in pixels) between watershed centers
Returns:
-
imagepipe.raw_functions.
in_contact
(mask1, mask2, distance=10)¶ Finds if two binary masks are in contact or proximity. distance of detection is defined by the distance parameter
Parameters: - mask1 –
- mask2 –
- distance –
Returns: two arrays of the same shape as masks, each with ones for labels that overlap.
-
imagepipe.raw_functions.
label_and_correct
(binary_channel, value_channel, min_px_radius=3, min_intensity=0, mean_diff=10)¶ - Labelling of a binary image, with constraints on minimal feature size, minimal intensity of area
- covered by a binary label or minimal mean difference from background
Parameters: - binary_channel –
- value_channel – used to compute total intensity
- min_px_radius – minimal feature size
- min_intensity – minimal total intensity
- mean_diff – minimal (multiplicative) difference from the background
Returns:
-
imagepipe.raw_functions.
label_based_aq
(labels, field_of_interest)¶ Calculates average qualifying intensity of field of interest based on the labels mask
Parameters: - labels –
- field_of_interest –
Returns: list of averages, pad of averages
-
imagepipe.raw_functions.
locally_normalize
(channel, local_xy_pool=5, local_z_pool=2)¶ Performs a per- zslice local normalization of a 3d channel
Parameters: - channel –
- local_xy_pool – size of the neighborhood to be considered for normalization
- local_z_pool – placeholder, currently unused
Returns: normalized 3d channel
-
imagepipe.raw_functions.
mask_filter_2d
(base, _filter)¶ Applies a filter a base mask in 2d
Parameters: - base –
- _filter –
Returns:
-
imagepipe.raw_functions.
max_projection
(current_image)¶ Max projection along z axis
Parameters: current_image – Returns:
-
imagepipe.raw_functions.
otsu_tresholding
(shape_base)¶ perofrms an otsu thresholding based of the shape_base
Parameters: shape_base – Returns:
-
imagepipe.raw_functions.
paint_mask
(label_masks, labels_to_paint)¶ Paints a labeled mask based off a numpy list of values assigned to labels to paint.
Parameters: - label_masks –
- labels_to_paint – 1d numpy array with values that need to be painted on the labels.
Returns:
-
imagepipe.raw_functions.
qualifying_gfp
(max_sum_projection)¶ Creates a binary mask for qualifying gfp
Parameters: max_sum_projection – Returns: binary mask
-
imagepipe.raw_functions.
random_walker_binarize
(base_image, _dilation=0)¶ Improved random walker binarization based on the the scikits image library
Parameters: - base_image –
- _dilation – if set to anything other than 0, would perform a morphological dilation using this parameter value as size
Returns: binary labels
-
imagepipe.raw_functions.
robust_binarize
(base_image, _dilation=0, heterogeity_size=10, feature_size=50)¶ Robust binarization algorithm based off random walker clustering
Parameters: - base_image –
- _dilation – if set to anything other than 0, would perform a morphological dilation using this parameter value as size
- heterogeity_size – size of the feature (px) that the method will try to eliminate by smoothing
- feature_size – size of the feature (px) that the method will try to segment out
Returns: binary_labels
-
imagepipe.raw_functions.
smooth
(image, smoothing_px=1.5)¶ Gaussian smoothing of the image
Parameters: - image –
- smoothing_px –
Returns:
-
imagepipe.raw_functions.
smooth_2d
(image, smoothing_px=1.5)¶ Gaussian smoothing of a 2d image
Parameters: - image –
- smoothing_px –
Returns:
-
imagepipe.raw_functions.
split_and_trim
(path_prefix, main_root)¶ helper function for OS Path trimming routine that accounts for the trailing separator
Parameters: - path_prefix – [str]
- main_root – [str]
:return:[list]
-
imagepipe.raw_functions.
sum_projection
(image)¶ Sum projection along z axis
Parameters: image – Returns:
-
imagepipe.raw_functions.
volume_aqvi
(float_volume, binary_volume)¶ Calculates the average of the float volume after filtering it through the binary volume
Parameters: - float_volume –
- binary_volume –
Returns:
-
imagepipe.raw_functions.
volume_mqvi
(float_volume, binary_volume)¶ Calculates the median of the float volume after filtering it through the binary volume
Parameters: - float_volume –
- binary_volume –
Returns:
-
imagepipe.raw_functions.
voronoi_segment_labels
(binary_labels)¶ Performs a Voronoi segmentation on binary labels (assuming background is set to 0)
Parameters: binary_labels – Returns: pad with labels of segmentation of the same size as binary_labels
imagepipe.traversals module¶
-
imagepipe.traversals.
color_based_traversal
(main_root, coding_separator='.', group_anchor=1)¶ Traverses the main root directory pulling the data from the images. different layers are assumed to be different colors, images are assumed to be 2D.
Parameters: - main_root –
- coding_separator – character used to derived codename of the image
- group_anchor – position where the group information is stored
Returns:
-
imagepipe.traversals.
name_channels
(stack_group_generator, channel_names)¶ Assigns names to the channel for the future processing and bundles them together
Parameters: - stack_group_generator – generator returning image stack,
- channel_names –
Returns:
-
imagepipe.traversals.
z_stack_based_traversal
(main_root, matching_rule='c', matching_map=None)¶ Traverses the main_root directory, looking for all the ‘.tif/.TIF’ files, performs name matching then iterates through the resulting matched dictironary.
Matching assumption is that except for the matching keys, the names are identical
Parameters: - main_root – folder from which will be traversed in depth
- matching_rule – name modification to type mapping. Currently ‘’ for no matching, ‘color’ for colors
- matching_map – {‘pattern in the file name’: color channel number}
Returns:
imagepipe.wrapped_functions module¶
This module essentially wraps the functions to be compatible with the usage inside the pipelines