Refactor small region merging
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
-
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 sizeTileSize
) -
Starting from size
i = 1
to sizei = MinSize
: Find and store for each segment of sizei
the label of its neighbour (this is done tile by tile). Then compare the mean vector of each segments of sizei
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.
-
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 fori=1
toi= 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 givenoutputRegionForThread
. 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 theStreamingStatisticsMapFromLabelImageFilter
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 aPersistentStreamingDecorator<PersistentLabelImageSmallRegionMergingFilter>
and calls it recursively from size 1 to sizeMinSize
(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