From ec6b1352366eb116c14afef0ffb4b26e82c0240d Mon Sep 17 00:00:00 2001 From: David Sarrut Date: Fri, 4 Nov 2011 10:26:11 +0100 Subject: [PATCH] Second version of rel pos analyzer --- itk/clitkRelativePositionAnalyzerFilter.h | 26 +-- itk/clitkRelativePositionAnalyzerFilter.txx | 169 +++++++----------- tools/clitkRelativePositionAnalyzer.ggo | 23 +-- ...kRelativePositionAnalyzerGenericFilter.txx | 24 +-- tools/clitkRelativePositionGenericFilter.txx | 2 +- 5 files changed, 101 insertions(+), 143 deletions(-) diff --git a/itk/clitkRelativePositionAnalyzerFilter.h b/itk/clitkRelativePositionAnalyzerFilter.h index 3554049..a41df8b 100644 --- a/itk/clitkRelativePositionAnalyzerFilter.h +++ b/itk/clitkRelativePositionAnalyzerFilter.h @@ -43,8 +43,6 @@ namespace clitk { template class RelativePositionAnalyzerFilter: - // public virtual clitk::FilterBase, - public clitk::FilterWithAnatomicalFeatureDatabaseManagement, public itk::ImageToImageFilter { @@ -81,6 +79,9 @@ namespace clitk { void SetInputObject(const ImageType * image); void SetInputTarget(const ImageType * image); + // Input + // supportname, objectname multiple targetname + // Options itkGetConstMacro(BackgroundValue, PixelType); itkSetMacro(BackgroundValue, PixelType); @@ -88,12 +89,12 @@ namespace clitk { itkGetConstMacro(ForegroundValue, PixelType); itkSetMacro(ForegroundValue, PixelType); + clitk::RelativePositionDirectionType & GetDirection() { return m_Direction; } + void SetDirection(clitk::RelativePositionDirectionType & d) { m_Direction = d; } + itkGetConstMacro(NumberOfBins, int); itkSetMacro(NumberOfBins, int); - itkGetConstMacro(NumberOfAngles, int); - itkSetMacro(NumberOfAngles, int); - itkGetConstMacro(AreaLossTolerance, double); itkSetMacro(AreaLossTolerance, double); @@ -102,14 +103,14 @@ namespace clitk { itkGetConstMacro(SizeWithThreshold, int); itkGetConstMacro(SizeWithReverseThreshold, int); - std::vector & GetListOfInformation() { return m_ListOfInformation; } - std::vector & GetListOfOrientation() { return m_ListOfOrientation; } + itkGetConstMacro(Info, clitk::RelativePositionInformationType); + itkGetConstMacro(InfoReverse, clitk::RelativePositionInformationType); // For debug void PrintOptions(); // Print output - void Print(std::string s=" ", std::ostream & os=std::cout); + void Print(std::ostream & os=std::cout); // I dont want to verify inputs information virtual void VerifyInputInformation() { } @@ -128,22 +129,21 @@ namespace clitk { ImagePointer m_Support; ImagePointer m_Object; ImagePointer m_Target; - int m_NumberOfAngles; int m_NumberOfBins; double m_AreaLossTolerance; int m_SupportSize; int m_TargetSize; int m_SizeWithReverseThreshold; int m_SizeWithThreshold; - std::vector m_ListOfAngles; - std::vector m_ListOfInformation; - std::vector m_ListOfOrientation; + clitk::RelativePositionDirectionType m_Direction; + clitk::RelativePositionInformationType m_Info; + clitk::RelativePositionInformationType m_InfoReverse; virtual void GenerateOutputInformation(); virtual void GenerateData(); typename FloatImageType::Pointer - ComputeFuzzyMap(ImageType * object, ImageType * target, double angle); + ComputeFuzzyMap(ImageType * object, ImageType * target, ImageType * support, double angle); void ComputeOptimalThresholds(FloatImageType * map, ImageType * target, int bins, double tolerance, diff --git a/itk/clitkRelativePositionAnalyzerFilter.txx b/itk/clitkRelativePositionAnalyzerFilter.txx index c8d126a..8313766 100644 --- a/itk/clitkRelativePositionAnalyzerFilter.txx +++ b/itk/clitkRelativePositionAnalyzerFilter.txx @@ -20,18 +20,13 @@ template clitk::RelativePositionAnalyzerFilter:: RelativePositionAnalyzerFilter(): - // clitk::FilterBase(), - clitk::FilterWithAnatomicalFeatureDatabaseManagement(), itk::ImageToImageFilter() { - this->SetNumberOfRequiredInputs(3); // support, object, target - VerboseFlagOff(); + this->SetNumberOfRequiredInputs(3); // Input : support, object, target SetBackgroundValue(0); SetForegroundValue(1); SetNumberOfBins(100); - SetNumberOfAngles(4); SetAreaLossTolerance(0.01); - m_ListOfAngles.clear(); SetSupportSize(0); SetTargetSize(0); SetSizeWithThreshold(0); @@ -106,20 +101,16 @@ void clitk::RelativePositionAnalyzerFilter:: GenerateData() { - this->LoadAFDB(); + static const unsigned int dim = ImageType::ImageDimension; - // Get input pointer - m_Support = dynamic_cast(itk::ProcessObject::GetInput(0)); + ImagePointer temp = dynamic_cast(itk::ProcessObject::GetInput(0)); m_Object = dynamic_cast(itk::ProcessObject::GetInput(1)); m_Target = dynamic_cast(itk::ProcessObject::GetInput(2)); - static const unsigned int dim = ImageType::ImageDimension; - // Remove object from support + // Remove object from support (keep initial image) + m_Support = clitk::Clone(temp); clitk::AndNot(m_Support, m_Object, GetBackgroundValue()); - // Resize object like target (to enable substraction later) - ImagePointer objectLikeTarget = clitk::ResizeImageLike(m_Object, m_Target, GetBackgroundValue()); - // Define filter to compute statics on mask image typedef itk::LabelStatisticsImageFilter StatFilterType; typename StatFilterType::Pointer statFilter = StatFilterType::New(); @@ -139,82 +130,63 @@ GenerateData() SetTargetSize(statFilter->GetCount(GetForegroundValue())); // DD(GetTargetSize()); - // Build the list of tested orientations - m_ListOfAngles.clear(); - for(uint i=0; i180) a = 180-a; - m_ListOfAngles.push_back(clitk::deg2rad(a)); - RelativePositionOrientationType r; - r.angle1 = clitk::deg2rad(a); - r.angle2 = 0; - r.notFlag = false; - m_ListOfOrientation.push_back(r); - r.notFlag = true; - m_ListOfOrientation.push_back(r); - } - - // Loop on all orientations + // int bins = GetNumberOfBins(); double tolerance = GetAreaLossTolerance(); - for(int i=0; i(map, "fuzzy_"+toString(i)+".mha"); - - // Compute the optimal thresholds (direct and inverse) - double mThreshold=0.0; - double mReverseThreshold=1.0; - ComputeOptimalThresholds(map, m_Target, bins, tolerance, mThreshold, mReverseThreshold); - // Use the threshold to compute new support - int s1 = GetSupportSize(); - // DD(mThreshold); - // DD(mReverseThreshold); - if (mThreshold > 0.0) { - ImagePointer support1 = - clitk::SliceBySliceRelativePosition(m_Support, m_Object, 2, - mThreshold, - m_ListOfAngles[i],false, - false, -1, true, false); - // writeImage(support1, "sup_"+toString(i)+".mha"); - // Compute the new support size - statFilter->SetInput(support1); - statFilter->SetLabelInput(support1); - statFilter->Update(); - s1 = statFilter->GetCount(GetForegroundValue()); - } - - int s2 = GetSupportSize(); - if (mReverseThreshold < 1.0) { - // DD(m_ListOfAngles[1]); - ImagePointer support2 = - clitk::SliceBySliceRelativePosition(m_Support, m_Object, 2, - mReverseThreshold, - m_ListOfAngles[i],true, - false, -1, true, false); - writeImage(support2, "sup_rev_"+toString(i)+".mha"); - // Compute the new support size - statFilter = StatFilterType::New(); - statFilter->SetInput(support2); - statFilter->SetLabelInput(support2); - statFilter->Update(); - s2 = statFilter->GetCount(GetForegroundValue()); - } - - // Set results values - RelativePositionInformationType r; - r.threshold = mThreshold; - r.sizeAfterThreshold = s1; // DD(s1); - r.sizeBeforeThreshold = GetSupportSize(); - r.sizeReference = GetTargetSize(); - m_ListOfInformation.push_back(r); - - r.threshold = mReverseThreshold; - r.sizeAfterThreshold = s2; // DD(s2); - m_ListOfInformation.push_back(r); - // Print(); - } // end loop on orientations + // Compute Fuzzy map + double angle = GetDirection().angle1; + typename FloatImageType::Pointer map = ComputeFuzzyMap(m_Object, m_Target, m_Support, angle); + writeImage(map, "fuzzy_"+toString(clitk::rad2deg(angle))+".mha"); + + // Compute the optimal thresholds (direct and inverse) + double mThreshold=0.0; + double mReverseThreshold=1.0; + ComputeOptimalThresholds(map, m_Target, bins, tolerance, mThreshold, mReverseThreshold); + + // Use the threshold to compute new support + int s1 = GetSupportSize(); + if (mThreshold > 0.0) { + ImagePointer support1 = + clitk::SliceBySliceRelativePosition(m_Support, m_Object, 2, + mThreshold, + angle,false, // inverseFlag + false, // uniqueConnectedComponent + -1, true, + false);//singleObjectCCL + // Compute the new support size + statFilter->SetInput(support1); + statFilter->SetLabelInput(support1); + statFilter->Update(); + s1 = statFilter->GetCount(GetForegroundValue()); + } + + int s2 = GetSupportSize(); + if (mReverseThreshold < 1.0) { + ImagePointer support2 = + clitk::SliceBySliceRelativePosition(m_Support, m_Object, 2, + mReverseThreshold, + angle,true,// inverseFlag + false, // uniqueConnectedComponent + -1, true, + false); //singleObjectCCL + // Compute the new support size + statFilter = StatFilterType::New(); + statFilter->SetInput(support2); + statFilter->SetLabelInput(support2); + statFilter->Update(); + s2 = statFilter->GetCount(GetForegroundValue()); + } + + // Set results values + m_Info.threshold = mThreshold; + m_Info.sizeAfterThreshold = s1; + m_Info.sizeBeforeThreshold = GetSupportSize(); + m_Info.sizeReference = GetTargetSize(); + m_InfoReverse.threshold = mReverseThreshold; + m_InfoReverse.sizeAfterThreshold = s2; + m_InfoReverse.sizeBeforeThreshold = GetSupportSize(); + m_InfoReverse.sizeReference = GetTargetSize(); } //-------------------------------------------------------------------- @@ -223,24 +195,27 @@ GenerateData() template typename clitk::RelativePositionAnalyzerFilter::FloatImageType::Pointer clitk::RelativePositionAnalyzerFilter:: -ComputeFuzzyMap(ImageType * object, ImageType * target, double angle) +ComputeFuzzyMap(ImageType * object, ImageType * target, ImageType * support, double angle) { typedef clitk::SliceBySliceRelativePositionFilter SliceRelPosFilterType; typedef typename SliceRelPosFilterType::FloatImageType FloatImageType; typename SliceRelPosFilterType::Pointer sliceRelPosFilter = SliceRelPosFilterType::New(); sliceRelPosFilter->VerboseStepFlagOff(); sliceRelPosFilter->WriteStepFlagOff(); - sliceRelPosFilter->SetInput(target); + sliceRelPosFilter->SetInput(support); sliceRelPosFilter->SetInputObject(object); sliceRelPosFilter->SetDirection(2); sliceRelPosFilter->SetIntermediateSpacingFlag(false); //sliceRelPosFilter->AddOrientationTypeString(orientation); - sliceRelPosFilter->AddAngles(angle, 0.0); + sliceRelPosFilter->AddAnglesInRad(angle, 0.0); sliceRelPosFilter->FuzzyMapOnlyFlagOn(); // do not threshold, only compute the fuzzy map // sliceRelPosFilter->PrintOptions(); sliceRelPosFilter->Update(); typename FloatImageType::Pointer map = sliceRelPosFilter->GetFuzzyMap(); + // Resize map like object to allow SetBackground + map = clitk::ResizeImageLike(map, object, GetBackgroundValue()); + // Remove initial object from the fuzzy map map = clitk::SetBackground(map, object, GetForegroundValue(), 0.0, true); @@ -310,17 +285,3 @@ ComputeOptimalThresholds(FloatImageType * map, ImageType * target, int bins, dou } //-------------------------------------------------------------------- - -//-------------------------------------------------------------------- -template -void -clitk::RelativePositionAnalyzerFilter:: -Print(std::string s, std::ostream & os) -{ - for(int i=0; i void clitk::RelativePositionAnalyzerGenericFilter:: SetOptionsFromArgsInfoToFilter(FilterType * f) { - f->SetAFDBFilename(mArgsInfo.afdb_arg); f->SetNumberOfBins(mArgsInfo.bins_arg); - f->SetNumberOfAngles(mArgsInfo.nb_arg); f->SetAreaLossTolerance(mArgsInfo.tol_arg); + clitk::RelativePositionDirectionType d; + if (mArgsInfo.angle1_given) d.angle1 = clitk::deg2rad(mArgsInfo.angle1_arg); + if (mArgsInfo.angle2_given) d.angle2 = clitk::deg2rad(mArgsInfo.angle2_arg); + if (mArgsInfo.inverse_given) d.notFlag = clitk::deg2rad(mArgsInfo.inverse_flag); + f->SetDirection(d); } +//-------------------------------------------------------------------- + //-------------------------------------------------------------------- // Update with the number of dimensions and the pixeltype @@ -97,19 +102,8 @@ UpdateWithInputImageType() filter->Update(); // Display output - std::string s; - if (mArgsInfo.afdb_given) { - NewAFDB(afdb, mArgsInfo.afdb_arg); - std::string patient = afdb->GetTagValue("PatientID"); - std::string support; - std::string object; - if (mArgsInfo.objectName_given) object = mArgsInfo.objectName_arg; - else object = mArgsInfo.object_arg; - if (mArgsInfo.supportName_given) support = mArgsInfo.supportName_arg; - else support = mArgsInfo.support_arg; - s = patient+" "+support+" "+object+" "; - } - filter->Print(s, std::cout); + filter->GetInfo().Println(); + filter->GetInfoReverse().Println(); } //-------------------------------------------------------------------- diff --git a/tools/clitkRelativePositionGenericFilter.txx b/tools/clitkRelativePositionGenericFilter.txx index 4114e55..8af353a 100644 --- a/tools/clitkRelativePositionGenericFilter.txx +++ b/tools/clitkRelativePositionGenericFilter.txx @@ -144,7 +144,7 @@ UpdateWithInputImageType() filter->SetInput(input); filter->SetInputObject(object); if (mArgsInfo.angle1_given && mArgsInfo.angle2_given) - filter->AddAngles(mArgsInfo.angle1_arg, mArgsInfo.angle2_arg); + filter->AddAnglesInDeg(mArgsInfo.angle1_arg, mArgsInfo.angle2_arg); SetOptionsFromArgsInfoToFilter(filter); // Go ! -- 2.47.1