X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=itk%2FclitkSliceBySliceRelativePositionFilter.txx;h=c3361ca5090e24bfd4ae4766f5c1b7f6b02fd7a4;hb=4f6aadc0552db99c03057d4aa40a7fc4a1697350;hp=e3801024bf389f93a0188ae367afb6ae168107a7;hpb=72375037f90c596a034b2ebe5e54e209e7b45511;p=clitk.git diff --git a/itk/clitkSliceBySliceRelativePositionFilter.txx b/itk/clitkSliceBySliceRelativePositionFilter.txx index e380102..c3361ca 100644 --- a/itk/clitkSliceBySliceRelativePositionFilter.txx +++ b/itk/clitkSliceBySliceRelativePositionFilter.txx @@ -17,6 +17,7 @@ ======================================================================-====*/ // clitk +#include "clitkCropLikeImageFilter.h" #include "clitkSegmentationUtils.h" #include "clitkExtractSliceFilter.h" #include "clitkResampleImageWithOptionsFilter.h" @@ -31,8 +32,16 @@ SliceBySliceRelativePositionFilter(): clitk::AddRelativePositionConstraintToLabelImageFilter() { SetDirection(2); - UniqueConnectedComponentBySliceOff(); - SetIgnoreEmptySliceObject(false); + UniqueConnectedComponentBySliceFlagOff(); + SetIgnoreEmptySliceObjectFlag(false); + UseTheLargestObjectCCLFlagOff(); + this->VerboseStepFlagOff(); + this->WriteStepFlagOff(); + this->SetCombineWithOrFlag(false); + ObjectCCLSelectionFlagOff(); + SetObjectCCLSelectionDimension(0); + SetObjectCCLSelectionDirection(1); + ObjectCCLSelectionIgnoreSingleCCLFlagOff(); } //-------------------------------------------------------------------- @@ -65,19 +74,28 @@ SetInputObject(const ImageType * image) template void clitk::SliceBySliceRelativePositionFilter:: -PrintOptions() +PrintOptions(std::ostream & os) { - DD(this->GetDirection()); - DD((int)this->GetObjectBackgroundValue()); - DDV(this->GetOrientationTypeString(), (uint)this->GetNumberOfAngles()); - DD(this->GetResampleBeforeRelativePositionFilter()); - DD(this->GetIntermediateSpacing()); - DD(this->GetFuzzyThreshold()); - DD(this->GetUniqueConnectedComponentBySlice()); - DD(this->GetAutoCropFlag()); - DD(this->GetInverseOrientationFlag()); - DD(this->GetRemoveObjectFlag()); - DD(this->GetCombineWithOrFlag()); + os << "Slice direction = " << this->GetDirection() << std::endl + << "BG value = " << this->GetBackgroundValue() << std::endl; + for(int i=0; iGetNumberOfAngles(); i++) { + os << "Orientation = " << this->GetOrientationTypeString()[i] << std::endl; + os << "Angles = " << clitk::rad2deg(this->GetAngle1(i)) + << " " << clitk::rad2deg(this->GetAngle2(i)) << std::endl; + } + os << "InverseOrientationFlag = " << this->GetInverseOrientationFlag() << std::endl + << "SpacingFlag = " << this->GetIntermediateSpacingFlag() << std::endl + << "Spacing = " << this->GetIntermediateSpacing() << std::endl + << "FuzzyThreshold = " << this->GetFuzzyThreshold() << std::endl + << "UniqueConnectedComponentBySliceFlag = " << this->GetUniqueConnectedComponentBySliceFlag() << std::endl + << "AutoCropFlag = " << this->GetAutoCropFlag() << std::endl + << "RemoveObjectFlag= " << this->GetRemoveObjectFlag() << std::endl + << "CombineWithOrFlag = " << this->GetCombineWithOrFlag() << std::endl + << "UseTheLargestObjectCCLFlag = " << this->GetUseTheLargestObjectCCLFlag() << std::endl + << "ObjectCCLSelectionFlag = " << this->GetObjectCCLSelectionFlag() << std::endl + << "ObjectCCLSelectionDimension = " << this->GetObjectCCLSelectionDimension() << std::endl + << "ObjectCCLSelectionIgnoreSingleCCLFlag = " << this->GetObjectCCLSelectionIgnoreSingleCCLFlag() << std::endl + << "IgnoreEmptySliceObjectFlag = " << this->GetIgnoreEmptySliceObjectFlag() << std::endl; } //-------------------------------------------------------------------- @@ -168,48 +186,137 @@ GenerateOutputInformation() extractSliceFilter->GetOutputSlices(mObjectSlices); this->template StopCurrentStep(mObjectSlices[0]); + //-------------------------------------------------------------------- + // Prepare fuzzy slices (if needed) + std::vector mFuzzyMapSlices; + mFuzzyMapSlices.resize(mInputSlices.size()); + //-------------------------------------------------------------------- // Perform slice by slice relative position this->StartNewStep("Perform slice by slice relative position"); for(unsigned int i=0; i(mObjectSlices[i], 0, true, 1, nb); - if ((!GetIgnoreEmptySliceObject()) || (nb!=0)) { - mObjectSlices[i] = KeepLabels(mObjectSlices[i], 0, 1, 1, 1, true); - - // Relative position - typedef clitk::AddRelativePositionConstraintToLabelImageFilter RelPosFilterType; - typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New(); - relPosFilter->VerboseStepFlagOff(); - relPosFilter->WriteStepFlagOff(); - relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId()); - relPosFilter->SetBackgroundValue(this->GetBackgroundValue()); - relPosFilter->SetInput(mInputSlices[i]); - relPosFilter->SetInputObject(mObjectSlices[i]); - relPosFilter->SetRemoveObjectFlag(this->GetRemoveObjectFlag()); - for(int j=0; jGetNumberOfAngles(); j++) { - relPosFilter->AddOrientationTypeString(this->GetOrientationTypeString(j)); + + // If no object and empty slices : + if ((nb==0) && (this->GetFuzzyMapOnlyFlag())) { + typename FloatSliceType::Pointer one = FloatSliceType::New(); + one->CopyInformation(mObjectSlices[0]); + one->SetRegions(mObjectSlices[0]->GetLargestPossibleRegion()); + one->Allocate(); + one->FillBuffer(2.0); + mFuzzyMapSlices[i] = one; + } + else { + if ((!GetIgnoreEmptySliceObjectFlag()) || (nb!=0)) { + + // Select or not a single CCL ? + if (GetUseTheLargestObjectCCLFlag()) { + mObjectSlices[i] = KeepLabels(mObjectSlices[i], 0, 1, 1, 1, true); + } + + // Select a single according to a position if more than one CCL + if (GetObjectCCLSelectionFlag()) { + // if several CCL, choose the most extrema according a direction, + // if not -> should we consider this slice ? + if (nb<2) { + if (GetObjectCCLSelectionIgnoreSingleCCLFlag()) { + mObjectSlices[i] = SetBackground(mObjectSlices[i], mObjectSlices[i], + 1, this->GetBackgroundValue(), + true); + } + } + int dim = GetObjectCCLSelectionDimension(); + int direction = GetObjectCCLSelectionDirection(); + std::vector centroids; + ComputeCentroids(mObjectSlices[i], this->GetBackgroundValue(), centroids); + uint index=1; + for(uint j=1; j centroids[index][dim]) index = j; + } + else { + if (centroids[j][dim] < centroids[index][dim]) index = j; + } + } + for(uint v=1; v(mObjectSlices[i], mObjectSlices[i], + (char)v, this->GetBackgroundValue(), + true); + } + } + } // end GetbjectCCLSelectionFlag = true + + // Relative position + typedef clitk::AddRelativePositionConstraintToLabelImageFilter RelPosFilterType; + typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New(); + + relPosFilter->VerboseStepFlagOff(); + relPosFilter->WriteStepFlagOff(); + relPosFilter->SetBackgroundValue(this->GetBackgroundValue()); + relPosFilter->SetInput(mInputSlices[i]); + relPosFilter->SetInputObject(mObjectSlices[i]); + relPosFilter->SetRemoveObjectFlag(this->GetRemoveObjectFlag()); + // This flag (InverseOrientation) *must* be set before + // AddOrientation because AddOrientation can change it. + relPosFilter->SetInverseOrientationFlag(this->GetInverseOrientationFlag()); + for(int j=0; jGetNumberOfAngles(); j++) { + // relPosFilter->AddOrientationTypeString(this->GetOrientationTypeString(j)); + relPosFilter->AddAngles(this->GetAngle1(j), this->GetAngle2(j)); + // DD(this->GetOrientationTypeString(j)); + } + // DD(this->GetInverseOrientationFlag()); + //relPosFilter->SetOrientationType(this->GetOrientationType()); + relPosFilter->SetIntermediateSpacing(this->GetIntermediateSpacing()); + relPosFilter->SetIntermediateSpacingFlag(this->GetIntermediateSpacingFlag()); + relPosFilter->SetFuzzyThreshold(this->GetFuzzyThreshold()); + relPosFilter->AutoCropFlagOff(); // important ! because we join the slices after this loop + relPosFilter->SetCombineWithOrFlag(this->GetCombineWithOrFlag()); + + // should we stop after fuzzy map ? + relPosFilter->SetFuzzyMapOnlyFlag(this->GetFuzzyMapOnlyFlag()); + + // Go ! + relPosFilter->Update(); + + // If we stop after the fuzzy map, store the fuzzy slices + if (this->GetFuzzyMapOnlyFlag()) { + mFuzzyMapSlices[i] = relPosFilter->GetFuzzyMap(); + // writeImage(mFuzzyMapSlices[i], "slice_"+toString(i)+".mha"); + } + else { + mInputSlices[i] = relPosFilter->GetOutput(); + // Select main CC if needed + if (GetUniqueConnectedComponentBySliceFlag()) { + mInputSlices[i] = Labelize(mInputSlices[i], 0, true, 1); + mInputSlices[i] = KeepLabels(mInputSlices[i], 0, 1, 1, 1, true); + } + + } + } - relPosFilter->SetInverseOrientationFlag(this->GetInverseOrientationFlag()); - //relPosFilter->SetOrientationType(this->GetOrientationType()); - relPosFilter->SetIntermediateSpacing(this->GetIntermediateSpacing()); - relPosFilter->SetResampleBeforeRelativePositionFilter(this->GetResampleBeforeRelativePositionFilter()); - relPosFilter->SetFuzzyThreshold(this->GetFuzzyThreshold()); - relPosFilter->AutoCropFlagOff(); // important ! because we join the slices after this loop - relPosFilter->SetCombineWithOrFlag(this->GetCombineWithOrFlag()); - relPosFilter->Update(); - mInputSlices[i] = relPosFilter->GetOutput(); - - // Select main CC if needed - if (GetUniqueConnectedComponentBySlice()) { - mInputSlices[i] = Labelize(mInputSlices[i], 0, true, 1); - mInputSlices[i] = KeepLabels(mInputSlices[i], 0, 1, 1, 1, true); + /* + // Select unique CC according to the most in a given direction + if (GetUniqueConnectedComponentBySliceAccordingToADirection()) { + int nb; + mInputSlices[i] = LabelizeAndCountNumberOfObjects(mInputSlices[i], 0, true, 1, nb); + std::vector & centroids; + ComputeCentroids } - + */ } } + // Join the fuzzy map if needed + if (this->GetFuzzyMapOnlyFlag()) { + this->m_FuzzyMap = clitk::JoinSlices(mFuzzyMapSlices, input, GetDirection()); + this->template StopCurrentStep(this->m_FuzzyMap); + return; + } + // Join the slices m_working_input = clitk::JoinSlices(mInputSlices, input, GetDirection()); this->template StopCurrentStep(m_working_input); @@ -244,6 +351,7 @@ GenerateData() //-------------------------------------------------------------------- // Final Step -> set output //this->SetNthOutput(0, m_working_input); + if (this->GetFuzzyMapOnlyFlag()) return; // no output in this case this->GraftOutput(m_working_input); return; }