Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
Main Repositories
otb
Commits
100f3818
Commit
100f3818
authored
Sep 27, 2018
by
Cédric Traizet
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'small_region_merging' into 'develop'
Refactor small region merging See merge request
!233
parents
7ec1f79b
bfa19860
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
855 additions
and
3 deletions
+855
-3
Modules/Applications/AppSegmentation/app/CMakeLists.txt
Modules/Applications/AppSegmentation/app/CMakeLists.txt
+5
-0
Modules/Applications/AppSegmentation/app/otbLSMSSmallRegionsMerging.cxx
...ations/AppSegmentation/app/otbLSMSSmallRegionsMerging.cxx
+1
-0
Modules/Applications/AppSegmentation/app/otbLargeScaleMeanShift.cxx
...plications/AppSegmentation/app/otbLargeScaleMeanShift.cxx
+1
-3
Modules/Applications/AppSegmentation/app/otbSmallRegionsMerging.cxx
...plications/AppSegmentation/app/otbSmallRegionsMerging.cxx
+198
-0
Modules/Applications/AppSegmentation/test/CMakeLists.txt
Modules/Applications/AppSegmentation/test/CMakeLists.txt
+15
-0
Modules/Segmentation/Conversion/include/otbLabelImageSmallRegionMergingFilter.h
...onversion/include/otbLabelImageSmallRegionMergingFilter.h
+255
-0
Modules/Segmentation/Conversion/include/otbLabelImageSmallRegionMergingFilter.hxx
...version/include/otbLabelImageSmallRegionMergingFilter.hxx
+380
-0
No files found.
Modules/Applications/AppSegmentation/app/CMakeLists.txt
View file @
100f3818
...
...
@@ -57,3 +57,8 @@ otb_create_application(
NAME LargeScaleMeanShift
SOURCES otbLargeScaleMeanShift.cxx
LINK_LIBRARIES
${${
otb-module
}
_LIBRARIES
}
)
otb_create_application
(
NAME SmallRegionsMerging
SOURCES otbSmallRegionsMerging.cxx
LINK_LIBRARIES
${${
otb-module
}
_LIBRARIES
}
)
Modules/Applications/AppSegmentation/app/otbLSMSSmallRegionsMerging.cxx
View file @
100f3818
...
...
@@ -104,6 +104,7 @@ private:
"[2] LSMSegmentation
\n
"
"[3] LSMSVectorization"
);
AddDocTag
(
Tags
::
Segmentation
);
AddDocTag
(
Tags
::
Deprecated
);
AddDocTag
(
"LSMS"
);
AddParameter
(
ParameterType_InputImage
,
"in"
,
"Input image"
);
...
...
Modules/Applications/AppSegmentation/app/otbLargeScaleMeanShift.cxx
View file @
100f3818
...
...
@@ -86,7 +86,7 @@ private:
ClearApplications
();
AddApplication
(
"MeanShiftSmoothing"
,
"smoothing"
,
"Smoothing step"
);
AddApplication
(
"LSMSSegmentation"
,
"segmentation"
,
"Segmentation step"
);
AddApplication
(
"
LSMS
SmallRegionsMerging"
,
"merging"
,
"Small region merging step"
);
AddApplication
(
"SmallRegionsMerging"
,
"merging"
,
"Small region merging step"
);
AddApplication
(
"LSMSVectorization"
,
"vectorization"
,
"Vectorization step"
);
ShareParameter
(
"in"
,
"smoothing.in"
);
...
...
@@ -130,8 +130,6 @@ private:
Connect
(
"merging.ram"
,
"smoothing.ram"
);
Connect
(
"vectorization.ram"
,
"smoothing.ram"
);
Connect
(
"merging.tilesizex"
,
"segmentation.tilesizex"
);
Connect
(
"merging.tilesizey"
,
"segmentation.tilesizey"
);
Connect
(
"vectorization.tilesizex"
,
"segmentation.tilesizex"
);
Connect
(
"vectorization.tilesizey"
,
"segmentation.tilesizey"
);
...
...
Modules/Applications/AppSegmentation/app/otbSmallRegionsMerging.cxx
0 → 100644
View file @
100f3818
/*
* Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"
#include "otbStreamingStatisticsMapFromLabelImageFilter.h"
#include "otbLabelImageSmallRegionMergingFilter.h"
#include "itkChangeLabelImageFilter.h"
#include "otbStopwatch.h"
namespace
otb
{
namespace
Wrapper
{
class
SmallRegionsMerging
:
public
Application
{
public:
typedef
SmallRegionsMerging
Self
;
typedef
Application
Superclass
;
typedef
itk
::
SmartPointer
<
Self
>
Pointer
;
typedef
itk
::
SmartPointer
<
const
Self
>
ConstPointer
;
typedef
FloatVectorImageType
ImageType
;
typedef
ImageType
::
InternalPixelType
ImagePixelType
;
typedef
UInt32ImageType
LabelImageType
;
typedef
LabelImageType
::
InternalPixelType
LabelImagePixelType
;
typedef
otb
::
StreamingStatisticsMapFromLabelImageFilter
<
ImageType
,
LabelImageType
>
StatisticsMapFromLabelImageFilterType
;
typedef
otb
::
LabelImageSmallRegionMergingFilter
<
LabelImageType
>
LabelImageSmallRegionMergingFilterType
;
typedef
itk
::
ChangeLabelImageFilter
<
LabelImageType
,
LabelImageType
>
ChangeLabelImageFilterType
;
itkNewMacro
(
Self
);
itkTypeMacro
(
Merging
,
otb
::
Application
);
private:
ChangeLabelImageFilterType
::
Pointer
m_ChangeLabelFilter
;
void
DoInit
()
override
{
SetName
(
"SmallRegionsMerging"
);
SetDescription
(
"This application merges small regions of a segmentation "
"result."
);
SetDocName
(
"Small Region Merging"
);
SetDocLongDescription
(
"Given a segmentation result and the original image,"
" it will merge segments whose size in pixels is"
" lower than minsize parameter with the adjacent"
" segments with the adjacent segment with closest"
" radiometry and acceptable size.
\n\n
"
"Small segments will be processed by increasing size:"
" first all segments for which area is equal to 1"
" pixel will be merged with adjacent segments, then"
" all segments of area equal to 2 pixels will be"
" processed, until segments of area minsize."
);
SetDocLimitations
(
"None"
)
;
SetDocAuthors
(
"OTB-Team"
);
SetDocSeeAlso
(
"Segmentation"
);
AddDocTag
(
Tags
::
Segmentation
);
AddParameter
(
ParameterType_InputImage
,
"in"
,
"Input image"
);
SetParameterDescription
(
"in"
,
"The input image, containing initial"
" spectral signatures corresponding to the segmented image (inseg)."
);
AddParameter
(
ParameterType_InputImage
,
"inseg"
,
"Segmented image"
);
SetParameterDescription
(
"inseg"
,
"Segmented image where each pixel value"
" is the unique integer label of the segment it belongs to."
);
AddParameter
(
ParameterType_OutputImage
,
"out"
,
"Output Image"
);
SetParameterDescription
(
"out"
,
"The output image. The output image is the"
" segmented image where the minimal segments have been merged."
);
SetDefaultOutputPixelType
(
"out"
,
ImagePixelType_uint32
);
AddParameter
(
ParameterType_Int
,
"minsize"
,
"Minimum Segment Size"
);
SetParameterDescription
(
"minsize"
,
"Minimum Segment Size. If, after the "
" segmentation, a segment is of size strictly lower than this criterion,"
" the segment is merged with the segment that has the closest sepctral"
" signature."
);
SetDefaultParameterInt
(
"minsize"
,
50
);
SetMinimumParameterIntValue
(
"minsize"
,
1
);
MandatoryOff
(
"minsize"
);
AddRAMParameter
();
// Doc example parameter settings
SetDocExampleParameterValue
(
"in"
,
"smooth.tif"
);
SetDocExampleParameterValue
(
"inseg"
,
"segmentation.tif"
);
SetDocExampleParameterValue
(
"out"
,
"merged.tif"
);
SetDocExampleParameterValue
(
"minsize"
,
"50"
);
SetOfficialDocLink
();
}
void
DoUpdateParameters
()
override
{
}
void
DoExecute
()
override
{
// Start Timer for the application
auto
Timer
=
Stopwatch
::
StartNew
();
unsigned
int
minSize
=
GetParameterInt
(
"minsize"
);
//Acquisition of the input image dimensions
ImageType
::
Pointer
imageIn
=
GetParameterImage
(
"in"
);
LabelImageType
::
Pointer
labelIn
=
GetParameterUInt32Image
(
"inseg"
);
// Compute statistics for each segment
auto
labelStatsFilter
=
StatisticsMapFromLabelImageFilterType
::
New
();
labelStatsFilter
->
SetInput
(
imageIn
);
labelStatsFilter
->
SetInputLabelImage
(
labelIn
);
AddProcess
(
labelStatsFilter
->
GetStreamer
()
,
"Computing stats on input"
" image ..."
);
labelStatsFilter
->
Update
();
// Convert Map to Unordered map
auto
labelPopulationMap
=
labelStatsFilter
->
GetLabelPopulationMap
();
std
::
unordered_map
<
unsigned
int
,
double
>
labelPopulation
;
for
(
auto
population
:
labelPopulationMap
)
{
labelPopulation
[
population
.
first
]
=
population
.
second
;
}
auto
meanValueMap
=
labelStatsFilter
->
GetMeanValueMap
();
std
::
unordered_map
<
unsigned
int
,
itk
::
VariableLengthVector
<
double
>
>
meanValues
;
for
(
const
auto
&
mean
:
meanValueMap
)
{
meanValues
[
mean
.
first
]
=
mean
.
second
;
}
// Compute the LUT from the original label image to the merged output
// label image.
auto
regionMergingFilter
=
LabelImageSmallRegionMergingFilterType
::
New
();
regionMergingFilter
->
SetInputLabelImage
(
labelIn
);
regionMergingFilter
->
SetLabelPopulation
(
labelPopulation
);
regionMergingFilter
->
SetLabelStatistic
(
meanValues
);
regionMergingFilter
->
SetMinSize
(
minSize
);
AddProcess
(
regionMergingFilter
,
"Computing LUT ..."
);
regionMergingFilter
->
Update
();
// Relabelling using the LUT
auto
changeLabelFilter
=
ChangeLabelImageFilterType
::
New
();
changeLabelFilter
->
SetInput
(
labelIn
);
const
auto
&
LUT
=
regionMergingFilter
->
GetLUT
();
for
(
auto
const
&
label
:
LUT
)
{
if
(
label
.
first
!=
label
.
second
)
{
changeLabelFilter
->
SetChange
(
label
.
first
,
label
.
second
);
}
}
SetParameterOutputImage
(
"out"
,
changeLabelFilter
->
GetOutput
());
RegisterPipeline
();
Timer
.
Stop
();
otbAppLogINFO
(
"Total elapsed time: "
<<
float
(
Timer
.
GetElapsedMilliseconds
())
/
1000
<<
" seconds."
);
}
};
}
}
OTB_APPLICATION_EXPORT
(
otb
::
Wrapper
::
SmallRegionsMerging
)
Modules/Applications/AppSegmentation/test/CMakeLists.txt
View file @
100f3818
...
...
@@ -250,6 +250,20 @@ otb_test_application(NAME apTvLSMS3SmallRegionsMerging
set_property
(
TEST apTvLSMS3SmallRegionsMerging PROPERTY DEPENDS apTvLSMS2Segmentation
)
#----------- SmallRegionsMerging TESTS ----------------
otb_test_application
(
NAME apTvSmallRegionsMerging
APP SmallRegionsMerging
OPTIONS -in
${
TEMP
}
/apTvLSMS1_filtered_range.tif
-inseg
${
TEMP
}
/apTvLSMS2_Segmentation.tif
-out
${
TEMP
}
/apTvSmallMerged.tif uint32
-minsize 10
VALID --compare-image
${
NOTOL
}
${
BASELINE
}
/apTvSmallMerged.tif
${
TEMP
}
/apTvSmallMerged.tif
)
set_property
(
TEST apTvSmallRegionsMerging PROPERTY DEPENDS apTvLSMS2Segmentation
)
#----------- LSMSVectorization TESTS ----------------
otb_test_application
(
NAME apTvLSMS4Vectorization_SmallMerged
APP LSMSVectorization
...
...
@@ -308,3 +322,4 @@ otb_test_application(NAME apTvSeLargeScaleMeanShiftTest
${
BASELINE_FILES
}
/apTvSeLargeScaleMeanShiftTestOut.shp
${
TEMP
}
/apTvSeLargeScaleMeanShiftTestOut.shp
)
Modules/Segmentation/Conversion/include/otbLabelImageSmallRegionMergingFilter.h
0 → 100644
View file @
100f3818
/*
* Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef otbLabelImageSmallRegionMergingFilter_h
#define otbLabelImageSmallRegionMergingFilter_h
#include "otbPersistentImageFilter.h"
#include "otbPersistentFilterStreamingDecorator.h"
#include <unordered_map>
namespace
otb
{
/** \class PersistentLabelImageSmallRegionMergingFilter
*
* This class can be used to merge each segments of a given size in a label
* image to the connected segment with the closest radiometry (in the sense of
* the euclidian squared distance).
* This persistent filter should be used as template parameter of a
* PersistentFilterStreamingDecorator.
* It computes from an input label image an equivalence table
* that gives for each pixel, the corresponding label in the merged image.
* The merged image can then be computed using a ChangeLabelImageFilter.
*
* This filter can be updated several times for different values of size,
* the output equivalence table will be the results of all computations.
*
* \ingroup ImageSegmentation
*
* \ingroup OTBConversion
*/
template
<
class
TInputLabelImage
>
class
ITK_EXPORT
PersistentLabelImageSmallRegionMergingFilter
:
public
PersistentImageFilter
<
TInputLabelImage
,
TInputLabelImage
>
{
public:
/** Standard class typedef */
typedef
PersistentLabelImageSmallRegionMergingFilter
Self
;
typedef
PersistentImageFilter
<
TInputLabelImage
,
TInputLabelImage
>
Superclass
;
typedef
itk
::
SmartPointer
<
Self
>
Pointer
;
typedef
itk
::
SmartPointer
<
const
Self
>
ConstPointer
;
/** Type macro */
itkTypeMacro
(
PersistentLabelImageSmallRegionMergingFilter
,
PersistentImageFilter
);
itkNewMacro
(
Self
);
/** Template parameters typedefs */
typedef
TInputLabelImage
InputImageType
;
typedef
typename
InputImageType
::
Pointer
InputImagePointerType
;
typedef
typename
InputImageType
::
PixelType
InputLabelType
;
typedef
typename
InputImageType
::
SizeType
InputSizeType
;
typedef
typename
InputImageType
::
PointType
PointType
;
typedef
typename
InputImageType
::
RegionType
RegionType
;
typedef
itk
::
VariableLengthVector
<
double
>
RealVectorPixelType
;
typedef
std
::
unordered_map
<
InputLabelType
,
std
::
set
<
InputLabelType
>
>
NeigboursMapType
;
typedef
std
::
unordered_map
<
InputLabelType
,
RealVectorPixelType
>
LabelStatisticType
;
typedef
std
::
unordered_map
<
InputLabelType
,
double
>
LabelPopulationType
;
typedef
std
::
unordered_map
<
InputLabelType
,
InputLabelType
>
LUTType
;
/** Set/Get size of segments to be merged */
itkGetMacro
(
Size
,
unsigned
int
);
itkSetMacro
(
Size
,
unsigned
int
);
/** Set the Label population and initialize the LUT */
void
SetLabelPopulation
(
LabelPopulationType
const
&
labelPopulation
);
/** Get the Label population */
LabelPopulationType
const
&
GetLabelPopulation
()
const
;
/** Set the label statistic */
void
SetLabelStatistic
(
LabelStatisticType
const
&
labelStatistic
);
/** Get the label statistic */
LabelStatisticType
const
&
GetLabelStatistic
()
const
;
/** Get the LUT */
LUTType
const
&
GetLUT
()
const
;
virtual
void
Reset
(
void
)
override
;
virtual
void
Synthetize
(
void
)
override
;
protected:
/** The input requested region should be padded by a radius of 1 to use the
* neigbourhood iterator */
void
GenerateInputRequestedRegion
()
override
;
/** Threaded Generate Data : find the neighbours of each segments of size
* m_Size for each tile and store them in an accumulator */
void
ThreadedGenerateData
(
const
RegionType
&
outputRegionForThread
,
itk
::
ThreadIdType
threadId
)
override
;
/** Use the LUT recursively to find the label corresponding to the input
* label */
InputLabelType
FindCorrespondingLabel
(
InputLabelType
label
);
/** Constructor */
PersistentLabelImageSmallRegionMergingFilter
();
/** Destructor */
~
PersistentLabelImageSmallRegionMergingFilter
()
override
=
default
;
/** PrintSelf method */
void
PrintSelf
(
std
::
ostream
&
os
,
itk
::
Indent
indent
)
const
override
;
private:
PersistentLabelImageSmallRegionMergingFilter
(
const
Self
&
)
=
delete
;
void
operator
=
(
const
Self
&
)
=
delete
;
/** Size of the segments to be merged */
unsigned
int
m_Size
;
/** Map containing at key i the population of the segment labelled i */
LabelPopulationType
m_LabelPopulation
;
/** Map containing at key i the mean of element of the segment labelled i */
LabelStatisticType
m_LabelStatistic
;
/** Neigbours maps for each thread */
std
::
vector
<
NeigboursMapType
>
m_NeighboursMapsTmp
;
/** LUT giving correspondance between labels in the original segmentation
* and the merged labels */
LUTType
m_LUT
;
};
/** \class LabelImageSmallRegionMergingFilter
*
* This filter computes from a label image an equivalence table that gives for
* each pixel, the corresponding label in the merged image. It uses a
* PersistentFilterStreamingDecorator templated over a
* PersistentLabelImageSmallRegionMergingFilter
* to merge the segments recursively from segment of size 1 to segment of a
* size specified by the attribute MinSize.
* The equivalence table can be accessed with the method GetLut and used to
* compute the merged image with a ChangeLabelImageFilterType.
*
* \ingroup ImageSegmentation
*
* \ingroup OTBConversion
*/
template
<
class
TInputLabelImage
>
class
ITK_EXPORT
LabelImageSmallRegionMergingFilter
:
public
itk
::
ProcessObject
{
public:
/** Standard Self typedef */
typedef
LabelImageSmallRegionMergingFilter
Self
;
typedef
itk
::
ProcessObject
Superclass
;
typedef
itk
::
SmartPointer
<
Self
>
Pointer
;
typedef
itk
::
SmartPointer
<
const
Self
>
ConstPointer
;
/** Type macro */
itkNewMacro
(
Self
);
/** Creation through object factory macro */
itkTypeMacro
(
LabelImageSmallRegionMergingFilter
,
itk
::
ProcessObject
);
// Small region merging filter typedefs
typedef
PersistentLabelImageSmallRegionMergingFilter
<
TInputLabelImage
>
PersistentLabelImageSmallRegionMergingFilterType
;
typedef
PersistentFilterStreamingDecorator
<
PersistentLabelImageSmallRegionMergingFilterType
>
LabelImageSmallRegionMergingFilterType
;
typedef
typename
PersistentLabelImageSmallRegionMergingFilterType
::
LabelPopulationType
LabelPopulationType
;
typedef
typename
PersistentLabelImageSmallRegionMergingFilterType
::
LabelStatisticType
LabelStatisticType
;
typedef
typename
PersistentLabelImageSmallRegionMergingFilterType
::
LUTType
LUTType
;
/** Set/Get size of polygon to be merged */
itkGetMacro
(
MinSize
,
unsigned
int
);
itkSetMacro
(
MinSize
,
unsigned
int
);
/** Set the Label population map */
void
SetInputLabelImage
(
const
TInputLabelImage
*
labelImage
);
/** Set the Label population map */
void
SetLabelPopulation
(
LabelPopulationType
const
&
labelPopulation
);
/** Get the Label population map */
LabelPopulationType
const
&
GetLabelPopulation
()
const
;
/** Set the Label statistic map */
void
SetLabelStatistic
(
LabelStatisticType
const
&
labelStatistic
);
/** Get the Label statistic map */
LabelStatisticType
const
&
GetLabelStatistic
()
const
;
/** Get the Label statistic map */
LUTType
const
&
GetLUT
()
const
;
/** Call GenerateData() */
void
Update
()
override
;
protected:
/** Constructor */
LabelImageSmallRegionMergingFilter
();
/** Destructor */
~
LabelImageSmallRegionMergingFilter
()
override
=
default
;
/** Generate Data method (Update LabelImageSmallRegionMergingFilterType
* recursively) */
void
GenerateData
()
override
;
private:
LabelImageSmallRegionMergingFilter
(
const
Self
&
)
=
delete
;
void
operator
=
(
const
Self
&
)
=
delete
;
// Filter used recursively to build the equivalence table
typename
LabelImageSmallRegionMergingFilterType
::
Pointer
m_SmallRegionMergingFilter
;
// All segments with size < m_MinSize will be merged to bigger segments.
unsigned
int
m_MinSize
;
};
}
// end namespace otb
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbLabelImageSmallRegionMergingFilter.hxx"
#endif
#endif
Modules/Segmentation/Conversion/include/otbLabelImageSmallRegionMergingFilter.hxx
0 → 100644
View file @
100f3818
/*
* Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef otbLabelImageSmallRegionMergingFilter_hxx
#define otbLabelImageSmallRegionMergingFilter_hxx
#include "otbLabelImageSmallRegionMergingFilter.h"
#include "itkConstShapedNeighborhoodIterator.h"
#include "itkProgressReporter.h"
namespace
otb
{
template
<
class
TInputLabelImage
>
PersistentLabelImageSmallRegionMergingFilter
<
TInputLabelImage
>
::
PersistentLabelImageSmallRegionMergingFilter
()
:
m_Size
(
1
)
{
}
template
<
class
TInputLabelImage
>
void
PersistentLabelImageSmallRegionMergingFilter
<
TInputLabelImage
>
::
SetLabelPopulation
(
LabelPopulationType
const
&
labelPopulation
)
{
m_LabelPopulation
=
labelPopulation
;
// Initialize m_CorrespondingMap to the identity (i.e. m[label] = label)
for
(
auto
label
:
m_LabelPopulation
)
{
m_LUT
[
label
.
first
]
=
label
.
first
;
}
}
template
<
class
TInputLabelImage
>
typename
PersistentLabelImageSmallRegionMergingFilter
<
TInputLabelImage
>
::
LabelPopulationType
const
&
PersistentLabelImageSmallRegionMergingFilter
<
TInputLabelImage
>
::
GetLabelPopulation
()
const
{
return
m_LabelPopulation
;
}
template
<
class
TInputLabelImage
>
void
PersistentLabelImageSmallRegionMergingFilter
<
TInputLabelImage
>
::
SetLabelStatistic
(
LabelStatisticType
const
&
labelStatistic
)
{
m_LabelStatistic
=
labelStatistic
;
}
template
<
class
TInputLabelImage
>
typename
PersistentLabelImageSmallRegionMergingFilter
<
TInputLabelImage
>
::
LabelStatisticType
const
&
PersistentLabelImageSmallRegionMergingFilter
<
TInputLabelImage
>
::
GetLabelStatistic
()
const