Skip to content

Refactor small region merging

Cédric Traizet requested to merge small_region_merging into develop

Summary

This merge request adds a filter and an application for small region merging, and is a refactoring of the existing application LSMSSmallRegionMerging.

Rationale

From a segmentation (raster) result, the application LSMSSmallRegionsMerging merges all the segments smaller than a given size to the connected segment with the closest radiometry and acceptable size. This application is part of the Large Scale Mean Shift (LSMS) segmentation framework, but it is also interesting as a post-processing step for other segmentation algorithms.

The algorithm used in this application can be summarized as follow : Input : LabelImage , Image , MinSize , TileSize

  1. Computes for each segment in LabelImage the number of pixel in the segment and the sum of these pixels (this will be used later to compute the mean vector of the segment). This is done tile by tile using accumulators (and tile of size TileSize)

  2. Starting from size i = 1 to size i = MinSize : Find and store for each segment of size i the label of its neighbour (this is done tile by tile). Then compare the mean vector of each segments of size i to the mean vector of its neighbours using a squared euclidian distance. The segment will be merged to the closest neighbour.

    A LUT is built to determine for each segment of the input Image its label in the merged image.

  3. The output merged image is written using the LUT and a ITK ChangeLabelImageFilter

The problem with this application is that steps 1 and 2 are implemented directly in the DoExecute() method of the application, instead of using dedicated filters. Therefore the application re-implements the functionalities offered by a filter : for example the streaming is done by hand using ExtractROI filters and a tile size specified by the user, and threading is not implemented.

The new application uses persistent filters :

  • for step 1), we use a StreamingStatisticsMapFromLabelImageFilter, already in OTB.
  • for step 2), a new persistent filter have been created. This filter merges all segment of size i and update the LUT. This filter is called recursively for i=1 to i= MinSize
  • step 3 is unchanged

Implementation Details

Classes and files
  • New persistent filter PersistentLabelImageSmallRegionMergingFilter :

    The ThreadedGenerateData method computes the neighbours of each segment of size i in the given outputRegionForThread. The synthesize method gather the neighbours of the different thread (in case some segments were split across tiles), and then use the mean vector from the StreamingStatisticsMapFromLabelImageFilter to determine the closest neighbour. The LUT and the statistics are then updated accordingly. Note that the LUT is not reseted in the Reset() method, so the filter can be called several time for different size.

  • New filter LabelImageSmallRegionMergingFilter : This filter stores a PersistentStreamingDecorator<PersistentLabelImageSmallRegionMergingFilter> and calls it recursively from size 1 to size MinSize (attribute)

These filters are implemented in files otbLabelImageSmallRegionMergingFilter.h and .hxx.

Applications

New application SmallRegionMerging in file otbSmallRegionMerging.cxx . The parameters are the same as the LSMSSmallRegionMerging application, except for the size tile parameter, as it is estimated automatically in the filters with the available RAM.

Tests

A validation test has been created for the application

Copyright

The copyright owner is CNES and has signed the ORFEO ToolBox Contributor License Agreement.


Check before merging:

  • All discussions are resolved
  • At least 2 👍 votes from core developers, no 👎 vote.
  • The feature branch is (reasonably) up-to-date with the base branch
  • Dashboard is green
  • Copyright owner has signed the ORFEO ToolBox Contributor License Agreement
Edited by Cédric Traizet

Merge request reports