Preprocessing images#
There are two main methods to preprocess images with Fluidimage:
with user-defined preprocessing functions or classes, or
with pre-defined preprocessing classes.
For both methods, we use a Work
class to try parameters and a Topology
class to apply this work in parallel on a large serie of images.
See the Overview of the package for an explanation about this terminology.
1. User-defined preprocessing#
Let’s assume that you have a function or a class which gets an image as argument and returns a new image. If it is importable, you can use Fluidimage to first investigate which are the better parameters for your case:
from fluidimage.image2image import Work
params = Work.create_default_params()
# for a function:
# params.im2im = 'fluidimage.image2image.im2im_func_example'
# for a class (with one argument for the function init):
params.im2im = "fluidimage.image2image.Im2ImExample"
params.args_init = ((1024, 2048), "clip")
params.images.path = "../../image_samples/Jet/Images/c*"
params.images.str_subset = "60:,:"
work = Work(params)
work.display()
and then process a large serie of images in parallel with the class
fluidimage.image2image.Topology
.
"""This example shows how to plug user-defined functions or classes that
process an image with a fluidimage topology (which process several images).
The user has to write an importable function (or class) processing one image
(see {mod}`fluidimage.image2image`).
Here, we use a class defined in fluidimage
(`fluidimage.image2image.Im2ImExample`), but it can be any
importable class!
"""
from fluidimage.image2image import Topology
params = Topology.create_default_params()
# for a function:
# params.im2im = 'fluidimage.image2image.im2im_func_example'
# for a class (with one argument for the function init):
params.im2im = "fluidimage.image2image.Im2ImExample"
params.args_init = ((1024, 2048), "clip")
params.images.path = "../../image_samples/Jet/Images/c*"
params.saving.postfix = "im2im_example"
params.saving.how = "recompute"
topo = Topology(params)
topo.compute()
assert len(topo.results) == 4
2. Pre-defined preprocessing classes#
Fluidimage also provides pre-defined preprocessing classes to apply many standard preprocessing to images.
Preprocessing one serie#
To find the good parameter, you can use the class
fluidimage.preproc.Work
(see also
fluidimage.preproc
).
from fluidimage.preproc import Work
params = Work.create_default_params()
params.series.path = "../../image_samples/Karman/Images"
print("Available preprocessing tools: ", params.tools.available_tools)
params.tools.sequence = ["sliding_median", "global_threshold"]
params.tools.sliding_median.enable = True
params.tools.sliding_median.window_size = 25
params.tools.global_threshold.enable = True
params.tools.global_threshold.minima = 0.0
params.tools.global_threshold.maxima = 255.0
preproc = Work(params)
preproc.display(1, hist=False)
Preprocessing large series of images#
To apply the preprocessing to a large serie of images in parallel, use
fluidimage.preproc.Topology
.
from fluidimage import get_path_image_samples
from fluidimage.preproc import Topology
params = Topology.create_default_params()
params.series.path = get_path_image_samples() / "Jet/Images"
params.series.str_subset = "i,:"
p_tools = params.tools
print("Available preprocessing tools: ", p_tools.available_tools)
p_tools.sequence = ["temporal_median", "sliding_median", "global_threshold"]
print("Enabled preprocessing tools: ", p_tools.sequence)
p_tools.sliding_median.enable = True
p_tools.sliding_median.weight = 0.5
p_tools.sliding_median.window_size = 10
p_tools.temporal_median.enable = False
p_tools.temporal_median.weight = 0.5
p_tools.temporal_median.window_shape = (5, 2, 2)
p_tools.global_threshold.enable = True
p_tools.global_threshold.minima = 0.0
params.saving.how = "recompute"
params.saving.postfix = "pre_example"
topology = Topology(params, logging_level="info", nb_max_workers=4)
# Compute in parallel
topology.compute()
# Compute in sequential (for debugging)
# topology.compute(sequential=True)
assert len(topology.results) == 2