From 7d2112cf3e366658023ee70f58226426022e70fe Mon Sep 17 00:00:00 2001 From: Vivien Delmon Date: Tue, 29 Nov 2011 12:03:49 +0100 Subject: [PATCH] Add seedRadius option to clitkRegionGrowing - Add seedRadius option to clitkRegionGrowing to allow ball of seeds instead of single pixel seed. --- segmentation/clitkRegionGrowing.ggo | 1 + .../clitkRegionGrowingGenericFilter.txx | 74 ++++++++++++++++--- 2 files changed, 65 insertions(+), 10 deletions(-) diff --git a/segmentation/clitkRegionGrowing.ggo b/segmentation/clitkRegionGrowing.ggo index 59cb77c..60bcae2 100644 --- a/segmentation/clitkRegionGrowing.ggo +++ b/segmentation/clitkRegionGrowing.ggo @@ -25,6 +25,7 @@ option "adaptLower" - "3,4: (locally) adapt lower thresholding" flag off option "adaptUpper" - "3,4: (locally) adapt upper thresholding" flag off option "multiplier" m "2-4: (2-3) accept if within mean+-mutiplier*SD, (4) explosion if size increases multiplier times" double no default="2.0" option "seed" s "Seed index postion (in voxels)" int multiple no default="0" +option "seedRadius" - "Radius used for seed dilatation(in voxel)" int multiple no default="0" option "pad" p "The replace padding value" double no default="1.0" option "radius" r "1-3: The radius of the neighborhood" int no multiple default="1" option "maxSD" - "3: Limit to SD" double no diff --git a/segmentation/clitkRegionGrowingGenericFilter.txx b/segmentation/clitkRegionGrowingGenericFilter.txx index b922727..43f5b08 100644 --- a/segmentation/clitkRegionGrowingGenericFilter.txx +++ b/segmentation/clitkRegionGrowingGenericFilter.txx @@ -17,6 +17,8 @@ ===========================================================================**/ #ifndef clitkRegionGrowingGenericFilter_txx #define clitkRegionGrowingGenericFilter_txx +#include +#include namespace clitk { @@ -75,17 +77,64 @@ namespace clitk typename InputImageType::Pointer input= reader->GetOutput(); // Seed - typename InputImageType::IndexType index; + typedef typename std::vector SeedsType; + SeedsType seeds(1); if(m_ArgsInfo.seed_given==Dimension) for (unsigned int i=0; i BallType; + typename BallType::RadiusType r; + + if (m_ArgsInfo.seedRadius_given == Dimension) + for (unsigned i = 0; i < Dimension; i++) + r[i] = m_ArgsInfo.seedRadius_arg[i]; + else + r.Fill(m_ArgsInfo.seed_arg[0]); + + BallType ball; + ball.SetRadius(r); + ball.CreateStructuringElement(); + + typedef itk::ConstShapedNeighborhoodIterator IteratorType; + IteratorType it(ball.GetRadius(), + input, + input->GetLargestPossibleRegion()); +#if ITK_VERSION_MAJOR < 4 + typename BallType::ConstIterator nit; + unsigned idx = 0; + for (nit = ball.Begin(); nit != ball.End(); ++nit, ++idx) + { + if (*nit) + { + it.ActivateOffset(it.GetOffset(idx)); + } + else + { + it.DeactivateOffset(it.GetOffset(idx)); + } + } +#else + it.CreateActiveListFromNeighborhood(ball); + it.NeedToUseBoundaryConditionOff(); +#endif + + it.SetLocation(seeds[0]); + for (typename IteratorType::ConstIterator i = it.Begin(); !i.IsAtEnd(); ++i) + { + typename InputImageType::IndexType id = seeds[0] + i.GetNeighborhoodOffset(); + if (id != seeds[0] && input->GetLargestPossibleRegion().IsInside(id)) + seeds.push_back(id); + } + } // Filter typedef itk::ImageToImageFilter ImageToImageFilterType; @@ -101,7 +150,8 @@ namespace clitk f->SetLower(m_ArgsInfo.lower_arg); f->SetUpper(m_ArgsInfo.upper_arg); f->SetReplaceValue(static_cast(m_ArgsInfo.pad_arg)); - f->SetSeed(index); + for (typename SeedsType::const_iterator it = seeds.begin(); it != seeds.end(); ++it) + f->AddSeed(*it); filter=f; if(m_Verbose)std::cout<<"Using the connected threshold image filter..."<SetLower(m_ArgsInfo.lower_arg); f->SetUpper(m_ArgsInfo.upper_arg); f->SetReplaceValue(static_cast(m_ArgsInfo.pad_arg)); - f->AddSeed(index); + for (typename SeedsType::const_iterator it = seeds.begin(); it != seeds.end(); ++it) + f->AddSeed(*it); f->SetRadius(size); filter=f; if(m_Verbose)std::cout<<"Using the neighborhood threshold connected image filter..."<SetMultiplier( m_ArgsInfo.multiplier_arg ); f->SetNumberOfIterations( m_ArgsInfo.multiplier_arg ); - f->AddSeed( index ); + for (typename SeedsType::const_iterator it = seeds.begin(); it != seeds.end(); ++it) + f->AddSeed(*it); f->SetNumberOfIterations( m_ArgsInfo.iter_arg); f->SetReplaceValue(static_cast(m_ArgsInfo.pad_arg)); f->SetInitialNeighborhoodRadius(size[0]); @@ -187,7 +239,8 @@ namespace clitk f->SetMultiplier(m_ArgsInfo.multiplier_arg); f->SetMaximumSDIsGiven(m_ArgsInfo.maxSD_given); if (m_ArgsInfo.maxSD_given) f->SetMaximumSD(m_ArgsInfo.maxSD_arg); - f->AddSeed(index); + for (typename SeedsType::const_iterator it = seeds.begin(); it != seeds.end(); ++it) + f->AddSeed(*it); f->SetRadius(size); filter=f; if(m_Verbose)std::cout<<"Using the locally adaptive threshold connected image filter..."<SetThresholdStepSize(m_ArgsInfo.step_arg); f->SetMinimumThresholdStepSize(m_ArgsInfo.minStep_arg); f->SetFullyConnected(m_ArgsInfo.full_flag); - f->AddSeed(index); + for (typename SeedsType::const_iterator it = seeds.begin(); it != seeds.end(); ++it) + f->AddSeed(*it); filter=f; if(m_Verbose)std::cout<<"Using the explosion controlled threshold connected image filter..."<