/*========================================================================= 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 CLITKFILLMASKFILTER_TXX #define CLITKFILLMASKFILTER_TXX //-------------------------------------------------------------------- template clitk::FillMaskFilter::FillMaskFilter(): itk::ImageToImageFilter() { // Default global options this->SetNumberOfRequiredInputs(1); ResetDirections(); } //-------------------------------------------------------------------- //-------------------------------------------------------------------- template void clitk::FillMaskFilter:: AddDirection(int dir) { m_Directions.push_back(dir); } //-------------------------------------------------------------------- //-------------------------------------------------------------------- template void clitk::FillMaskFilter:: ResetDirections() { m_Directions.clear(); } //-------------------------------------------------------------------- //-------------------------------------------------------------------- template template void clitk::FillMaskFilter:: SetOptionsFromArgsInfo(ArgsInfoType & mArgsInfo) { ResetDirections(); for(uint i=0; i template void clitk::FillMaskFilter:: SetOptionsToArgsInfo(ArgsInfoType & mArgsInfo) { mArgsInfo.dir_arg = new int[m_Directions.size()]; mArgsInfo.dir_given = m_Directions.size(); for(uint i=0; i void clitk::FillMaskFilter:: GenerateData() { InputImagePointer input = dynamic_cast(itk::ProcessObject::GetInput(0)); // Cast typedef int InternalPixelType; typedef itk::Image InternalImageType; typedef itk::CastImageFilter InputCastImageFilterType; typename InputCastImageFilterType::Pointer inputCaster = InputCastImageFilterType::New(); inputCaster->SetInput(input); inputCaster->Update(); //---------------------------------------- // Loop over directions //---------------------------------------- typename InternalImageType::Pointer output = inputCaster->GetOutput(); for (unsigned int i=0; i ImageSliceType; typedef itk::Image MaskSliceType; typename InternalImageType::RegionType region3D = input->GetLargestPossibleRegion(); typename InternalImageType::RegionType::SizeType size3D = region3D.GetSize(); typename InternalImageType::RegionType::SizeType size2D = size3D; size2D[m_Directions[i]]=0; typename InternalImageType::IndexType start2D; start2D.Fill(0); typename InternalImageType::RegionType desiredRegion; desiredRegion.SetSize( size2D ); desiredRegion.SetIndex( start2D ); // Extract and Join typedef itk::ExtractImageFilter ExtractImageFilterType; typedef itk::JoinSeriesImageFilter JoinSeriesFilterType; typename JoinSeriesFilterType::Pointer joinFilter=JoinSeriesFilterType::New(); joinFilter->SetSpacing(input->GetSpacing()[m_Directions[i]]); //---------------------------------------- // Run over the sliceIndexs // ---------------------------------------- for(unsigned int sliceIndex=0; sliceIndex SetInput(output); start2D[m_Directions[i]]=sliceIndex; desiredRegion.SetIndex( start2D ); extractFilter->SetExtractionRegion( desiredRegion ); extractFilter->SetDirectionCollapseToSubmatrix(); extractFilter->Update( ); typename ImageSliceType::Pointer slice= extractFilter->GetOutput(); // Binarize the image (Before: OBJECT!=0, rest=0, After: object=1, rest=0 ) typedef itk::BinaryThresholdImageFilter BinarizeFilterType; typename BinarizeFilterType::Pointer binarizeFilter=BinarizeFilterType::New(); binarizeFilter->SetInput(slice); binarizeFilter->SetUpperThreshold(0); binarizeFilter->SetOutsideValue(0); binarizeFilter->SetInsideValue(1); // writeImage(binarizeFilter->GetOutput(),"/home/jef/tmp/input.mhd"); // Perform connected labelling on the slice (body+air=0 ) typedef itk::ConnectedComponentImageFilter ConnectFilterType; typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New(); connectFilter->SetInput(binarizeFilter->GetOutput()); connectFilter->SetBackgroundValue(0); connectFilter->SetFullyConnected(false); //connectFilter->Update(); //writeImage(connectFilter->GetOutput(),"/home/jef/tmp/connect.mhd"); // Sort the labels typedef itk::RelabelComponentImageFilter RelabelFilterType; typename RelabelFilterType::Pointer relabelFilter=RelabelFilterType::New(); relabelFilter->SetInput(connectFilter->GetOutput()); //relabelFilter->Update(); //writeImage(relabelFilter->GetOutput(),"/home/jef/tmp/label.mhd"); // Keep the first typedef itk::ThresholdImageFilter ThresholdFilterType; typename ThresholdFilterType::Pointer thresholdFilter=ThresholdFilterType::New(); thresholdFilter->SetInput(relabelFilter->GetOutput()); thresholdFilter->SetUpper(1); thresholdFilter->SetOutsideValue(0); // thresholdFilter->Update(); // writeImage(thresholdFilter->GetOutput(),"/home/jef/tmp/bin.mhd"); // Invert the labels (lung 1, rest 0) typename BinarizeFilterType::Pointer switchFilter=BinarizeFilterType::New(); switchFilter->SetInput(thresholdFilter->GetOutput()); switchFilter->SetUpperThreshold(0); switchFilter->SetOutsideValue(0); switchFilter->SetInsideValue(1); switchFilter->Update(); //writeImage(switchFilter->GetOutput(),"/home/jef/tmp/inv_bin.mhd"); //Join joinFilter->SetInput( sliceIndex, switchFilter->GetOutput()); } // Join to a 3D image joinFilter->Update(); // Permute the axes to reset to orientation typedef itk::PermuteAxesImageFilter PermuteFilterType; typename PermuteFilterType::Pointer permuteFilter=PermuteFilterType::New(); permuteFilter->SetInput(joinFilter->GetOutput()); typename PermuteFilterType::PermuteOrderArrayType order; order[m_Directions[i]]=2; if( m_Directions[i]==2) { order[0]=0; order[1]=1; } else if ( m_Directions[i]==1) { order[0]=0; order[2]=1; } else if (m_Directions[i]==0) { order[1]=0; order[2]=1; } permuteFilter->SetOrder(order); permuteFilter->Update(); output = permuteFilter->GetOutput(); // Set the image direction to the input one output->SetDirection(input->GetDirection()); output->SetOrigin(input->GetOrigin()); } // Cast typedef itk::CastImageFilter OutputCastImageFilterType; typename OutputCastImageFilterType::Pointer outputCaster =OutputCastImageFilterType::New(); outputCaster->SetInput(output); outputCaster->Update(); // Output this->GraftOutput(outputCaster->GetOutput()); } //-------------------------------------------------------------------- #endif //#define CLITKFILLMASKFILTER_TXX