Commit 086aee41 authored by Cédric Traizet's avatar Cédric Traizet
Browse files

ENH : persistent small region merging app

parent c12f8611
......@@ -128,16 +128,6 @@ private:
SetMinimumParameterIntValue("minsize", 0);
MandatoryOff("minsize");
AddParameter(ParameterType_Int, "tilesizex", "Size of tiles in pixel (X-axis)");
SetParameterDescription("tilesizex", "Size of tiles along the X-axis for tile-wise processing.");
SetDefaultParameterInt("tilesizex", 500);
SetMinimumParameterIntValue("tilesizex", 1);
AddParameter(ParameterType_Int, "tilesizey", "Size of tiles in pixel (Y-axis)");
SetParameterDescription("tilesizey", "Size of tiles along the Y-axis for tile-wise processing.");
SetDefaultParameterInt("tilesizey", 500);
SetMinimumParameterIntValue("tilesizey", 1);
AddRAMParameter();
// Doc example parameter settings
......@@ -158,12 +148,9 @@ private:
void DoExecute() override
{
clock_t tic = clock();
unsigned int minSize = GetParameterInt("minsize");
unsigned long sizeTilesX = GetParameterInt("tilesizex");
unsigned long sizeTilesY = GetParameterInt("tilesizey");
//Acquisition of the input image dimensions
ImageType::Pointer imageIn = GetParameterImage("in");
......@@ -176,16 +163,12 @@ private:
AddProcess(labelStatsFilter->GetStreamer() , "Computing stats on input image ...");
labelStatsFilter->Update();
auto meanMap = labelStatsFilter->GetMeanValueMap();
auto nbPixelsMap = labelStatsFilter->GetLabelPopulationMap();
// Merge small segments
auto regionMergingFilter = LabelImageSmallRegionMergingFilterType::New();
regionMergingFilter->SetInputLabelImage( labelIn );
regionMergingFilter->SetInputSpectralImage( imageIn );
regionMergingFilter->SetLabelPopulation( nbPixelsMap );
regionMergingFilter->SetLabelPopulation( labelStatsFilter->GetLabelPopulationMap() );
regionMergingFilter->SetLabelStatistic( labelStatsFilter->GetMeanValueMap() );
for (unsigned int size = 1 ; size < minSize ; size++)
......@@ -194,20 +177,22 @@ private:
regionMergingFilter->Update();
}
/*
//Relabelling
m_ChangeLabelFilter = ChangeLabelImageFilterType::New();
m_ChangeLabelFilter->SetInput(labelIn);
for(LabelImagePixelType label = 1; label<regionCount+1; ++label)
auto changeLabelFilter = ChangeLabelImageFilterType::New();
changeLabelFilter->SetInput(labelIn);
auto correspondanceMap = regionMergingFilter->GetCorrespondanceMap();
for (auto correspondance : correspondanceMap)
{
if (correspondance.first != correspondance.second)
{
if(label!=LUT[label])
{
m_ChangeLabelFilter->SetChange(label,LUT[label]);
}
std::cout << correspondance.first << " " << correspondance.second << std::endl;
changeLabelFilter->SetChange(correspondance.first, correspondance.second);
}
}
SetParameterOutputImage("out", changeLabelFilter->GetOutput());
SetParameterOutputImage("out", m_ChangeLabelFilter->GetOutput());
*/
clock_t toc = clock();
otbAppLogINFO(<<"Elapsed time: "<<(double)(toc - tic) / CLOCKS_PER_SEC<<" seconds");
......
......@@ -80,7 +80,7 @@ public:
typedef std::map<InputLabelType, double> LabelPopulationMapType;
typedef std::map<InputLabelType, std::set<InputLabelType> > NeigboursMapType;
typedef std::map<InputLabelType, RealVectorPixelType > LabelStatisticMapType;
typedef std::map<InputLabelType, InputLabelType> CorrespondanceMapType;
/** Sets the input image where the value of a pixel is the region id */
void SetInputLabelImage( const InputLabelImageType * labelImage);
/** Sets the input image representing spectral values */
......@@ -94,10 +94,15 @@ public:
itkGetMacro(Size , unsigned int);
itkSetMacro(Size , unsigned int);
/** Set/Get the Label population map */
/** Set/Get the Label population map and initialize the correspondance map*/
void SetLabelPopulation( LabelPopulationMapType const & labelPopulation )
{
m_LabelPopulation = labelPopulation;
// Initialize m_CorrespondingMap to the identity (i.e. m[label] = label)
for (auto label : labelPopulation)
{
m_CorrespondanceMap[ label.first ] = label.first;
}
}
LabelPopulationMapType const & GetLabelPopulation() const
......@@ -107,12 +112,17 @@ public:
void SetLabelStatistic( LabelStatisticMapType const & labelStatistic )
{
m_labelStatistic = labelStatistic;
m_LabelStatistic = labelStatistic;
}
LabelStatisticMapType const & GetLabelStatistic() const
{
return m_labelStatistic;
return m_LabelStatistic;
}
CorrespondanceMapType const & GetCorrespondanceMap() const
{
return m_CorrespondanceMap;
}
virtual void Reset(void);
......@@ -126,6 +136,10 @@ protected:
void ThreadedGenerateData(const RegionType&
outputRegionForThread, itk::ThreadIdType threadId) override;
// Use m_CorrespondanceMap recurively to find the label corresponding to the input label
InputLabelType FindCorrespondingLabel( InputLabelType label);
/** Constructor */
PersistentLabelImageSmallRegionMergingFilter();
......@@ -142,12 +156,13 @@ private:
unsigned int m_Size;
LabelPopulationMapType m_LabelPopulation;
LabelStatisticMapType m_labelStatistic;
LabelStatisticMapType m_LabelStatistic;
// Neigbours maps for each thread
std::vector <NeigboursMapType > m_NeighboursMapsTmp;
NeigboursMapType m_NeighboursMap;
CorrespondanceMapType m_CorrespondanceMap;
//NeigboursMapType m_NeighboursMap;
};
/** \class LabelImageSmallRegionMergingFilter
......@@ -185,6 +200,7 @@ public:
typedef typename PersistentFilterType::InputSpectralImageType InputSpectralImageType;
typedef typename PersistentFilterType::LabelPopulationMapType LabelPopulationMapType;
typedef typename PersistentFilterType::LabelStatisticMapType LabelStatisticMapType;
typedef typename PersistentFilterType::CorrespondanceMapType CorrespondanceMapType;
/** Sets the input image where the value of a pixel is the region id */
void SetInputLabelImage( const InputLabelImageType * labelImage)
......@@ -247,6 +263,12 @@ public:
return this->GetFilter()->GetLabelStatistic();
}
CorrespondanceMapType const & GetCorrespondanceMap() const
{
return this->GetFilter()->GetCorrespondanceMap();
}
protected:
/** Constructor */
LabelImageSmallRegionMergingFilter() {}
......
......@@ -98,7 +98,7 @@ PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralIma
std::cout << "Synthetize" << std::endl;
NeigboursMapType neighboursMap;
// Merge the neighbours maps from all threads
for( int threadId = 0; threadId < this->GetNumberOfThreads(); threadId++)
for( unsigned int threadId = 0; threadId < this->GetNumberOfThreads(); threadId++)
{
for (auto it = m_NeighboursMapsTmp[threadId].begin(); it != m_NeighboursMapsTmp[threadId].end(); it++)
{
......@@ -106,18 +106,54 @@ PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralIma
}
}
for (auto itLabel = neighboursMap.begin(); itLabel != neighboursMap.end(); ++itLabel)
// For each label of the label map, find the "closest" connected label, according
// to the euclidian distance between the corresponding m_labelStatistic elements.
for (auto neighbours : neighboursMap)
{
InputLabelType neighbor = itLabel->first;
double proximity = std::numeric_limits<double>::max();
InputLabelType label = neighbours.first;
InputLabelType closestNeighbour = label;
for (auto neighbour : neighbours.second)
{
auto statsLabel = m_LabelStatistic[ label ];
auto statsNeighbour = m_LabelStatistic[ neighbour ];
assert( statsLabel.Size() == statsNeighbour.Size() );
double distance = 0;
for (int i = 0 ; i < statsLabel.Size(); i++)
{
distance += pow( statsLabel[i] - statsNeighbour[i] , 2);
}
if (distance < proximity)
{
proximity = distance;
closestNeighbour = neighbour;
}
std::cout << label << " " << neighbour << " " << distance << " " << closestNeighbour <<std::endl;
}
m_CorrespondanceMap[label] = closestNeighbour;
//InputLabelType neighbor = itLabel->first;
//
for (auto itNeigh = itLabel->second.begin(); itNeigh != itLabel->second.end(); ++itNeigh)
/*for (auto itNeigh = itLabel->second.begin(); itNeigh != itLabel->second.end(); ++itNeigh)
{
// Compute squared distance between the current label and the current neighbour
//double dist = std::abs( std::pow( m_labelStatistic[itLabel->first], 2) - std::pow( m_labelStatistic[*itNeigh], 2) );
}
for (auto
}*/
}
// We have to update corresponding label to propagate the correspondance between the labels.
for (auto corres : m_CorrespondanceMap)
{
corres.second = FindCorrespondingLabel(corres.second);
std::cout << "label : " << corres.first << " closest : " << corres.second << std::endl;
}
/*
for (auto it = m_NeighboursMap.begin(); it != m_NeighboursMap.end(); it++)
{
......@@ -128,6 +164,23 @@ PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralIma
}*/
}
template <class TInputLabelImage, class TInputSpectralImage>
typename PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>::InputLabelType
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::FindCorrespondingLabel( typename PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::InputLabelType label)
{
auto correspondingLabel = m_CorrespondanceMap[label];
while (label != correspondingLabel)
{std::cout << "yo" << std::endl;
label = correspondingLabel;
correspondingLabel = m_CorrespondanceMap[correspondingLabel];
}
return correspondingLabel;
}
template <class TInputLabelImage, class TInputSpectralImage>
void
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
......@@ -141,7 +194,8 @@ void
PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralImage>
::ThreadedGenerateData(const RegionType& outputRegionForThread, itk::ThreadIdType threadId )
{
std::cout << threadId << std::endl;
std::cout << threadId << " " << outputRegionForThread.GetSize() << " " << outputRegionForThread.GetIndex() << std::endl;
using IteratorType = itk::ImageRegionConstIterator< TInputLabelImage >;
using NeighborhoodIteratorType = itk::ConstShapedNeighborhoodIterator< TInputLabelImage >;
typename NeighborhoodIteratorType::RadiusType radius;
......@@ -171,8 +225,9 @@ PersistentLabelImageSmallRegionMergingFilter<TInputLabelImage, TInputSpectralIma
//std::cout << it.Get() << std::endl;
for (auto ci = itN.Begin() ; !ci.IsAtEnd(); ci++)
{
int neighbourLabel = ci.Get();
if (neighbourLabel != it.Get())
int neighbourLabel = FindCorrespondingLabel(ci.Get() );
std::cout << neighbourLabel << " " << ci.Get() << " " << it.Get() << std::endl;
if (neighbourLabel != it.Get() && m_LabelPopulation[neighbourLabel] > m_Size)
m_NeighboursMapsTmp[threadId][ it.Get() ].insert( neighbourLabel );
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment