Processing
ImageDev processing features allow the application of computational algorithms on data extracted from images.
- Image Manipulation: This category contains algorithms for creating and editing images.
- Geometry And Matching: This category provides algorithms for performing geometrical transformations and detecting predefined patterns.
- Arithmetic And Logic: This category contains algorithms that perform classic mathematical pointwise operations.
- Image Filtering: This category gathers filtering algorithms (for example, for denoising an image or enhancing its contrast).
- Edge Detection: This category contains algorithms for extracting image edges.
- Image Segmentation: This category contains algorithms that isolate relevant information from an image into a binary or label image.
- Mathematical Morphology: This category introduces a theory for the analysis of geometrical structures.
- Image Analysis: The purpose of quantitative analysis is to extract new representations in the form of measurements from images.
- IO: This category describes helper functions used to load and save data objects used by ImageDev that do not have serialization methods. Most of these objects are part of the IOLink library.
ImageDev contains different types of algorithms:
Each algorithm documentation exposes two code snippets illustrating the use of both modes.
The result can be obtained either as a returned value, or as the last parameter(s) of the function prototype. This mode is simpler to use for algorithms with few parameters and, in some ways, in languages where parameters can be omitted, like in Python. This mode saves memory by reusing already allocated data which can be, for eligible algorithms, the input data (in situ processing).
With function mode, outputs are returned by the function. When an algorithm generates several outputs:
This mode is simpler to use for algorithms with many parameters, when most of parameters have to keep their default value.
With class mode, a parameter can be:
By convention:
To access an image stored on disk without loading the whole data set into memory, the "ioformat::openView" function should be used rather than the "ioformat::readImage" function.
To create temporary images on disk, the "iolink::ImageViewFactory::allocateOnDisk" function should be used. The associated file is automatically deleted when the image is no longer used.
The following example illustrates the use of disk images.
- Algorithms working on images and providing output images (processing filters).
- Algorithms providing numerical results (analysis algorithms).
- Algorithms working on vector data that represent segments of object edges (polygonal approximation).
- Algorithms working only on 2D images.
- Algorithms working only on 3D images.
- Algorithms working on both 2D and 3D images.
Class and Function programming modes
ImageDev provides two modes for invoking an image processing algorithm: a class and a function programming mode.Each algorithm documentation exposes two code snippets illustrating the use of both modes.
Function mode
In Function programming mode, the algorithm is directly launched when calling the function.The result can be obtained either as a returned value, or as the last parameter(s) of the function prototype. This mode is simpler to use for algorithms with few parameters and, in some ways, in languages where parameters can be omitted, like in Python. This mode saves memory by reusing already allocated data which can be, for eligible algorithms, the input data (in situ processing).
With function mode, outputs are returned by the function. When an algorithm generates several outputs:
- A specific structure is returned in C++ and C#.
- A tuple is returned in Python.
Class mode
In Class programming mode, the algorithm is instantiated as a class object and is launched when calling its execute() method.This mode is simpler to use for algorithms with many parameters, when most of parameters have to keep their default value.
With class mode, a parameter can be:
- Written in C++ as argument of a method named with the set prefix in front of the parameter name
- Written in C# and Python by assigning it to a property named with the parameter name (no set prefix)
- Read as returned value of a method or property named with the parameter name (no get prefix)
Naming conventions
Capitalization Rules
For a given type of identifier, ImageDev uses the recommended case in each language. $$ \begin{array}{|l|l|l|l|} \hline \textbf{Type of Identifier} & \textbf{C++ Case} & \textbf{Python Case} & \textbf{C# Case}\\ \hline \textbf{Class} & \mbox{PascalCase} & \mbox{PascalCase} & \mbox{PascalCase}\\ \hline \textbf{Function} & \mbox{camelCase} & \mbox{snake_case} & \mbox{PascalCase}\\ \hline \textbf{Class method} & \mbox{camelCase} & \mbox{snake_case} & \mbox{PascalCase}\\ \hline \textbf{Argument} & \mbox{camelCase} & \mbox{snake_case} & \mbox{camelCase}\\ \hline \textbf{Enumerate Type} & \mbox{PascalCase} & \mbox{PascalCase} & \mbox{PascalCase}\\ \hline \textbf{Enumerate Value} & \mbox{SCREAMING_SNAKE_CASE} & \mbox{SCREAMING_SNAKE_CASE} & \mbox{SCREAMING_SNAKE_CASE}\\ \hline \end{array} $$Dimensional compatibility
ImageDev algorithm names may end with 2d or 3d:- 2d indicates that an algorithm is dedicated to deal with 2D images.
- 3d indicates that an algorithm is dedicated to deal with 3D images.
- If this information is omitted, the algorithm works on both types of images.
Parameter naming
Input and output data
An algorithm parameter (a function argument or a class member) can be:- An input data object (generally an image)
- An output data object
- A computation setting
- A parameter name beginning with input represents an input data object.
- A parameter name beginning with output represents an output data object.
- A parameter name beginning neither with input , nor output represents a computation setting.
- Exception: the outputDataType parameter, available in several ImageDev algorithms, is an enumerated value that represents the type to assign to the output data.
- A parameter name containing Image represents an image (an ImageView object).
- A parameter name containing Analysis represents a result of analysis; that is, a list of measurements for a set of objects(AnalysisMeasurement object).
- A parameter name containing Segment represents a chain of segments; that is, a list of vertices obtained from a polygonal approximation of objects edges.
- A parameter named outputMeasurement represents a result object specific to the algorithm. It generally represents the measurement results of a global analysis of an image (for example, Area2d::outputMeasurement ).
Kernel size parameters
In many ImageDev processing filters, a parameter represents the size of a moving window applied on the input image to compute the output image. Generally, this window is a square in 2D and a cube in 3D which must have an odd side length in pixels, but, in some cases, it also can be a disk or a ball.By convention:
- A parameter name beginning with kernelSize represents a full size of a window side length. Some algorithms may raise an exception when this parameter is set to an even value (for example, BilateralFilter2d::kernelSizeX ).
- A parameter name beginning with kernelRadius represents a half size of a window side length or a radius for disk and ball kernels (for example, MedianFilter2d::kernelRadius ).
Disk processing
ImageDev disk processing features allow the application of computational algorithms on data stored on disk.To access an image stored on disk without loading the whole data set into memory, the "ioformat::openView" function should be used rather than the "ioformat::readImage" function.
To create temporary images on disk, the "iolink::ImageViewFactory::allocateOnDisk" function should be used. The associated file is automatically deleted when the image is no longer used.
The following example illustrates the use of disk images.
Example
// ImageDev library initialization imagedev::init(); // Open a tif file auto viewInput = ioformat::openView( std::string( IMAGEDEVDATA_IMAGES_FOLDER ) + "hello_imagedev.tif" ); auto imageInput = iolink::ImageViewProvider::toImage( viewInput ); // Create the temporary image to store the result of the normalization auto imageNorm = iolink::ImageViewFactory::allocateOnDisk( "tmp_norm.raw", { 1, 1 }, iolink::DataTypeId::UINT8 ); // Apply a normalization of its graylevels using function coding style imagedev::rescaleIntensity( imageInput, imagedev::RescaleIntensity::OutputType::SAME_AS_INPUT, imagedev::RescaleIntensity::RangeMode::PERCENTILE, { 2, 98 }, { 0, 255 }, { 0, 255 }, imageNorm ); // Create the temporary image to store the result of the median filter auto imageMedian = iolink::ImageViewFactory::allocateOnDisk( "tmp_median.raw", { 1, 1 }, iolink::DataTypeId::UINT8 ); // Apply a median filter processing using class coding style { imagedev::MedianFilter2d processMedian; processMedian.setInputImage( imageNorm ); processMedian.setKernelMode( imagedev::MedianFilter2d::KernelMode::DISK ); processMedian.setKernelRadius( 1 ); processMedian.setOutputImage( imageMedian ); processMedian.execute(); } // Force the free of the temporary image; The temporary file will be deleted. // Without it, the temporary image will be freed when it will be no longer used (at the end of the scope). imageNorm.reset(); // Export the resulting image as a png file ioformat::writeView( iolink::ImageViewProvider::toRead( imageMedian ), "hello_imagedev_output.png" ); // Free the temporary image; The temporary file will be deleted. imageMedian.reset(); // ImageDev library finalization imagedev::finish();
import imagedev as id import imagedev_data import ioformat import iolink # ImageDev library initialization id.init() # Open and display a tif file image_input = ioformat.open_view(imagedev_data.get_image_path("hello_imagedev.tif")) # Create the temporary image to store the result of the normalization image_norm = iolink.ImageViewFactory.allocate_on_disk("tmp_norm.raw", iolink.VectorXu64(1, 1), iolink.DataTypeId_UINT8, None, None) # Apply a normalization of its graylevels using function coding style image_norm = id.rescale_intensity(image_input, range_mode=id.RescaleIntensity.RangeMode.PERCENTILE, output_image=image_norm) # Create the temporary image to store the result of the median filter image_median = iolink.ImageViewFactory.allocate_on_disk("tmp_median.raw", iolink.VectorXu64(1, 1), iolink.DataTypeId_UINT8, None, None) # Apply a median filter processing using class coding style process_median = id.MedianFilter2d() process_median.input_image = image_norm process_median.kernel_mode = id.MedianFilter2d.KernelMode.DISK process_median.kernel_radius = 1 process_median.output_image = image_median process_median.execute() # Force the free of the processing class; This removes the links between the class and the input and output images. process_median = None # Force the free of the temporary image; The temporary file will be deleted. # Without it, the temporary image will be freed when it will be no longer used (at the end of the scope). image_norm = None # Export the resulting image as a png file ioformat.write_view(image_median, "hello_imagedev_output.png") # Free the temporary image; The temporary file will be deleted. image_median = None # ImageDev library finalization id.finish()
// ImageDev library initialization Initialization.Init(); // Open a tif file View viewInput = IOFormat.ViewIO.OpenView(@"Data/images/hello_imagedev.tif"); ImageView imageInput = IOLink.ImageViewProvider.ToImage(viewInput); // Create the temporary image to store the result of the normalization ReadImageView imageNorm = IOLink.ImageViewFactory.AllocateOnDisk(@"Data/images/tmp_norm.raw", new VectorXu64(1, 1), IOLink.DataTypeId.UINT8); // Apply a normalization of its graylevels using function coding style Processing.RescaleIntensity(imageInput, RescaleIntensity.OutputType.SAME_AS_INPUT, RescaleIntensity.RangeMode.PERCENTILE, new double[] { 2, 98 }, new double[] { 0, 255 }, new double[] { 10, 228 }, imageNorm); // Create the temporary image to store the result of the median filter ReadImageView imageMedian = IOLink.ImageViewFactory.AllocateOnDisk(@"Data/images/tmp_median.raw", new VectorXu64(1, 1), IOLink.DataTypeId.UINT8); // Apply a median filter processing using class coding style MedianFilter2d processMedian = new MedianFilter2d { inputImage = imageNorm, kernelMode = MedianFilter2d.KernelMode.DISK, kernelRadius = 1, outputImage = imageMedian }; processMedian.Execute(); // Notify the garbage collector that the class can be freed and remove links with input and output images. processMedian.Dispose(); // Notify the garbage collector that the intermediate image can be freed // The temporary file will be deleted imageNorm.Dispose(); // Export the resulting image as a png file IOFormat.ViewIO.WriteView(imageMedian, @"Data/images/hello_imagedev_output.png"); // Notify the garbage collector that the intermediate image can be freed // The temporary file will be deleted imageMedian.Dispose(); // ImageDev library finalization Initialization.Finish();