21 #ifndef __otbLabelImageToLabelMapWithAdjacencyFilter_txx
22 #define __otbLabelImageToLabelMapWithAdjacencyFilter_txx
25 #include "itkNumericTraits.h"
32 template <
class TInputImage,
class TOutputImage>
36 m_BackgroundValue = itk::NumericTraits<OutputImagePixelType>::NonpositiveMin();
39 template <
class TInputImage,
class TOutputImage>
44 for (
unsigned int idx = 0; idx < this->GetNumberOfInputs(); ++idx)
49 input->SetRequestedRegionToLargestPossibleRegion();
62 this->CallCopyOutputRegionToInputRegion(inputRegion, this->GetOutput()->GetRequestedRegion());
63 input->SetRequestedRegion( inputRegion );
69 template <
class TInputImage,
class TOutputImage>
77 template<
class TInputImage,
class TOutputImage>
83 m_TemporaryImages.resize( this->GetNumberOfThreads() );
85 m_TemporaryAdjacencyMaps.resize( this->GetNumberOfThreads() );
87 for(
int i=0; i<this->GetNumberOfThreads(); ++i )
92 m_TemporaryImages[0] = this->GetOutput();
97 m_TemporaryImages[i] = OutputImageType::New();
101 m_TemporaryImages[i]->SetBackgroundValue( m_BackgroundValue );
107 template<
class TInputImage,
class TOutputImage>
113 if(m_TemporaryAdjacencyMaps[threadId].find(label2)!= m_TemporaryAdjacencyMaps[threadId].end())
115 m_TemporaryAdjacencyMaps[threadId][label2].insert(label1);
120 newContainer.insert(label1);
121 m_TemporaryAdjacencyMaps[threadId][label2]=newContainer;
124 if(m_TemporaryAdjacencyMaps[threadId].find(label1)!=m_TemporaryAdjacencyMaps[threadId].end())
126 m_TemporaryAdjacencyMaps[threadId][label1].insert(label2);
131 newContainer.insert(label2);
132 m_TemporaryAdjacencyMaps[threadId][label1]=newContainer;
136 template<
class TInputImage,
class TOutputImage>
142 typename RLEVectorType::const_iterator it = line.begin();
147 while(it!=line.end())
153 this->AddAdjacency(previousLabel, nextLabel, threadId);
156 previousLabel = nextLabel;
161 template<
class TInputImage,
class TOutputImage>
170 for(
typename RLEVectorType::const_iterator it1 = line1.begin(); it1!=line1.end(); ++it1)
173 long start1 = it1->where[0];
174 long end1 = start1 + it1->length-1;
178 for(
typename RLEVectorType::const_iterator it2 = line2.begin(); it2!=line2.end(); ++it2)
181 long start2 = it2->where[0];
182 long end2 = start2 + it2->length-1;
189 if( ( (start1 >= start2 - offset) && (start1 <= end2 + offset) )
190 || ( (end1 >= start2 - offset) && (end1 <= end2 + offset) )
191 || ( (start2 >= start1 - offset) && (start2 <= end1 + offset) )
192 || ( (end2 >= start1 - offset) && (end2 <= end1 + offset) ))
195 this->AddAdjacency(label1, label2, threadId);
202 template<
class TInputImage,
class TOutputImage>
211 InputLineIteratorType it( this->GetInput(), regionForThread );
218 typename InputImageType::RegionType previousLineRegion;
219 typename InputImageType::SizeType previousLineRegionSize;
220 typename InputImageType::IndexType previousLineRegionIndex;
222 previousLineRegionIndex = regionForThread.GetIndex();
223 previousLineRegionIndex[1]--;
225 previousLineRegionSize = regionForThread.GetSize();
226 previousLineRegionSize[1]=1;
228 previousLineRegion.SetIndex(previousLineRegionIndex);
229 previousLineRegion.SetSize(previousLineRegionSize);
232 if(previousLineRegion.Crop(this->GetInput()->GetRequestedRegion()))
243 if( v != m_BackgroundValue )
254 previousLine.push_back(
RLE(idx, length, v));
264 for( it.GoToBegin(); !it.IsAtEnd(); it.NextLine() )
267 it.GoToBeginOfLine();
273 while( !it.IsAtEndOfLine() )
277 if( v != m_BackgroundValue )
283 while( !it.IsAtEndOfLine() && it.Get() == v )
289 m_TemporaryImages[threadId]->SetLine( idx, length, v );
290 currentLine.push_back(
RLE(idx, length, v));
300 if(currentLine.size()>0)
303 this->ParseLine(currentLine, threadId);
304 this->ParseConsecutiveLines(previousLine, currentLine, threadId);
308 previousLine = currentLine;
313 template<
class TInputImage,
class TOutputImage>
323 for(
int i=1; i<this->GetNumberOfThreads(); ++i )
325 typedef typename OutputImageType::LabelObjectContainerType LabelObjectContainerType;
326 const LabelObjectContainerType & labelObjectContainer = m_TemporaryImages[i]->GetLabelObjectContainer();
328 for(
typename LabelObjectContainerType::const_iterator it = labelObjectContainer.begin();
329 it != labelObjectContainer.end();
333 if( output->HasLabel( labelObject->GetLabel() ) )
336 typename LabelObjectType::LineContainerType & src = labelObject->GetLineContainer();
337 typename LabelObjectType::LineContainerType & dest = output->GetLabelObject( labelObject->GetLabel() )->GetLineContainer();
338 dest.insert( dest.end(), src.begin(), src.end() );
343 output->AddLabelObject( labelObject );
352 for(
int threadId = 1; threadId < this->GetNumberOfThreads(); ++threadId)
355 for(
typename AdjacencyMapType::const_iterator mit = m_TemporaryAdjacencyMaps[threadId].begin();
356 mit!= m_TemporaryAdjacencyMaps[threadId].end();
360 if(adjMap.find(mit->first) != adjMap.end())
365 std::vector<LabelType> mergedLabels(adjLabels1.size()+adjLabels2.size(), 0);
368 typename std::vector<LabelType>::const_iterator vend = set_union(adjLabels1.begin(), adjLabels1.end(), adjLabels2.begin(), adjLabels2.end(), mergedLabels.begin());
372 for(
typename std::vector<LabelType>::const_iterator vit = mergedLabels.begin();
375 mergedLabelsSet.insert(*vit);
379 adjMap[mit->first]=mergedLabelsSet;
384 adjMap[mit->first]=mit->second;
390 output->SetAdjacencyMap(adjMap);
393 m_TemporaryImages.clear();
394 m_TemporaryAdjacencyMaps.clear();
398 template<
class TInputImage,
class TOutputImage>
403 Superclass::PrintSelf(os, indent);
405 os << indent <<
"BackgroundValue: " <<
static_cast<typename itk::NumericTraits<OutputImagePixelType>::PrintType
>(m_BackgroundValue) << std::endl;