X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=itk%2FclitkSliceBySliceRelativePositionFilter.txx;h=f2452d872ad2258528c20301f0515f606648e323;hb=303195f7f56d1fa1256af63faeb4f452bf42faf2;hp=a8a79ec85599d681518edfe869da79598fcbec60;hpb=c361c11f0875b493f99ed8dca7796dd1bd4535f9;p=clitk.git diff --git a/itk/clitkSliceBySliceRelativePositionFilter.txx b/itk/clitkSliceBySliceRelativePositionFilter.txx index a8a79ec..f2452d8 100644 --- a/itk/clitkSliceBySliceRelativePositionFilter.txx +++ b/itk/clitkSliceBySliceRelativePositionFilter.txx @@ -19,21 +19,28 @@ // clitk #include "clitkSegmentationUtils.h" #include "clitkExtractSliceFilter.h" +#include "clitkResampleImageWithOptionsFilter.h" + +// itk +#include //-------------------------------------------------------------------- template clitk::SliceBySliceRelativePositionFilter:: SliceBySliceRelativePositionFilter(): - clitk::FilterBase(), - itk::ImageToImageFilter() + clitk::AddRelativePositionConstraintToLabelImageFilter() { - this->SetNumberOfRequiredInputs(2); SetDirection(2); - SetObjectBackgroundValue(0); - SetFuzzyThreshold(0.6); - SetOrientationType(RelPosFilterType::LeftTo); - SetIntermediateSpacing(10); - ResampleBeforeRelativePositionFilterOff(); + UniqueConnectedComponentBySliceOff(); + SetIgnoreEmptySliceObjectFlag(false); + UseASingleObjectConnectedComponentBySliceFlagOn(); + this->VerboseStepFlagOff(); + this->WriteStepFlagOff(); + this->SetCombineWithOrFlag(false); + CCLSelectionFlagOff(); + SetCCLSelectionDimension(0); + SetCCLSelectionDirection(1); + CCLSelectionIgnoreSingleCCLFlagOff(); } //-------------------------------------------------------------------- @@ -66,11 +73,19 @@ SetInputObject(const ImageType * image) template void clitk::SliceBySliceRelativePositionFilter:: -GenerateOutputInformation() -{ - ImagePointer input = dynamic_cast(itk::ProcessObject::GetInput(0)); - ImagePointer outputImage = this->GetOutput(0); - outputImage->SetRegions(input->GetLargestPossibleRegion()); +PrintOptions() +{ + DD(this->GetDirection()); + DD((int)this->GetObjectBackgroundValue()); + DDV(this->GetOrientationTypeString(), (uint)this->GetNumberOfAngles()); + DD(this->GetIntermediateSpacingFlag()); + DD(this->GetIntermediateSpacing()); + DD(this->GetFuzzyThreshold()); + DD(this->GetUniqueConnectedComponentBySlice()); + DD(this->GetAutoCropFlag()); + DD(this->GetInverseOrientationFlag()); + DD(this->GetRemoveObjectFlag()); + DD(this->GetCombineWithOrFlag()); } //-------------------------------------------------------------------- @@ -91,13 +106,17 @@ GenerateInputRequestedRegion() } //-------------------------------------------------------------------- - + //-------------------------------------------------------------------- template void clitk::SliceBySliceRelativePositionFilter:: -GenerateData() +GenerateOutputInformation() { + if (this->GetVerboseOptionFlag()) { + PrintOptions(); + } + // Get input pointer input = dynamic_cast(itk::ProcessObject::GetInput(0)); object = dynamic_cast(itk::ProcessObject::GetInput(1)); @@ -105,26 +124,24 @@ GenerateData() //-------------------------------------------------------------------- // Resample object to the same spacing than input if (!clitk::HaveSameSpacing(object, input)) { - StartNewStep("Resample object to the same spacing than input"); + this->StartNewStep("Resample object to the same spacing than input"); m_working_object = clitk::ResampleImageSpacing(object, input->GetSpacing()); - StopCurrentStep(m_working_object); + this->template StopCurrentStep(m_working_object); } else { - DD("no resampling"); m_working_object = object; } //-------------------------------------------------------------------- // Pad object to the same size than input if (!clitk::HaveSameSizeAndSpacing(m_working_object, input)) { - StartNewStep("Pad object to the same size than input"); - m_working_object = clitk::EnlargeImageLike(m_working_object, - input, - GetObjectBackgroundValue()); - StopCurrentStep(m_working_object); + this->StartNewStep("Pad object to the same size than input"); + m_working_object = clitk::ResizeImageLike(m_working_object, + input, + this->GetObjectBackgroundValue()); + this->template StopCurrentStep(m_working_object); } else { - DD("no pad"); } /* @@ -137,7 +154,7 @@ GenerateData() //-------------------------------------------------------------------- // Extract input slices - StartNewStep("Extract input slices"); + this->StartNewStep("Extract input slices"); typedef clitk::ExtractSliceFilter ExtractSliceFilterType; typename ExtractSliceFilterType::Pointer extractSliceFilter = ExtractSliceFilterType::New(); extractSliceFilter->SetInput(input); @@ -146,86 +163,143 @@ GenerateData() typedef typename ExtractSliceFilterType::SliceType SliceType; std::vector mInputSlices; extractSliceFilter->GetOutputSlices(mInputSlices); - StopCurrentStep(mInputSlices[0]); + this->template StopCurrentStep(mInputSlices[0]); //-------------------------------------------------------------------- // Extract object slices - StartNewStep("Extract object slices"); + this->StartNewStep("Extract object slices"); extractSliceFilter = ExtractSliceFilterType::New(); - extractSliceFilter->SetInput(object); + extractSliceFilter->SetInput(m_working_object);//object); extractSliceFilter->SetDirection(GetDirection()); extractSliceFilter->Update(); std::vector mObjectSlices; extractSliceFilter->GetOutputSlices(mObjectSlices); - StopCurrentStep(mObjectSlices[0]); + this->template StopCurrentStep(mObjectSlices[0]); //-------------------------------------------------------------------- // Perform slice by slice relative position - StartNewStep("Perform slice by slice relative position"); + this->StartNewStep("Perform slice by slice relative position"); for(unsigned int i=0; iGetOrigin()); - // writeImage(mInputSlices[i], "inp"+clitk::toString(i)+".mhd"); - - // Select main CC in each object slice : this should be the main bronchus - mObjectSlices[i] = Labelize(mObjectSlices[i], 0, true, 1); - mObjectSlices[i] = KeepLabels(mObjectSlices[i], 0, 1, 1, 1, true); - - // Relative position - typedef clitk::AddRelativePositionConstraintToLabelImageFilter RelPosFilterType; - typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New(); - relPosFilter->VerboseStepOff(); - relPosFilter->WriteStepOff(); - relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId()); - relPosFilter->SetInput(mInputSlices[i]); - relPosFilter->SetInputObject(mObjectSlices[i]); - relPosFilter->SetOrientationType(this->GetOrientationType()); - relPosFilter->SetIntermediateSpacing(this->GetIntermediateSpacing()); - relPosFilter->SetResampleBeforeRelativePositionFilter(this->GetResampleBeforeRelativePositionFilter()); - relPosFilter->SetFuzzyThreshold(this->GetFuzzyThreshold()); - relPosFilter->AutoCropOff(); // important ! because we join the slices after this loop - relPosFilter->Update(); - // writeImage(relPosFilter->GetOutput(), "inp-after"+clitk::toString(i)+".mhd"); - mInputSlices[i] = relPosFilter->GetOutput(); + + // Count the number of CCL (allow to ignore empty slice) + int nb=0; + mObjectSlices[i] = LabelizeAndCountNumberOfObjects(mObjectSlices[i], 0, true, 1, nb); + if ((!GetIgnoreEmptySliceObjectFlag()) || (nb!=0)) { + + // Select or not a single CCL ? + if (GetUseASingleObjectConnectedComponentBySliceFlag()) { + mObjectSlices[i] = KeepLabels(mObjectSlices[i], 0, 1, 1, 1, true); + } + + // Select a single according to a position if more than one CCL + if (GetCCLSelectionFlag()) { + // if several CCL, choose the most extrema according a direction, + // if not -> should we consider this slice ? + if (nb<2) { + if (GetCCLSelectionIgnoreSingleCCLFlag()) { + mObjectSlices[i] = SetBackground(mObjectSlices[i], mObjectSlices[i], + 1, this->GetBackgroundValue(), + true); + } + } + int dim = GetCCLSelectionDimension(); + int direction = GetCCLSelectionDirection(); + 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 GetCCLSelectionFlag = 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()); + for(int j=0; jGetNumberOfAngles(); j++) { + relPosFilter->AddOrientationTypeString(this->GetOrientationTypeString(j)); + } + relPosFilter->SetInverseOrientationFlag(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()); + 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 + } + */ + } } - DD(this->GetIntermediateSpacing()); - DD(this->GetResampleBeforeRelativePositionFilter()); - DD("End slice"); - typedef itk::JoinSeriesImageFilter JoinSeriesFilterType; - typename JoinSeriesFilterType::Pointer joinFilter = JoinSeriesFilterType::New(); - joinFilter->SetOrigin(input->GetOrigin()[GetDirection()]); - joinFilter->SetSpacing(input->GetSpacing()[GetDirection()]); - for(unsigned int i=0; iGetLargestPossibleRegion().GetIndex()); -// DD(mInputSlices[i]->GetLargestPossibleRegion().GetSize()); -// DD(mInputSlices[i]->GetRequestedRegion().GetIndex()); -// DD(mInputSlices[i]->GetRequestedRegion().GetSize()); - joinFilter->PushBackInput(mInputSlices[i]); - //SetInput(i, mInputSlices[i]); + // Join the slices + m_working_input = clitk::JoinSlices(mInputSlices, input, GetDirection()); + this->template StopCurrentStep(m_working_input); + + //-------------------------------------------------------------------- + // Step 7: autocrop + if (this->GetAutoCropFlag()) { + this->StartNewStep("Final AutoCrop"); + typedef clitk::AutoCropFilter CropFilterType; + typename CropFilterType::Pointer cropFilter = CropFilterType::New(); + cropFilter->SetInput(m_working_input); + cropFilter->ReleaseDataFlagOff(); + cropFilter->Update(); + m_working_input = cropFilter->GetOutput(); + this->template StopCurrentStep(m_working_input); } - DD("before update"); - joinFilter->Update(); - DD("after update"); - m_working_input = joinFilter->GetOutput(); - - // Update the origin - DD(input->GetSpacing()); - DD(input->GetOrigin()); - DD(mInputSlices[0]->GetSpacing()); - DD(mInputSlices[0]->GetOrigin()); - DD(m_working_input->GetSpacing()); - DD(m_working_input->GetOrigin()); - // typename ImageType::PointType origin = m_working_input->GetOrigin(); -// origin[GetDirection()] = input->GetOrigin()[GetDirection()]; -// m_working_input->SetOrigin(origin); -// DD(m_working_input->GetOrigin()); - StopCurrentStep(m_working_input); + // Update output info + this->GetOutput(0)->SetRegions(m_working_input->GetLargestPossibleRegion()); +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +template +void +clitk::SliceBySliceRelativePositionFilter:: +GenerateData() +{ + // Get input pointer //-------------------------------------------------------------------- //-------------------------------------------------------------------- // Final Step -> set output - this->SetNthOutput(0, m_working_input); + //this->SetNthOutput(0, m_working_input); + this->GraftOutput(m_working_input); return; } //--------------------------------------------------------------------