/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkLabelImageToLabelMapFilter.txx,v $ Language: C++ Date: $Date: 2005/08/23 15:09:03 $ Version: $Revision: 1.6 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef __itkLabelImageToLabelMapFilter_txx #define __itkLabelImageToLabelMapFilter_txx #include "itkLabelImageToLabelMapFilter.h" #include "itkNumericTraits.h" #include "itkProgressReporter.h" #include "itkImageLinearConstIteratorWithIndex.h" namespace itk { template LabelImageToLabelMapFilter ::LabelImageToLabelMapFilter() { m_BackgroundValue = NumericTraits::NonpositiveMin(); } template void LabelImageToLabelMapFilter ::GenerateInputRequestedRegion() { // call the superclass' implementation of this method Superclass::GenerateInputRequestedRegion(); // We need all the input. InputImagePointer input = const_cast(this->GetInput()); if ( !input ) { return; } input->SetRequestedRegion( input->GetLargestPossibleRegion() ); } template void LabelImageToLabelMapFilter ::EnlargeOutputRequestedRegion(DataObject *) { this->GetOutput() ->SetRequestedRegion( this->GetOutput()->GetLargestPossibleRegion() ); } template void LabelImageToLabelMapFilter ::BeforeThreadedGenerateData() { // init the temp images - one per thread m_TemporaryImages.resize( this->GetNumberOfThreads() ); for( int i=0; iGetNumberOfThreads(); i++ ) { if( i == 0 ) { // the first one is the output image m_TemporaryImages[0] = this->GetOutput(); } else { // the other must be created m_TemporaryImages[i] = OutputImageType::New(); } // set the minimum data needed to create the objects properly m_TemporaryImages[i]->SetBackgroundValue( m_BackgroundValue ); } } template void LabelImageToLabelMapFilter ::ThreadedGenerateData( const OutputImageRegionType& regionForThread, int threadId ) { ProgressReporter progress( this, threadId, regionForThread.GetNumberOfPixels() ); typedef ImageLinearConstIteratorWithIndex< InputImageType > InputLineIteratorType; InputLineIteratorType it( this->GetInput(), regionForThread ); it.SetDirection(0); for( it.GoToBegin(); !it.IsAtEnd(); it.NextLine() ) { it.GoToBeginOfLine(); while( !it.IsAtEndOfLine() ) { const InputImagePixelType & v = it.Get(); if( v != m_BackgroundValue ) { // We've hit the start of a run IndexType idx = it.GetIndex(); long length=1; ++it; while( !it.IsAtEndOfLine() && it.Get() == v ) { ++length; ++it; } // create the run length object to go in the vector m_TemporaryImages[threadId]->SetLine( idx, length, v ); } else { // go the the next pixel ++it; } } } } template void LabelImageToLabelMapFilter ::AfterThreadedGenerateData() { OutputImageType * output = this->GetOutput(); // merge the lines from the temporary images in the output image // don't use the first image - that's the output image for( int i=1; iGetNumberOfThreads(); i++ ) { typedef typename OutputImageType::LabelObjectContainerType LabelObjectContainerType; const LabelObjectContainerType & labelObjectContainer = m_TemporaryImages[i]->GetLabelObjectContainer(); for( typename LabelObjectContainerType::const_iterator it = labelObjectContainer.begin(); it != labelObjectContainer.end(); it++ ) { LabelObjectType * labelObject = it->second; if( output->HasLabel( labelObject->GetLabel() ) ) { // merge the lines in the output's object typename LabelObjectType::LineContainerType & src = labelObject->GetLineContainer(); typename LabelObjectType::LineContainerType & dest = output->GetLabelObject( labelObject->GetLabel() )->GetLineContainer(); dest.insert( dest.end(), src.begin(), src.end() ); } else { // simply take the object output->AddLabelObject( labelObject ); } } } // release the data in the temp images m_TemporaryImages.clear(); } template void LabelImageToLabelMapFilter ::PrintSelf(std::ostream &os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "BackgroundValue: " << static_cast::PrintType>(m_BackgroundValue) << std::endl; } }// end namespace itk #endif