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
LabelImagethe 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 = 1to sizei = MinSize: Find and store for each segment of sizeithe label of its neighbour (this is done tile by tile). Then compare the mean vector of each segments of sizeito 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 
iand update the LUT. This filter is called recursively fori=1toi= 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
iin 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 theStreamingStatisticsMapFromLabelImageFilterto 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