ImageDev

SeparateObjects

Separates connected objects in a binary image.

Access to parameter description

For an introduction: This algorithm is based on the watershed algorithm to extract the lines separating objects of a binary image. These lines are used as boundary lines between overlapping particles.

This algorithm is a high-level combination of distance transform, numerical reconstruction, and watershed algorithms.
A contrast level parameter is used to reduce the number of markers for the watershed process and thus of false positive separation lines.
There is a limitation to the separation ability: if some particles overlap too much, they are not separated by the algorithm. A sensible criteria is that the distance between particle centroids should be larger than their greatest radius.

Note: This algorithm requires up to 10 times the size of the input image as free memory. If the system does not have enough free memory, this algorithm will fail during its computation. In this case, the SeparateObjectsByBlock should be used instead.

See also
See related example

Function Syntax

This function returns outputImage.
// Function prototype
std::shared_ptr< iolink::ImageView > separateObjects( std::shared_ptr< iolink::ImageView > inputBinaryImage, int32_t contrastValue, SeparateObjects::OutputType outputType, SeparateObjects::AlgorithmMode algorithmMode, SeparateObjects::Neighborhood neighborhood, std::shared_ptr< iolink::ImageView > outputImage = NULL );
This function returns outputImage.
// Function prototype.
separate_objects( input_binary_image,
                  contrast_value = 2,
                  output_type = SeparateObjects.OutputType.SEPARATED_OBJECTS,
                  algorithm_mode = SeparateObjects.AlgorithmMode.REPEATABLE,
                  neighborhood = SeparateObjects.Neighborhood.CONNECTIVITY_26,
                  output_image = None )
This function returns outputImage.
// Function prototype.
public static IOLink.ImageView
SeparateObjects( IOLink.ImageView inputBinaryImage,
                 Int32 contrastValue = 2,
                 SeparateObjects.OutputType outputType = ImageDev.SeparateObjects.OutputType.SEPARATED_OBJECTS,
                 SeparateObjects.AlgorithmMode algorithmMode = ImageDev.SeparateObjects.AlgorithmMode.REPEATABLE,
                 SeparateObjects.Neighborhood neighborhood = ImageDev.SeparateObjects.Neighborhood.CONNECTIVITY_26,
                 IOLink.ImageView outputImage = null );

Class Syntax

Parameters

Class Name SeparateObjects

Parameter Name Description Type Supported Values Default Value
input
inputBinaryImage
The input binary image. Image Binary nullptr
input
outputType
The type of result image.
SEPARATED_OBJECTS The result image is a binary image representing the original data minus separation lines (split particles).
WATERSHED_RIDGES The result image is a binary image representing the separation lines (watershed).
SEPARATED_BASINS The result image is a label image representing the catchment areas (labeled complement of the watershed).
CONTIGUOUS_BASINS The result image is a label image representing the catchment areas with separation lines filled by a label.
CONTIGUOUS_OBJECTS The result image is a label image representing the original image with labels taking into account the watershed.
Enumeration SEPARATED_OBJECTS
input
algorithmMode
The mode for applying the watershed algorithm.
REPEATABLE The result is repeatable but slower to compute.
FAST The result is faster to compute but not repeatable because of asynchronous parallel computation. Since a watershed problem does not generally have a unique solution, two processings of the same image can lead to two different results (both exact).
Enumeration REPEATABLE
input
contrastValue
The depth of the valley used to select the markers of the watershed. Int32 >=0 2
input
neighborhood
The 3D neighborhood configuration. This parameter is ignored with a 2D input image.
CONNECTIVITY_6 The structuring element is composed of voxels with a common face with the voxel of interest.
CONNECTIVITY_18 The structuring element is composed of voxels with at least one common edge.
CONNECTIVITY_26 The structuring element is a full cube.
Enumeration CONNECTIVITY_26
output
outputImage
The output binary or label image. Its dimensions are forced to the same values as the input image. Its type depends on the outputType parameter. Image nullptr

Object Examples

auto foam_sep = readVipImage( std::string( IMAGEDEVDATA_IMAGES_FOLDER ) + "foam_sep.vip" );

SeparateObjects separateObjectsAlgo;
separateObjectsAlgo.setInputBinaryImage( foam_sep );
separateObjectsAlgo.setContrastValue( 4 );
separateObjectsAlgo.setOutputType( SeparateObjects::OutputType::SEPARATED_OBJECTS );
separateObjectsAlgo.setAlgorithmMode( SeparateObjects::AlgorithmMode::REPEATABLE );
separateObjectsAlgo.setNeighborhood( SeparateObjects::Neighborhood::CONNECTIVITY_26 );
separateObjectsAlgo.execute();

std::cout << "outputImage:" << separateObjectsAlgo.outputImage()->toString();
foam_sep = imagedev.read_vip_image(imagedev_data.get_image_path("foam_sep.vip"))

separate_objects_algo = imagedev.SeparateObjects()
separate_objects_algo.input_binary_image = foam_sep
separate_objects_algo.contrast_value = 4
separate_objects_algo.output_type = imagedev.SeparateObjects.SEPARATED_OBJECTS
separate_objects_algo.algorithm_mode = imagedev.SeparateObjects.REPEATABLE
separate_objects_algo.neighborhood = imagedev.SeparateObjects.CONNECTIVITY_26
separate_objects_algo.execute()

print( "output_image:", str( separate_objects_algo.output_image ) )
ImageView foam_sep = Data.ReadVipImage( @"Data/images/foam_sep.vip" );

SeparateObjects separateObjectsAlgo = new SeparateObjects
{
    inputBinaryImage = foam_sep,
    contrastValue = 4,
    outputType = SeparateObjects.OutputType.SEPARATED_OBJECTS,
    algorithmMode = SeparateObjects.AlgorithmMode.REPEATABLE,
    neighborhood = SeparateObjects.Neighborhood.CONNECTIVITY_26
};
separateObjectsAlgo.Execute();

Console.WriteLine( "outputImage:" + separateObjectsAlgo.outputImage.ToString() );

Function Examples

auto foam_sep = readVipImage( std::string( IMAGEDEVDATA_IMAGES_FOLDER ) + "foam_sep.vip" );

auto result = separateObjects( foam_sep, 4, SeparateObjects::OutputType::SEPARATED_OBJECTS, SeparateObjects::AlgorithmMode::REPEATABLE, SeparateObjects::Neighborhood::CONNECTIVITY_26 );

std::cout << "outputImage:" << result->toString();
foam_sep = imagedev.read_vip_image(imagedev_data.get_image_path("foam_sep.vip"))

result = imagedev.separate_objects( foam_sep, 4, imagedev.SeparateObjects.SEPARATED_OBJECTS, imagedev.SeparateObjects.REPEATABLE, imagedev.SeparateObjects.CONNECTIVITY_26 )

print( "output_image:", str( result ) )
ImageView foam_sep = Data.ReadVipImage( @"Data/images/foam_sep.vip" );

IOLink.ImageView result = Processing.SeparateObjects( foam_sep, 4, SeparateObjects.OutputType.SEPARATED_OBJECTS, SeparateObjects.AlgorithmMode.REPEATABLE, SeparateObjects.Neighborhood.CONNECTIVITY_26 );

Console.WriteLine( "outputImage:" + result.ToString() );