[Insight-users] Fwd: Re: Filling big 3D holes
Gib Bogle
g.bogle at auckland.ac.nz
Wed Feb 2 23:09:28 EST 2011
(Sorry about forgetting to "reply-all")
-------- Original Message --------
Subject: Re: [Insight-users] Filling big 3D holes
Date: Thu, 03 Feb 2011 17:06:42 +1300
From: Gib Bogle <g.bogle at auckland.ac.nz>
To: brian avants <stnava at gmail.com>
Hi Brian,
Before I delve into this, do you think it overcomes the problem of wall
continuity that I refer to in my reply to Richard?
Thanks
Gib
On 3/02/2011 5:00 p.m., brian avants wrote:
> hi gib
>
> following on richard's response
>
> // hole-filling algorithm :
> 1. get distance map of background from object
> 2. threshold above zero
> 3. label connected components
> 4. label surface of each connected component
> 5. if everywhere on the surface is next to object then it's a hole
>
> an itk code sketch that approximates this is below ---
>
> brian
>
>
> template<unsigned int ImageDimension>
> int FillHoles(int argc, char *argv[])
> {
>
> typedef itk::DanielssonDistanceMapImageFilter<ImageType, ImageType>
> FilterType;
> typename FilterType::Pointer filter = FilterType::New();
> filter->InputIsBinaryOff();
> filter->SetUseImageSpacing(false);
> filter->SetInput(image1);
> filter->Update();
>
> typedef itk::Image<int, ImageDimension> labelimagetype;
> typename ImageType::Pointer dist = filter->GetOutput();
> typename ImageType::Pointer regions =
> BinaryThreshold<ImageType>(0.001,1.e9,1,dist);
>
> typedef itk::ConnectedComponentImageFilter< labelimagetype,
> labelimagetype> ccFilterType;
> typedef itk::RelabelComponentImageFilter< labelimagetype, ImageType
>> RelabelType;
> typename RelabelType::Pointer relabel = RelabelType::New();
> typename ccFilterType::Pointer ccfilter = ccFilterType::New();
>
> typename CastFilterType::Pointer castRegions = CastFilterType::New();
> castRegions->SetInput( regions );
>
> ccfilter->SetInput(castRegions->GetOutput());
> ccfilter->SetFullyConnected( 0 );
> ccfilter->Update();
> relabel->SetInput( ccfilter->GetOutput() );
>
> relabel->SetMinimumObjectSize( 0 );
> // relabel->SetUseHistograms(true);
> try
> {
> relabel->Update();
> }
> catch( itk::ExceptionObject& excep )
> {
> std::cerr<< "Relabel: exception caught !"<< std::endl;
> std::cerr<< excep<< std::endl;
> }
>
>
> // WriteImage<ImageType>(relabel->GetOutput(),"test.nii");
>
> if (holeparam == 2)
> {
> std::cout<<" Filling all holes"<< std::endl;
> typedef itk::ImageRegionIteratorWithIndex<ImageType> Iterator;
> Iterator vfIter( relabel->GetOutput(),
> relabel->GetOutput()->GetLargestPossibleRegion() );
>
> for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter )
> {
> if (vfIter.Get()> 1 ) imageout->SetPixel(vfIter.GetIndex(),1);
> }
>
> // WriteImage<ImageType>(imageout,outname.c_str());
>
> return 0;
> }
>
>
> typedef itk::NeighborhoodIterator<ImageType> iteratorType;
> typename iteratorType::RadiusType rad;
> for (unsigned int j=0; j<ImageDimension; j++) rad[j]=1;
> iteratorType GHood(rad,
> relabel->GetOutput(),relabel->GetOutput()->GetLargestPossibleRegion());
>
> float maximum=relabel->GetNumberOfObjects();
> //now we have the exact number of objects labeled independently
> for (unsigned int lab=2; lab<=maximum; lab++)
> {
> float erat=2;
> if (holeparam<= 1 )
> {
> GHood.GoToBegin();
>
> unsigned long objectedge=0;
> unsigned long backgroundedge=0;
> unsigned long totaledge=0;
> unsigned long volume=0;
>
> while (!GHood.IsAtEnd())
> {
> typename ImageType::PixelType p = GHood.GetCenterPixel();
> typename ImageType::IndexType ind = GHood.GetIndex();
> typename ImageType::IndexType ind2;
> if ( p == lab )
> {
> volume++;
> for (unsigned int i = 0; i< GHood.Size(); i++)
> {
> ind2=GHood.GetIndex(i);
> float dist=0.0;
> for (unsigned int j=0; j<ImageDimension; j++)
> dist+=(float)(ind[j]-ind2[j])*(float)(ind[j]-ind2[j]);
> dist=sqrt(dist);
> float val2=image1->GetPixel(ind2);
> if (val2>= 0.5&& GHood.GetPixel(i) != lab )
> {
> objectedge++;
> totaledge++;
> }
> else if (val2< 0.5&& GHood.GetPixel(i) != lab )
> {
> backgroundedge++;
> totaledge++;
> }
> }
> }
> ++GHood;
> }
> float vrat=(float)totaledge/(float)volume;
> erat=(float)objectedge/(float)totaledge;
> std::cout<<" Lab "<< lab<< " volume "<< volume<< " v-rat"
> << vrat<< " edge "<< erat<< std::endl;
> }
>
> if (erat> holeparam)// fill the hole
> {
> std::cout<<" Filling "<< lab<< " of "<< maximum<< std::endl;
> typedef itk::ImageRegionIteratorWithIndex<ImageType> Iterator;
> Iterator vfIter( relabel->GetOutput(),
> relabel->GetOutput()->GetLargestPossibleRegion() );
>
> for( vfIter.GoToBegin(); !vfIter.IsAtEnd(); ++vfIter )
> {
> if (vfIter.Get() == lab ) imageout->SetPixel(vfIter.GetIndex(),1);
> }
>
> }
>
> }
>
> // write the image
> // WriteImage<ImageType>(imageout,outname.c_str());
>
>
> return 0;
>
> }
>
>
>
>
>
>
> On Wed, Feb 2, 2011 at 10:28 PM, Gib Bogle<g.bogle at auckland.ac.nz> wrote:
>> I'm working with a volume image that was generated by labelling the laminae
>> of blood vessels. My aim is to segment out the vasculature. There are many
>> difficulties, and the particular issue I'm addressing at the moment is
>> filling in the vessels. The intensity of the labelling of the walls is
>> variable, with patches that are indistinguishable from background. The
>> vessel diameters vary widely, from about 4 to about 60 voxels. After some
>> preprocessing I have a binary image, on which the ITK hole-filling function
>> works well with the small-diameter vessels, but the big vessels present a
>> problem, even when the walls are "watertight" (i.e. without holes).
>>
>> My best idea so far is to send probes out in all 26 directions (all
>> neighbours of a voxel) and count the number of probes that hit a wall within
>> a specified radius. It's tricky to specify both the radius and the critical
>> number of hits, without getting too many false positives (voxels outside the
>> vessels showing up as inside). (The filter is of course applied
>> iteratively.)
>>
>> I'm wondering if anyone else here has addressed a similar problem.
>>
>> Thanks
>> Gib
>> _____________________________________
>> Powered by www.kitware.com
>>
>> Visit other Kitware open-source projects at
>> http://www.kitware.com/opensource/opensource.html
>>
>> Kitware offers ITK Training Courses, for more information visit:
>> http://www.kitware.com/products/protraining.html
>>
>> Please keep messages on-topic and check the ITK FAQ at:
>> http://www.itk.org/Wiki/ITK_FAQ
>>
>> Follow this link to subscribe/unsubscribe:
>> http://www.itk.org/mailman/listinfo/insight-users
>>
More information about the Insight-users
mailing list