From: David Sarrut Date: Thu, 25 Jul 2013 09:32:39 +0000 (+0200) Subject: Merge branch 'master' of git.creatis.insa-lyon.fr:clitk X-Git-Tag: v1.4.0~164^2~40 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=dad5c078062d820e3fc4c2b6c47b822245487cb9;hp=8a1e18abc039b3abea199a6152d9822523fef9ad;p=clitk.git Merge branch 'master' of git.creatis.insa-lyon.fr:clitk --- diff --git a/common/clitkCommon.h b/common/clitkCommon.h index 8cd82fb..2f5b26f 100644 --- a/common/clitkCommon.h +++ b/common/clitkCommon.h @@ -43,6 +43,8 @@ # include #endif +#define VTK_EXCLUDE_STRSTREAM_HEADERS + //-------------------------------------------------------------------- namespace clitk { diff --git a/common/clitkTransformUtilities.h b/common/clitkTransformUtilities.h index d3644b1..562ed63 100644 --- a/common/clitkTransformUtilities.h +++ b/common/clitkTransformUtilities.h @@ -23,6 +23,7 @@ #include "itkPoint.h" #include "clitkImageCommon.h" #include "clitkCommon.h" +#define VTK_EXCLUDE_STRSTREAM_HEADERS #include #include diff --git a/common/vvImage.h b/common/vvImage.h index 7240be8..10ffc86 100644 --- a/common/vvImage.h +++ b/common/vvImage.h @@ -23,6 +23,7 @@ #include #include +#define VTK_EXCLUDE_STRSTREAM_HEADERS #include #include diff --git a/itk/clitkLabelImageOverlapMeasureFilter.h b/itk/clitkLabelImageOverlapMeasureFilter.h index 17b7c21..cf0645f 100644 --- a/itk/clitkLabelImageOverlapMeasureFilter.h +++ b/itk/clitkLabelImageOverlapMeasureFilter.h @@ -1,7 +1,7 @@ /*========================================================================= Program: vv http://www.creatis.insa-lyon.fr/rio/vv - Authors belong to: + Authors belong to: - University of LYON http://www.universite-lyon.fr/ - Léon Bérard cancer center http://www.centreleonberard.fr - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr @@ -23,24 +23,24 @@ #include "clitkFilterBase.h" #include "clitkCropLikeImageFilter.h" #include "clitkSegmentationUtils.h" -// #include "itkLabelOverlapMeasuresImageFilter.h" // itk #include #include +#include #include namespace clitk { - + //-------------------------------------------------------------------- /* Analyze the relative position of a Target (mask image) according to some Object, in a given Support. Indicate the main important - position of this Target according the Object. + position of this Target according the Object. */ //-------------------------------------------------------------------- - + template class LabelImageOverlapMeasureFilter: public virtual FilterBase, @@ -53,30 +53,30 @@ namespace clitk { typedef LabelImageOverlapMeasureFilter Self; typedef itk::SmartPointer Pointer; typedef itk::SmartPointer ConstPointer; - + /** Method for creation through the object factory. */ itkNewMacro(Self); - + /** Run-time type information (and related methods). */ itkTypeMacro(LabelImageOverlapMeasureFilter, ImageToImageFilter); /** Some convenient typedefs. */ typedef typename ImageType::ConstPointer ImageConstPointer; typedef typename ImageType::Pointer ImagePointer; - typedef typename ImageType::RegionType RegionType; + typedef typename ImageType::RegionType RegionType; typedef typename ImageType::PixelType PixelType; typedef typename ImageType::SpacingType SpacingType; typedef typename ImageType::SizeType SizeType; typedef typename ImageType::IndexType IndexType; typedef typename ImageType::PointType PointType; - + /** ImageDimension constants */ itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension); FILTERBASE_INIT; - + // Options itkGetConstMacro(BackgroundValue, PixelType); - itkSetMacro(BackgroundValue, PixelType); + //itkSetMacro(BackgroundValue, PixelType); itkGetConstMacro(Label1, PixelType); itkSetMacro(Label1, PixelType); @@ -84,18 +84,28 @@ namespace clitk { itkGetConstMacro(Label2, PixelType); itkSetMacro(Label2, PixelType); + itkSetMacro(VerboseFlag, bool); + itkGetConstMacro(VerboseFlag, bool); + itkBooleanMacro(VerboseFlag); + + itkSetMacro(LongFlag, bool); + itkGetConstMacro(LongFlag, bool); + itkBooleanMacro(LongFlag); + // I dont want to verify inputs information virtual void VerifyInputInformation() { } - + protected: LabelImageOverlapMeasureFilter(); virtual ~LabelImageOverlapMeasureFilter() {} - + PixelType m_BackgroundValue; PixelType m_Label1; PixelType m_Label2; ImagePointer m_Input1; ImagePointer m_Input2; + bool m_VerboseFlag; + bool m_LongFlag; virtual void GenerateOutputInformation(); virtual void GenerateInputRequestedRegion(); @@ -104,7 +114,7 @@ namespace clitk { private: LabelImageOverlapMeasureFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented - + }; // end class //-------------------------------------------------------------------- diff --git a/itk/clitkLabelImageOverlapMeasureFilter.txx b/itk/clitkLabelImageOverlapMeasureFilter.txx index 0375709..e62a1a9 100644 --- a/itk/clitkLabelImageOverlapMeasureFilter.txx +++ b/itk/clitkLabelImageOverlapMeasureFilter.txx @@ -1,7 +1,7 @@ /*========================================================================= Program: vv http://www.creatis.insa-lyon.fr/rio/vv - Authors belong to: + Authors belong to: - University of LYON http://www.universite-lyon.fr/ - Léon Bérard cancer center http://www.centreleonberard.fr - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr @@ -26,17 +26,19 @@ LabelImageOverlapMeasureFilter(): this->SetNumberOfRequiredInputs(2); SetLabel1(1); SetLabel2(1); - SetBackgroundValue(0); + m_BackgroundValue = 0; + SetVerboseFlag(false); + SetLongFlag(false); } //-------------------------------------------------------------------- //-------------------------------------------------------------------- template -void +void clitk::LabelImageOverlapMeasureFilter:: -GenerateOutputInformation() -{ +GenerateOutputInformation() +{ // DD("GenerateOutputInformation"); //ImagePointer input = dynamic_cast(itk::ProcessObject::GetInput(0)); // ImagePointer outputImage = this->GetOutput(0); @@ -47,9 +49,9 @@ GenerateOutputInformation() //-------------------------------------------------------------------- template -void +void clitk::LabelImageOverlapMeasureFilter:: -GenerateInputRequestedRegion() +GenerateInputRequestedRegion() { // Call default itk::ImageToImageFilter::GenerateInputRequestedRegion(); @@ -63,12 +65,10 @@ GenerateInputRequestedRegion() //-------------------------------------------------------------------- template -void +void clitk::LabelImageOverlapMeasureFilter:: -GenerateData() +GenerateData() { - // DD("GenerateData"); - // Get input pointer m_Input1 = dynamic_cast(itk::ProcessObject::GetInput(0)); m_Input2 = dynamic_cast(itk::ProcessObject::GetInput(1)); @@ -86,60 +86,14 @@ GenerateData() // Resize like the union ImagePointer input1 = clitk::ResizeImageLike(m_Input1, bbo, GetBackgroundValue()); ImagePointer input2 = clitk::ResizeImageLike(m_Input2, bbo, GetBackgroundValue()); - //DD(input1->GetLargestPossibleRegion()); - //DD(input2->GetLargestPossibleRegion()); - - // Compute overlap image - ImagePointer image_union = clitk::Clone(input1); - ImagePointer image_intersection = clitk::Clone(input1); - clitk::Or(image_union, input2, GetBackgroundValue()); - clitk::And(image_intersection, input2, GetBackgroundValue()); - - ImagePointer image_1NotIn2 = clitk::Clone(input1); - clitk::AndNot(image_1NotIn2, input2, GetBackgroundValue()); - - ImagePointer image_2NotIn1 = clitk::Clone(input2); - clitk::AndNot(image_2NotIn1, input1, GetBackgroundValue()); - - //writeImage(image_union, "union.mha"); - //writeImage(image_intersection, "intersection.mha"); - //writeImage(image_1NotIn2, "image_1NotIn2.mha"); - //writeImage(image_2NotIn1, "image_2NotIn1.mha"); - - // Compute size - typedef itk::LabelStatisticsImageFilter StatFilterType; - typename StatFilterType::Pointer statFilter = StatFilterType::New(); - statFilter->SetInput(image_union); - statFilter->SetLabelInput(image_union); - statFilter->Update(); - int u = statFilter->GetCount(GetLabel1()); - - statFilter->SetInput(image_intersection); - statFilter->SetLabelInput(image_intersection); - statFilter->Update(); - int inter = statFilter->GetCount(GetLabel1()); - - statFilter->SetInput(m_Input1); - statFilter->SetLabelInput(m_Input1); - statFilter->Update(); - int in1 = statFilter->GetCount(GetLabel1()); - - statFilter->SetInput(m_Input2); - statFilter->SetLabelInput(m_Input2); - statFilter->Update(); - int in2 = statFilter->GetCount(GetLabel1()); - - statFilter->SetInput(image_1NotIn2); - statFilter->SetLabelInput(image_1NotIn2); - statFilter->Update(); - int l1notIn2 = statFilter->GetCount(GetLabel1()); - - statFilter->SetInput(image_2NotIn1); - statFilter->SetLabelInput(image_2NotIn1); - statFilter->Update(); - int l2notIn1 = statFilter->GetCount(GetLabel1()); - - double dice = 2.0*(double)inter/(double)(in1+in2); + /* + if (GetVerboseFlag()) { + std::cout << "Resize images to the union of bounding boxes: " + << input1->GetLargestPossibleRegion().GetSize() << std::endl; + } + */ + + /* int width = 6; std::cout << std::setw(width) << in1 << " " << std::setw(width) << in2 << " " @@ -148,6 +102,38 @@ GenerateData() << std::setw(width) << l1notIn2 << " " << std::setw(width) << l2notIn1 << " " << std::setw(width) << dice << " "; //std::endl; + */ + + // Compute overlap, dice + typedef itk::LabelOverlapMeasuresImageFilter FilterType; + typename FilterType::Pointer diceFilter = FilterType::New(); + diceFilter->SetSourceImage(input1); + diceFilter->SetTargetImage(input2); + diceFilter->Update(); + + // Display information + if (!GetLongFlag()) { + if (GetVerboseFlag()) { + std::cout << "Dice : "; + } + std::cout << diceFilter->GetDiceCoefficient() << std::endl; + } + else { // long options + if (GetVerboseFlag()) { + std::cout << "Dice Jaccard Source Target Inter Union SrComp TarComp" << std::endl; + } + typename FilterType::MapType m = diceFilter->GetLabelSetMeasures(); + int width = 6; + std::cout << std::setw(width) << diceFilter->GetDiceCoefficient() << " " + << std::setw(width) << diceFilter->GetJaccardCoefficient() << " " + << std::setw(width) << m[m_Label1].m_Source << " " + << std::setw(width) << m[m_Label2].m_Target << " " + << std::setw(width) << m[m_Label1].m_Intersection << " " + << std::setw(width) << m[m_Label1].m_Union << " " + << std::setw(width) << m[m_Label1].m_SourceComplement << " " + << std::setw(width) << m[m_Label2].m_TargetComplement << " " + << std::endl; + } + } //-------------------------------------------------------------------- - diff --git a/itk/itkLabelOverlapMeasuresImageFilter.h b/itk/itkLabelOverlapMeasuresImageFilter.h deleted file mode 100644 index 978fed3..0000000 --- a/itk/itkLabelOverlapMeasuresImageFilter.h +++ /dev/null @@ -1,212 +0,0 @@ -/*========================================================================= - - Program: Insight Segmentation & Registration Toolkit - Module: $RCSfile: itkLabelOverlapMeasuresImageFilter.h,v $ - Language: C++ - Date: $Date: $ - Version: $Revision: $ - - 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 __itkLabelOverlapMeasuresImageFilter_h -#define __itkLabelOverlapMeasuresImageFilter_h - -#include "itkImageToImageFilter.h" -#include "itkFastMutexLock.h" -#include "itkNumericTraits.h" - -//#include "itk_hash_map.h" -#include "itksys/hash_map.hxx" - -namespace itk { - -/** \class LabelOverlapMeasuresImageFilter - * \brief Computes overlap measures between the set same set of labels of - * pixels of two images. Background is assumed to be 0. - * - * \sa LabelOverlapMeasuresImageFilter - * - * \ingroup MultiThreaded - */ -template -class ITK_EXPORT LabelOverlapMeasuresImageFilter : - public ImageToImageFilter -{ -public: - /** Standard Self typedef */ - typedef LabelOverlapMeasuresImageFilter Self; - typedef ImageToImageFilter Superclass; - typedef SmartPointer Pointer; - typedef SmartPointer ConstPointer; - - /** Method for creation through the object factory. */ - itkNewMacro( Self ); - - /** Runtime information support. */ - itkTypeMacro( LabelOverlapMeasuresImageFilter, ImageToImageFilter ); - - virtual void VerifyInputInformation() { } - - - /** Image related typedefs. */ - typedef TLabelImage LabelImageType; - typedef typename TLabelImage::Pointer LabelImagePointer; - typedef typename TLabelImage::ConstPointer LabelImageConstPointer; - - typedef typename TLabelImage::RegionType RegionType; - typedef typename TLabelImage::SizeType SizeType; - typedef typename TLabelImage::IndexType IndexType; - - typedef typename TLabelImage::PixelType LabelType; - - /** Type to use form computations. */ - typedef typename NumericTraits::RealType RealType; - - /** \class LabelLabelOverlapMeasuress - * \brief Metrics stored per label */ - class LabelSetMeasures - { - public: - // default constructor - LabelSetMeasures() - { - m_Source = 0; - m_Target = 0; - m_Union = 0; - m_Intersection = 0; - m_SourceComplement = 0; - m_TargetComplement = 0; - } - - // added for completeness - LabelSetMeasures& operator=( const LabelSetMeasures& l ) - { - m_Source = l.m_Source; - m_Target = l.m_Target; - m_Union = l.m_Union; - m_Intersection = l.m_Intersection; - m_SourceComplement = l.m_SourceComplement; - m_TargetComplement = l.m_TargetComplement; - } - - unsigned long m_Source; - unsigned long m_Target; - unsigned long m_Union; - unsigned long m_Intersection; - unsigned long m_SourceComplement; - unsigned long m_TargetComplement; - }; - - /** Type of the map used to store data per label */ - typedef itksys::hash_map MapType; - typedef typename MapType::iterator MapIterator; - typedef typename MapType::const_iterator MapConstIterator; - - /** Image related typedefs. */ - itkStaticConstMacro( ImageDimension, unsigned int, - TLabelImage::ImageDimension ); - - /** Set the source image. */ - void SetSourceImage( const LabelImageType * image ) - { this->SetNthInput( 0, const_cast( image ) ); } - - /** Set the target image. */ - void SetTargetImage( const LabelImageType * image ) - { this->SetNthInput( 1, const_cast( image ) ); } - - /** Get the source image. */ - const LabelImageType * GetSourceImage( void ) - { return this->GetInput( 0 ); } - - /** Get the target image. */ - const LabelImageType * GetTargetImage( void ) - { return this->GetInput( 1 ); } - - /** Get the label set measures */ - MapType GetLabelSetMeasures() - { return this->m_LabelSetMeasures; } - - /** - * tric overlap measures - */ - /** measures over all labels */ - RealType GetTotalOverlap(); - RealType GetUnionOverlap(); - RealType GetMeanOverlap(); - RealType GetVolumeSimilarity(); - RealType GetFalseNegativeError(); - RealType GetFalsePositiveError(); - /** measures over individual labels */ - RealType GetTargetOverlap( LabelType ); - RealType GetUnionOverlap( LabelType ); - RealType GetMeanOverlap( LabelType ); - RealType GetVolumeSimilarity( LabelType ); - RealType GetFalseNegativeError( LabelType ); - RealType GetFalsePositiveError( LabelType ); - /** alternative names */ - RealType GetJaccardCoefficient() - { return this->GetUnionOverlap(); } - RealType GetJaccardCoefficient( LabelType label ) - { return this->GetUnionOverlap( label ); } - RealType GetDiceCoefficient() - { return this->GetMeanOverlap(); } - RealType GetDiceCoefficient( LabelType label ) - { return this->GetMeanOverlap( label ); } - - -#ifdef ITK_USE_CONCEPT_CHECKING - /** Begin concept checking */ - itkConceptMacro( Input1HasNumericTraitsCheck, - ( Concept::HasNumericTraits ) ); - /** End concept checking */ -#endif - -protected: - LabelOverlapMeasuresImageFilter(); - ~LabelOverlapMeasuresImageFilter(){}; - void PrintSelf( std::ostream& os, Indent indent ) const; - - /** - * Pass the input through unmodified. Do this by setting the output to the - * source this by setting the output to the source image in the - * AllocateOutputs() method. - */ - void AllocateOutputs(); - - void BeforeThreadedGenerateData(); - - void AfterThreadedGenerateData(); - - /** Multi-thread version GenerateData. */ - void ThreadedGenerateData( const RegionType&, int ); - - // Override since the filter needs all the data for the algorithm - void GenerateInputRequestedRegion(); - - // Override since the filter produces all of its output - void EnlargeOutputRequestedRegion( DataObject *data ); - -private: - LabelOverlapMeasuresImageFilter( const Self& ); //purposely not implemented - void operator=( const Self& ); //purposely not implemented - - std::vector m_LabelSetMeasuresPerThread; - MapType m_LabelSetMeasures; - - SimpleFastMutexLock m_Mutex; - -}; // end of class - -} // end namespace itk - -#ifndef ITK_MANUAL_INSTANTIATION -#include "itkLabelOverlapMeasuresImageFilter.txx" -#endif - -#endif diff --git a/itk/itkLabelOverlapMeasuresImageFilter.txx b/itk/itkLabelOverlapMeasuresImageFilter.txx deleted file mode 100644 index ced277b..0000000 --- a/itk/itkLabelOverlapMeasuresImageFilter.txx +++ /dev/null @@ -1,437 +0,0 @@ -/*========================================================================= - - Program: Insight Segmentation & Registration Toolkit - Module: $RCSfile: itkLabelOverlapMeasuresImageFilter.txx,v $ - Language: C++ - Date: $Date: $ - Version: $Revision: $ - - 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 _itkLabelOverlapMeasuresImageFilter_txx -#define _itkLabelOverlapMeasuresImageFilter_txx - -#include "itkLabelOverlapMeasuresImageFilter.h" - -#include "itkImageRegionConstIterator.h" -#include "itkProgressReporter.h" - -namespace itk { - -#if defined(__GNUC__) && (__GNUC__ <= 2) //NOTE: This class needs a mutex for gnu 2.95 -/** Used for mutex locking */ -#define LOCK_HASHMAP this->m_Mutex.Lock() -#define UNLOCK_HASHMAP this->m_Mutex.Unlock() -#else -#define LOCK_HASHMAP -#define UNLOCK_HASHMAP -#endif - -template -LabelOverlapMeasuresImageFilter -::LabelOverlapMeasuresImageFilter() -{ - // this filter requires two input images - this->SetNumberOfRequiredInputs( 2 ); -} - -template -void -LabelOverlapMeasuresImageFilter -::GenerateInputRequestedRegion() -{ - Superclass::GenerateInputRequestedRegion(); - if( this->GetSourceImage() ) - { - LabelImagePointer source = const_cast - ( this->GetSourceImage() ); - source->SetRequestedRegionToLargestPossibleRegion(); - } - if( this->GetTargetImage() ) - { - LabelImagePointer target = const_cast - ( this->GetTargetImage() ); - target->SetRequestedRegionToLargestPossibleRegion(); - } -} - -template -void -LabelOverlapMeasuresImageFilter -::EnlargeOutputRequestedRegion( DataObject *data ) -{ - Superclass::EnlargeOutputRequestedRegion( data ); - data->SetRequestedRegionToLargestPossibleRegion(); -} - - -template -void -LabelOverlapMeasuresImageFilter -::AllocateOutputs() -{ - // Pass the source through as the output - LabelImagePointer image = - const_cast( this->GetSourceImage() ); - this->SetNthOutput( 0, image ); - - // Nothing that needs to be allocated for the remaining outputs -} - -template -void -LabelOverlapMeasuresImageFilter -::BeforeThreadedGenerateData() -{ - int numberOfThreads = this->GetNumberOfThreads(); - - // Resize the thread temporaries - this->m_LabelSetMeasuresPerThread.resize( numberOfThreads ); - - // Initialize the temporaries - for( int n = 0; n < numberOfThreads; n++ ) - { - this->m_LabelSetMeasuresPerThread[n].clear(); - } - - // Initialize the final map - this->m_LabelSetMeasures.clear(); -} - -template -void -LabelOverlapMeasuresImageFilter -::AfterThreadedGenerateData() -{ - // Run through the map for each thread and accumulate the set measures. - for( int n = 0; n < this->GetNumberOfThreads(); n++ ) - { - // iterate over the map for this thread - for( MapConstIterator threadIt = this->m_LabelSetMeasuresPerThread[n].begin(); - threadIt != this->m_LabelSetMeasuresPerThread[n].end(); - ++threadIt ) - { - // does this label exist in the cumulative stucture yet? - MapIterator mapIt = this->m_LabelSetMeasures.find( ( *threadIt ).first ); - if( mapIt == this->m_LabelSetMeasures.end() ) - { - // create a new entry - typedef typename MapType::value_type MapValueType; - mapIt = this->m_LabelSetMeasures.insert( MapValueType( - (*threadIt).first, LabelSetMeasures() ) ).first; - } - - // accumulate the information from this thread - (*mapIt).second.m_Source += (*threadIt).second.m_Source; - (*mapIt).second.m_Target += (*threadIt).second.m_Target; - (*mapIt).second.m_Union += (*threadIt).second.m_Union; - (*mapIt).second.m_Intersection += - (*threadIt).second.m_Intersection; - (*mapIt).second.m_SourceComplement += - (*threadIt).second.m_SourceComplement; - (*mapIt).second.m_TargetComplement += - (*threadIt).second.m_TargetComplement; - } // end of thread map iterator loop - } // end of thread loop -} - -template -void -LabelOverlapMeasuresImageFilter -::ThreadedGenerateData( const RegionType& outputRegionForThread, - int threadId ) -{ - ImageRegionConstIterator ItS( this->GetSourceImage(), - outputRegionForThread ); - ImageRegionConstIterator ItT( this->GetTargetImage(), - outputRegionForThread ); - - // support progress methods/callbacks - ProgressReporter progress( this, threadId, - 2*outputRegionForThread.GetNumberOfPixels() ); - - for( ItS.GoToBegin(), ItT.GoToBegin(); !ItS.IsAtEnd(); ++ItS, ++ItT ) - { - LabelType sourceLabel = ItS.Get(); - LabelType targetLabel = ItT.Get(); - - // is the label already in this thread? - MapIterator mapItS = - this->m_LabelSetMeasuresPerThread[threadId].find( sourceLabel ); - MapIterator mapItT = - this->m_LabelSetMeasuresPerThread[threadId].find( targetLabel ); - - if( mapItS == this->m_LabelSetMeasuresPerThread[threadId].end() ) - { - // create a new label set measures object - typedef typename MapType::value_type MapValueType; - LOCK_HASHMAP; - mapItS = this->m_LabelSetMeasuresPerThread[threadId].insert( - MapValueType( sourceLabel, LabelSetMeasures() ) ).first; - UNLOCK_HASHMAP; - } - - if( mapItT == this->m_LabelSetMeasuresPerThread[threadId].end() ) - { - // create a new label set measures object - typedef typename MapType::value_type MapValueType; - LOCK_HASHMAP; - mapItT = this->m_LabelSetMeasuresPerThread[threadId].insert( - MapValueType( targetLabel, LabelSetMeasures() ) ).first; - UNLOCK_HASHMAP; - } - - (*mapItS).second.m_Source++; - (*mapItT).second.m_Target++; - - if( sourceLabel == targetLabel ) - { - (*mapItS).second.m_Intersection++; - (*mapItS).second.m_Union++; - } - else - { - (*mapItS).second.m_Union++; - (*mapItT).second.m_Union++; - - (*mapItS).second.m_SourceComplement++; - (*mapItT).second.m_TargetComplement++; - } - - progress.CompletedPixel(); - } -} - -/** - * measures - */ -template -typename LabelOverlapMeasuresImageFilter::RealType -LabelOverlapMeasuresImageFilter -::GetTotalOverlap() -{ - RealType numerator = 0.0; - RealType denominator = 0.0; - for( MapIterator mapIt = this->m_LabelSetMeasures.begin(); - mapIt != this->m_LabelSetMeasures.end(); ++mapIt ) - { - // Do not include the background in the final value. - if( (*mapIt).first == NumericTraits::Zero ) - { - continue; - } - numerator += static_cast( (*mapIt).second.m_Intersection ); - denominator += static_cast( (*mapIt).second.m_Target ); - } - return ( numerator / denominator ); -} - -template -typename LabelOverlapMeasuresImageFilter::RealType -LabelOverlapMeasuresImageFilter -::GetTargetOverlap( LabelType label ) -{ - MapIterator mapIt = this->m_LabelSetMeasures.find( label ); - if( mapIt == this->m_LabelSetMeasures.end() ) - { - itkWarningMacro( "Label " << label << " not found." ); - return 0.0; - } - RealType value = - static_cast( (*mapIt).second.m_Intersection ) / - static_cast( (*mapIt).second.m_Target ); - return value; -} - -template -typename LabelOverlapMeasuresImageFilter::RealType -LabelOverlapMeasuresImageFilter -::GetUnionOverlap() -{ - RealType numerator = 0.0; - RealType denominator = 0.0; - for( MapIterator mapIt = this->m_LabelSetMeasures.begin(); - mapIt != this->m_LabelSetMeasures.end(); ++mapIt ) - { - // Do not include the background in the final value. - if( (*mapIt).first == NumericTraits::Zero ) - { - continue; - } - numerator += static_cast( (*mapIt).second.m_Intersection ); - denominator += static_cast( (*mapIt).second.m_Union ); - } - return ( numerator / denominator ); -} - -template -typename LabelOverlapMeasuresImageFilter::RealType -LabelOverlapMeasuresImageFilter -::GetUnionOverlap( LabelType label ) -{ - MapIterator mapIt = this->m_LabelSetMeasures.find( label ); - if( mapIt == this->m_LabelSetMeasures.end() ) - { - itkWarningMacro( "Label " << label << " not found." ); - return 0.0; - } - RealType value = - static_cast( (*mapIt).second.m_Intersection ) / - static_cast( (*mapIt).second.m_Union ); - return value; -} - -template -typename LabelOverlapMeasuresImageFilter::RealType -LabelOverlapMeasuresImageFilter -::GetMeanOverlap() -{ - RealType uo = this->GetUnionOverlap(); - return ( 2.0 * uo / ( 1.0 + uo ) ); -} - -template -typename LabelOverlapMeasuresImageFilter::RealType -LabelOverlapMeasuresImageFilter -::GetMeanOverlap( LabelType label ) -{ - RealType uo = this->GetUnionOverlap( label ); - return ( 2.0 * uo / ( 1.0 + uo ) ); -} - -template -typename LabelOverlapMeasuresImageFilter::RealType -LabelOverlapMeasuresImageFilter -::GetVolumeSimilarity() -{ - RealType numerator = 0.0; - RealType denominator = 0.0; - for( MapIterator mapIt = this->m_LabelSetMeasures.begin(); - mapIt != this->m_LabelSetMeasures.end(); ++mapIt ) - { - // Do not include the background in the final value. - if( (*mapIt).first == NumericTraits::Zero ) - { - continue; - } - numerator += ( ( static_cast( (*mapIt).second.m_Source ) - - static_cast( (*mapIt).second.m_Target ) ) ); - denominator += ( ( static_cast( (*mapIt).second.m_Source ) + - static_cast( (*mapIt).second.m_Target ) ) ); - } - return ( 2.0 * numerator / denominator ); -} - -template -typename LabelOverlapMeasuresImageFilter::RealType -LabelOverlapMeasuresImageFilter -::GetVolumeSimilarity( LabelType label ) -{ - MapIterator mapIt = this->m_LabelSetMeasures.find( label ); - if( mapIt == this->m_LabelSetMeasures.end() ) - { - itkWarningMacro( "Label " << label << " not found." ); - return 0.0; - } - RealType value = 2.0 * - ( static_cast( (*mapIt).second.m_Source ) - - static_cast( (*mapIt).second.m_Target ) ) / - ( static_cast( (*mapIt).second.m_Source ) + - static_cast( (*mapIt).second.m_Target ) ); - return value; -} - -template -typename LabelOverlapMeasuresImageFilter::RealType -LabelOverlapMeasuresImageFilter -::GetFalseNegativeError() -{ - RealType numerator = 0.0; - RealType denominator = 0.0; - for( MapIterator mapIt = this->m_LabelSetMeasures.begin(); - mapIt != this->m_LabelSetMeasures.end(); ++mapIt ) - { - // Do not include the background in the final value. - if( (*mapIt).first == NumericTraits::Zero ) - { - continue; - } - numerator += static_cast( (*mapIt).second.m_TargetComplement ); - denominator += static_cast( (*mapIt).second.m_Target ); - } - return ( numerator / denominator ); -} - -template -typename LabelOverlapMeasuresImageFilter::RealType -LabelOverlapMeasuresImageFilter -::GetFalseNegativeError( LabelType label ) -{ - MapIterator mapIt = this->m_LabelSetMeasures.find( label ); - if( mapIt == this->m_LabelSetMeasures.end() ) - { - itkWarningMacro( "Label " << label << " not found." ); - return 0.0; - } - RealType value = - static_cast( (*mapIt).second.m_TargetComplement ) / - static_cast( (*mapIt).second.m_Target ); - return value; -} - -template -typename LabelOverlapMeasuresImageFilter::RealType -LabelOverlapMeasuresImageFilter -::GetFalsePositiveError() -{ - RealType numerator = 0.0; - RealType denominator = 0.0; - for( MapIterator mapIt = this->m_LabelSetMeasures.begin(); - mapIt != this->m_LabelSetMeasures.end(); ++mapIt ) - { - // Do not include the background in the final value. - if( (*mapIt).first == NumericTraits::Zero ) - { - continue; - } - numerator += static_cast( (*mapIt).second.m_SourceComplement ); - denominator += static_cast( (*mapIt).second.m_Source ); - } - return ( numerator / denominator ); -} - -template -typename LabelOverlapMeasuresImageFilter::RealType -LabelOverlapMeasuresImageFilter -::GetFalsePositiveError( LabelType label ) -{ - MapIterator mapIt = this->m_LabelSetMeasures.find( label ); - if( mapIt == this->m_LabelSetMeasures.end() ) - { - itkWarningMacro( "Label " << label << " not found." ); - return 0.0; - } - RealType value = - static_cast( (*mapIt).second.m_SourceComplement ) / - static_cast( (*mapIt).second.m_Source ); - return value; -} - -template -void -LabelOverlapMeasuresImageFilter -::PrintSelf( std::ostream& os, Indent indent ) const -{ - Superclass::PrintSelf( os, indent ); - -} - - -}// end namespace itk -#endif diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 77f12f9..7a8fc13 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -134,12 +134,12 @@ IF (CLITK_BUILD_TOOLS) WRAP_GGO(clitkUnsharpMask_GGO_C clitkUnsharpMask.ggo) ADD_EXECUTABLE(clitkUnsharpMask clitkUnsharpMask.cxx ${clitkUnsharpMask_GGO_C}) - TARGET_LINK_LIBRARIES(clitkUnsharpMask clitkCommon ) + TARGET_LINK_LIBRARIES(clitkUnsharpMask clitkCommon ) SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkUnsharpMask) WRAP_GGO(clitkFooImage_GGO_C clitkFooImage.ggo) ADD_EXECUTABLE(clitkFooImage clitkFooImage.cxx ${clitkFooImage_GGO_C}) - TARGET_LINK_LIBRARIES(clitkFooImage clitkCommon ) + TARGET_LINK_LIBRARIES(clitkFooImage clitkCommon ) SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkFooImage) #WRAP_GGO(clitkMedianImageFilter_GGO_C clitkMedianImageFilter.ggo) @@ -195,7 +195,7 @@ IF (CLITK_BUILD_TOOLS) # ADD_EXECUTABLE(clitkExtractSlice clitkExtractSlice.cxx clitkExtractSliceGenericFilter.cxx ${clitkExtractSlice_GGO_C}) # TARGET_LINK_LIBRARIES(clitkExtractSlice clitkCommon) #SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkExtractSlice) - + WRAP_GGO(clitkFlipImage_GGO_C clitkFlipImage.ggo) ADD_EXECUTABLE(clitkFlipImage clitkFlipImage.cxx clitkFlipImageGenericFilter.cxx ${clitkFlipImage_GGO_C}) TARGET_LINK_LIBRARIES(clitkFlipImage clitkCommon) @@ -240,6 +240,11 @@ IF (CLITK_BUILD_TOOLS) TARGET_LINK_LIBRARIES(clitkTransformLandmarks clitkCommon) SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkTransformLandmarks) + WRAP_GGO(clitkDice_GGO_C clitkDice.ggo) + ADD_EXECUTABLE(clitkDice clitkDice.cxx ${clitkDice_GGO_C}) + TARGET_LINK_LIBRARIES(clitkDice clitkSegmentationGgoLib clitkCommon ${ITK_LIBRARIES} ) + SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkDice) + WRAP_GGO(clitkMaskLandmarks_GGO_C clitkMaskLandmarks.ggo) ADD_EXECUTABLE(clitkMaskLandmarks clitkMaskLandmarks.cxx ${clitkMaskLandmarks_GGO_C}) TARGET_LINK_LIBRARIES(clitkMaskLandmarks clitkCommon) @@ -249,7 +254,7 @@ IF (CLITK_BUILD_TOOLS) ADD_EXECUTABLE(clitkJacobianImage clitkJacobianImage.cxx clitkJacobianImageGenericFilter.cxx ${clitkJacobianImage_GGO_C}) TARGET_LINK_LIBRARIES(clitkJacobianImage clitkCommon) SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkJacobianImage) - + WRAP_GGO(clitkPadImage_GGO_C clitkPadImage.ggo) ADD_EXECUTABLE(clitkPadImage clitkPadImage.cxx clitkPadImageGenericFilter.cxx ${clitkPadImage_GGO_C}) TARGET_LINK_LIBRARIES(clitkPadImage clitkCommon) @@ -303,4 +308,3 @@ IF (CLITK_BUILD_TOOLS) INSTALL (TARGETS ${TOOLS_INSTALL} DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) ENDIF(CLITK_BUILD_TOOLS) - diff --git a/tools/clitkDice.cxx b/tools/clitkDice.cxx new file mode 100644 index 0000000..121bcb4 --- /dev/null +++ b/tools/clitkDice.cxx @@ -0,0 +1,47 @@ +/*========================================================================= + Program: vv http://www.creatis.insa-lyon.fr/rio/vv + + Authors belong to: + - University of LYON http://www.universite-lyon.fr/ + - Léon Bérard cancer center http://www.centreleonberard.fr + - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the copyright notices for more information. + + It is distributed under dual licence + + - BSD See included LICENSE.txt file + - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html +===========================================================================**/ + +// clitk +#include "clitkIO.h" +#include "clitkDice_ggo.h" + +#include "clitkLabelImageOverlapMeasureGenericFilter.h" + +//-------------------------------------------------------------------- +int main(int argc, char * argv[]) { + + // Init command line + GGO(clitkDice, args_info); + CLITK_INIT; + + // Filter + typedef clitk::LabelImageOverlapMeasureGenericFilter FilterType; + FilterType::Pointer filter = FilterType::New(); + + filter->SetArgsInfo(args_info); + + try { + filter->Update(); + } catch(std::runtime_error e) { + std::cout << e.what() << std::endl; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} // This is the end, my friend +//-------------------------------------------------------------------- diff --git a/tools/clitkDice.ggo b/tools/clitkDice.ggo new file mode 100644 index 0000000..3fcaeaf --- /dev/null +++ b/tools/clitkDice.ggo @@ -0,0 +1,17 @@ +#File clitkDice.ggo +package "clitkDice" +version "1.0" +purpose "Compute Dice between labeled images. Background must be 0." + +section "General options" +option "config" - "Config file" string no +option "verbose" v "Verbose" flag off +option "imagetypes" - "Display allowed image types" flag off +option "long" l "Long display (not only dice)" flag off + +section "Input" +option "input1" i "Input mask 1" string yes +option "input2" j "Input mask 2" string yes + +option "label1" - "Label in input1" int no default="1" +option "label2" - "Label in input2" int no default="1" diff --git a/tools/clitkLabelImageOverlapMeasureGenericFilter.h b/tools/clitkLabelImageOverlapMeasureGenericFilter.h new file mode 100644 index 0000000..05332ea --- /dev/null +++ b/tools/clitkLabelImageOverlapMeasureGenericFilter.h @@ -0,0 +1,76 @@ +/*========================================================================= + Program: vv http://www.creatis.insa-lyon.fr/rio/vv + + Authors belong to: + - University of LYON http://www.universite-lyon.fr/ + - Léon Bérard cancer center http://www.centreleonberard.fr + - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the copyright notices for more information. + + It is distributed under dual licence + + - BSD See included LICENSE.txt file + - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html +===========================================================================**/ + +#ifndef CLITKLABELIMAGEOVERLAPMEASUREGENERICFILTER_H +#define CLITKLABELIMAGEOVERLAPMEASUREGENERICFILTER_H + +// clitk +#include "clitkImageToImageGenericFilter.h" +#include "clitkLabelImageOverlapMeasureFilter.h" +#include "clitkBoundingBoxUtils.h" +#include "clitkCropLikeImageFilter.h" + +//-------------------------------------------------------------------- +namespace clitk +{ + + template + class ITK_EXPORT LabelImageOverlapMeasureGenericFilter: + public ImageToImageGenericFilter > + { + public: + //-------------------------------------------------------------------- + LabelImageOverlapMeasureGenericFilter(); + + //-------------------------------------------------------------------- + typedef ImageToImageGenericFilter > Superclass; + typedef LabelImageOverlapMeasureGenericFilter Self; + typedef itk::SmartPointer Pointer; + typedef itk::SmartPointer ConstPointer; + + //-------------------------------------------------------------------- + itkNewMacro(Self); + itkTypeMacro(LabelImageOverlapMeasureGenericFilter, LightObject); + + //-------------------------------------------------------------------- + void SetArgsInfo(const ArgsInfoType & a); + template + void SetOptionsFromArgsInfoToFilter(FilterType * f) ; + + //-------------------------------------------------------------------- + // Main function called each time the filter is updated + template + void UpdateWithInputImageType(); + + protected: + template void InitializeImageType(); + ArgsInfoType mArgsInfo; + + private: + LabelImageOverlapMeasureGenericFilter(const Self&); //purposely not implemented + void operator=(const Self&); //purposely not implemented + + };// end class + //-------------------------------------------------------------------- +} // end namespace clitk + +#ifndef ITK_MANUAL_INSTANTIATION +#include "clitkLabelImageOverlapMeasureGenericFilter.txx" +#endif + +#endif // #define CLITKRELATIVEPOSITIONANALYZERGENERICFILTER_H diff --git a/tools/clitkLabelImageOverlapMeasureGenericFilter.txx b/tools/clitkLabelImageOverlapMeasureGenericFilter.txx new file mode 100644 index 0000000..1ac11ee --- /dev/null +++ b/tools/clitkLabelImageOverlapMeasureGenericFilter.txx @@ -0,0 +1,102 @@ +/*========================================================================= + Program: vv http://www.creatis.insa-lyon.fr/rio/vv + + Authors belong to: + - University of LYON http://www.universite-lyon.fr/ + - Léon Bérard cancer center http://www.centreleonberard.fr + - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the copyright notices for more information. + + It is distributed under dual licence + + - BSD See included LICENSE.txt file + - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html + ===========================================================================**/ + +//-------------------------------------------------------------------- +template +clitk::LabelImageOverlapMeasureGenericFilter:: +LabelImageOverlapMeasureGenericFilter(): + ImageToImageGenericFilter("LabelImageOverlapMeasure") +{ + // Default values + cmdline_parser_clitkDice_init(&mArgsInfo); + //InitializeImageType<2>(); + InitializeImageType<3>(); +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +template +template +void clitk::LabelImageOverlapMeasureGenericFilter:: +InitializeImageType() +{ + ADD_IMAGE_TYPE(Dim, uchar); +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +template +void clitk::LabelImageOverlapMeasureGenericFilter:: +SetArgsInfo(const ArgsInfoType & a) +{ + mArgsInfo=a; + //this->SetIOVerbose(mArgsInfo.verbose_flag); + if (mArgsInfo.imagetypes_flag) this->PrintAvailableImageTypes(); + if (mArgsInfo.input1_given) this->AddInputFilename(mArgsInfo.input1_arg); + if (mArgsInfo.input2_given) this->AddInputFilename(mArgsInfo.input2_arg); +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +// Update with the number of dimensions and the pixeltype +//-------------------------------------------------------------------- +template +template +void clitk::LabelImageOverlapMeasureGenericFilter:: +SetOptionsFromArgsInfoToFilter(FilterType * f) +{ + f->SetLabel1(mArgsInfo.label1_arg); + f->SetLabel2(mArgsInfo.label2_arg); + f->SetVerboseFlag(mArgsInfo.verbose_flag); + f->SetLongFlag(mArgsInfo.long_flag); +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +// Update with the number of dimensions and the pixeltype +//-------------------------------------------------------------------- +template +template +void clitk::LabelImageOverlapMeasureGenericFilter:: +UpdateWithInputImageType() +{ + // Reading input + typename ImageType::Pointer input1 = this->template GetInput(0); + typename ImageType::Pointer input2 = this->template GetInput(1); + + // Create filter + typedef clitk::LabelImageOverlapMeasureFilter FilterType; + typename FilterType::Pointer filter = FilterType::New(); + + // Set global Options + filter->SetInput(0, input1); + filter->SetInput(1, input2); + SetOptionsFromArgsInfoToFilter(filter); + + // Go ! + filter->Update(); + + // Write/Save results + // typename ImageType::Pointer output = filter->GetOutput(); + // this->template SetNextOutput(output); +} +//--------------------------------------------------------------------