[Insight-users] AW: itkDeformableTest. ConfidenceConnectedImageFilter
Ting Chen
chenting@graphics.cis.upenn.edu
Thu, 13 Feb 2003 16:33:42 -0500
Hi! Waltraut,
for the first question. what I did in the deformable test is to first use
m_bmmeshsource to create a mesh based on the input binary mask.
the input for the deformable3Dmeshfilter is the otuput mesh of
m_bmmeshsource. the binary mask itself will not be passed directly to the
model
the structure of the test is
input binary
mask-----(m_bmmeshsource)---->itkmesh----->(deformable3dmeshfilter)--->outpu
t mesh
and for the deformable filter, the user should also provide a gradient map
of the original image volume. the mesh created from the binary mask
will deform under the effect of the gradient
for the second question, you can speed up the fitting process by decrease
stepthreshold and increase timestep, however, there is the possibiblity that
the model be overfit. you need to play witht he parameters to find the
suitable value for your dataset
another thing is that the binary mask should be close enough to the edge
features. the deformable model can push the roughly estimation of the object
out of
local minima when the model is not too far away from the edge featuer, but
it cannot be used to get the right segmentation regardless of the initial
binary mask.
good luck
ting
----- Original Message -----
From: "Waltraud Henrich" <henrich@ira.uka.de>
To: "'Ting Chen'" <chenting@graphics.cis.upenn.edu>
Cc: <insight-users@public.kitware.com>
Sent: Thursday, February 13, 2003 4:02 AM
Subject: [Insight-users] AW: itkDeformableTest.
ConfidenceConnectedImageFilter
>
> Hello again Ting,
>
>
> I still have a couple of questions:
> 1) I use ConfidenceConnectedImageFilter to get the binary image, and then
I
> use deformableMesh3DFilter.
> If I use Region Growing then the region will run out(getting much to big).
I
> don't get the segmented image with ConfidenceConnectedImageFilter. Could
> you explain what the deformableMesh3DFilter makes exactly with the binary
> image (maybe a little more detailed)?
> Which are the best methods to be received the binary mask?
> Is the binary mask then fit somehow to gradients?
> 2)I get the binary picture, but somehow I think this is not the correct
one.
> Furthermore the invocation of the Update method (m_dfilter->Update();) on
> the DeformableMesh3DFilter takes about 8 minutes .
> I get something (if I convert m_bmmeshsource in vtkUnstructuredGrid (with
> Insight/Auxiliary/vtk2itk.cxx)), but, as already said, I think it isn't
> exactly what I wanted to have.
> May this problem comes with the wrong binary image?
>
> Thanks in advance.
>
> Waltraut
>
> It would be a great help for me if you could arrange to take a look at the
> following code.
>
>
>
>
> void DefBinaerTest::TestBinaer()
> {
> // here I create with ConfidenceConnectedImageFilter the binary image
>
>
> vtkImageData* pImage = GetImageData() ;
> pImage->GetDimensions(m_ImageDim );
>
>
> WIDTH = m_ImageDim[0];
> HEIGHT = m_ImageDim[1];
> DEPTH = m_ImageDim[2];
>
>
> int SEEDX = m_nSeedX;
> int SEEDY = m_nSeedY;
> int SEEDZ = m_nSeedZ;
>
>
>
> vtkImageCast *doubleImage = vtkImageCast::New();
> doubleImage->SetInput(pImage);
> doubleImage->SetOutputScalarTypeToDouble();
> doubleImage->Update();
>
> vtkImageExport* vtkExporter = vtkImageExport::New();
> vtkExporter->SetInput(doubleImage->GetOutput());
>
>
>
>
> //------------------------------------------------------------------------
> // VTK to ITK pipeline connection.
>
> //------------------------------------------------------------------------
>
> const unsigned int Dimension = 3;
> typedef itk::Image<double, Dimension> InternalImageType;
>
>
> typedef itk::VTKImageImport<InternalImageType> myImageImportType;
> myImageImportType::Pointer itkImporter = myImageImportType::New();
> ConnectPipelines(vtkExporter, itkImporter);
>
> itkImporter->Update();
>
>
> typedef itk::Image<unsigned short, Dimension>
> myUSImageType;
>
> typedef itk::Image<unsigned char, Dimension> ImageTypeUCHAR;
> //typedef unsigned char OutputPixelType;
> typedef unsigned short OutputPixelType; // ich muss ein Cast machen
> denn mein caster
>
> //ist unsigned char und ich brauch unsigned short
>
> typedef itk::Image< OutputPixelType, Dimension > OutputImageType;
>
> typedef itk::CastImageFilter<
> InternalImageType,
> OutputImageType > CastingFilterType;
>
> CastingFilterType::Pointer caster = CastingFilterType::New();
>
> typedef itk::CurvatureFlowImageFilter<
> InternalImageType,
> InternalImageType > CurvatureFlowImageFilterType;
>
>
>
> CurvatureFlowImageFilterType::Pointer smoothing =
> CurvatureFlowImageFilterType::New();
>
>
> typedef itk::ConfidenceConnectedImageFilter<
> InternalImageType,
> InternalImageType > ConnectedFilterType;
>
> ConnectedFilterType::Pointer confidenceConnected =
> ConnectedFilterType::New();
>
>
> smoothing->SetInput( itkImporter->GetOutput() );
>
> confidenceConnected->SetInput( smoothing->GetOutput() );
>
> caster->SetInput( confidenceConnected->GetOutput() );
>
> smoothing->SetNumberOfIterations(1);
>
> smoothing->SetTimeStep( 0.125 );
>
> smoothing->Update();
>
> confidenceConnected->SetMultiplier( 2.5 );
>
> confidenceConnected->SetNumberOfIterations( 2 );
>
> confidenceConnected->SetReplaceValue( 255 );
>
>
> InternalImageType::IndexType index;
>
>
> index[0] = SEEDX;
> index[1] = SEEDY;
> index[2] = SEEDZ;
>
> confidenceConnected->SetSeed( index );
>
> confidenceConnected->SetInitialNeighborhoodRadius( 2 );
>
> confidenceConnected->Update();
>
> caster->Update();
>
>
>
> //------------------------------------------------------------------------
> // ITK to VTK pipeline connection.
>
> //------------------------------------------------------------------------
>
>
>
> typedef itk::VTKImageExport<myUSImageType> ImageExportType;
> ImageExportType::Pointer itkExporter = ImageExportType::New();
> itkExporter->SetInput(caster->GetOutput());
>
> // Create the vtkImageImport and connect it to the
> itk::VTKImageExport instance.
> vtkImageImport* vtkImageImport = vtkImageImport::New();
> ConnectPipelines(itkExporter, vtkImageImport);
> vtkImageImport->Update();
>
> vtkImageData* pResultImage = vtkImageImport->GetOutput();
>
> //Daten in neues Objekt kopieren -> Unterbrechung der Pipeline
> vtkImageData* pNewResultImage = vtkImageData::New();
> pNewResultImage->DeepCopy(pResultImage); //Deep Copy sonst Absturz
>
> GfxPlaneViewer(pNewResultImage, "ConfidenceConnected");
>
>
>
>
>
> //itkDeformableTest
>
>
>
>
>
> // Declare the types of the output images
> typedef itk::Image<unsigned short, Dimension> binaryImageType;
>
> // Declare the type of the index to access images
> typedef itk::Index<Dimension> myIndexType;
>
> // Declare the type of the size
> typedef itk::Size<Dimension> mySizeType;
>
> // Declare the type of the Region
> typedef itk::ImageRegion<Dimension> myRegionType;
>
> // Declare the type of the Mesh
> typedef itk::Mesh<double> DMesh;
>
>
>
> typedef DMesh::PointType OPointType;
>
> // Declare the type of the gradient image
> typedef itk::CovariantVector<double, Dimension> myGradientType;
> typedef itk::Image<myGradientType, Dimension> myGradientImageType;
> typedef itk::CovariantVector<double, 2> double2DVector;
> typedef itk::CovariantVector<int, 3> int3DVector;
> typedef itk::CovariantVector<double, 3> double3DVector;
> typedef itk::CovariantVector<int, 2> int2DVector;
>
> typedef itk::BinaryMask3DMeshSource<DMesh> myMeshSource;
> typedef itk::LaplacianImageFilter<InternalImageType,
> InternalImageType> myLaplacianFilterType;
> typedef itk::GradientVectorFlowImageFilter<myGradientImageType,
> myGradientImageType>
> myGVFFilterType;
>
> typedef itk::GradientImageFilter<InternalImageType, double, double>
> myGFilterType;
>
> typedef itk::GradientToMagnitudeImageFilter<myGradientImageType,
> InternalImageType>
> myGToMFilterType;
>
> typedef itk::DeformableMesh3DFilter<DMesh, DMesh> DFilter;
>
> binaryImageType::Pointer biimg = caster->GetOutput();
> //=binaryImageType::New();
> myGradientImageType::Pointer gdimg=myGradientImageType::New();
>
> typedef itk::ImageRegionIteratorWithIndex<InternalImageType>
> myIteratorType;
> typedef itk::ImageRegionIteratorWithIndex<myGradientImageType>
> myGradientIteratorType;
>
> binaryImageType::SizeType bisize={{WIDTH,HEIGHT,DEPTH}};
> binaryImageType::IndexType biindex;
> binaryImageType::RegionType biregion;
> biindex.Fill(0);
> biregion.SetSize(bisize);
> biregion.SetIndex(biindex);
>
> myGradientImageType::SizeType gdsize={{WIDTH,HEIGHT,DEPTH}};
> myGradientImageType::IndexType gdindex;
> myGradientImageType::RegionType gdregion;
> gdindex.Fill(0);
> gdregion.SetSize(gdsize);
> gdregion.SetIndex(gdindex);
>
> biimg->SetLargestPossibleRegion( biregion );
> biimg->SetBufferedRegion( biregion );
> biimg->SetRequestedRegion( biregion );
> biimg->Allocate();
>
> gdimg->SetLargestPossibleRegion( gdregion );
> gdimg->SetBufferedRegion( gdregion );
> gdimg->SetRequestedRegion( gdregion );
> gdimg->Allocate();
>
> // image
> InternalImageType::Pointer inputImage =
> itkImporter->GetOutput();//myImageType::New();
>
> mySizeType size={{WIDTH,HEIGHT,DEPTH}};
> myIndexType start;
> start.Fill(0);
>
> myRegionType region;
> region.SetIndex( start );
> region.SetSize( size );
>
> // Initialize Image A
> inputImage->SetLargestPossibleRegion( region );
> inputImage->SetBufferedRegion( region );
> inputImage->SetRequestedRegion( region );
> inputImage->Allocate();
>
> itk::ImageRegionIteratorWithIndex <InternalImageType> it(inputImage,
> region);
> it.GoToBegin();
> itk::ImageRegionIteratorWithIndex <binaryImageType> bit(biimg,
> biregion);
> bit.GoToBegin();
>
>
>
>
> //////////////////////////////////////////////////////////////////////////
>
> itk::ShrinkImageFilter< InternalImageType, InternalImageType
> >::Pointer dshrink;
> dshrink = itk::ShrinkImageFilter< InternalImageType,
> InternalImageType >::New();
> dshrink->SetInput( inputImage );
> dshrink->SetNumberOfThreads(4);
>
> unsigned int dfactors[3] = { 1, 1, 1 };
> dshrink->SetShrinkFactors(dfactors);
> dshrink->UpdateLargestPossibleRegion();
>
> InternalImageType::RegionType drequestedRegion;
> drequestedRegion = dshrink->GetOutput()->GetRequestedRegion();
>
> typedef itk::GradientRecursiveGaussianImageFilter<
> InternalImageType,
> myGradientImageType
> > myFilterType;
>
>
> // Create a Filter
> myFilterType::Pointer grfilter = myFilterType::New();
>
> // Connect the input images
> grfilter->SetInput( dshrink->GetOutput() );
>
> // Set sigma
> grfilter->SetSigma( 2.0 );
>
> myLaplacianFilterType::Pointer m_LFilter =
> myLaplacianFilterType::New();
> myGVFFilterType::Pointer m_GVFFilter = myGVFFilterType::New();
>
> myGFilterType::Pointer gfilter = myGFilterType::New();
> m_GVFFilter->SetInput(gfilter->GetOutput());
> m_GVFFilter->SetLaplacianFilter(m_LFilter);
> m_GVFFilter->SetNoiseLevel(500);
>
> myGToMFilterType::Pointer gtomfilter = myGToMFilterType::New();
> gtomfilter->SetInput(grfilter->GetOutput());
>
> gfilter->SetInput(gtomfilter->GetOutput());
> gfilter->Update();
>
> std::cout << "The gradient map created!" << std::endl;
>
> // the gvf is temproraily disabled since the problem related with
> gradientimagefilter
> // m_GVFFilter->Update();
>
> // std::cout << "GVF created! " << std::endl;
>
>
>
////////////////////////////////////////////////////////////////////////////
> ////////////
> // construct the deformable mesh
>
> itk::ShrinkImageFilter< binaryImageType, binaryImageType >::Pointer
> shrink;
> shrink = itk::ShrinkImageFilter< binaryImageType, binaryImageType
> >::New();
> shrink->SetInput( biimg );
> shrink->SetNumberOfThreads(4);
>
> unsigned int factors[3] = { 1, 1, 1 };
> shrink->SetShrinkFactors(factors);
> shrink->UpdateLargestPossibleRegion();
>
> binaryImageType::RegionType requestedRegion;
> requestedRegion = shrink->GetOutput()->GetRequestedRegion();
>
> myMeshSource::Pointer m_bmmeshsource = myMeshSource::New();
>
> DFilter::Pointer m_dfilter = DFilter::New();
> m_dfilter->SetInput(m_bmmeshsource->GetOutput());
> // m_dfilter->SetGradient(m_GVFFilter->GetOutput());
> m_dfilter->SetGradient(gfilter->GetOutput());
>
>
>
>
> m_bmmeshsource->SetBinaryImage( shrink->GetOutput() );
> m_bmmeshsource->SetObjectValue( 255 );
>
> std::cout << "Deformable mesh created using Marching Cube!" <<
> std::endl;
>
> double2DVector m_stiff;
> m_stiff[0] = 0.0001;
> m_stiff[1] = 0.1;
>
> double3DVector m_scale;
> m_scale[0] = 1;
> m_scale[1] = 1;
> m_scale[2] = 1;
> m_dfilter->SetStiffness(m_stiff);
> m_dfilter->SetGradientMagnitude(0.1);
> m_dfilter->SetTimeStep(2);
> m_dfilter->SetStepThreshold(100);
> m_dfilter->SetScale(m_scale);
> std::cout << "Deformable mesh fitting...";
> m_dfilter->Update();
>
>
> // Create a vtkUnstructuredGrid
> vtkUnstructuredGrid* vgrid = vtkUnstructuredGrid::New();
> CreateVTKMeshBinaer(m_bmmeshsource,vgrid);
>
>
>
>
> std::cout << "Mesh Source: " << m_bmmeshsource;
>
>
> }
>
>
> -----Ursprüngliche Nachricht-----
> Von: Ting Chen [mailto:chenting@graphics.cis.upenn.edu]
> Gesendet: Donnerstag, 30. Januar 2003 19:47
> An: Waltraud Henrich
> Betreff: Re: itkDeformableTest.
>
>
> Hi!
>
> by using line 1, 2, 3 and 4, 5, 6, I created a cubic region in the middle
of
> the volume whose size is 36, 36, 36 and origin is 18, 18, 18. This way I
got
> my test image.
>
> it seems to me that in your code below, you create an image of the size
> WIDTH*HEIGHT*DEPTH, with a brighter cubic in it, and you also created a
> binary mask of the region in biimg.
>
> when you are trying to read in an existed image, you should not use the
code
> inside /* and */, instead, you need to assign the output of itkImporter to
> the inputimage, and you also need to create the binary mask using some
other
> segmentation methods.
>
> good luck
>
> ting
>
> ----- Original Message -----
> From: "Waltraud Henrich" <henrich@ira.uka.de>
> To: <chenting@graphics.cis.upenn.edu>
> Cc: <insight-users@public.kitware.com>
> Sent: Thursday, January 30, 2003 3:48 AM
> Subject: itkDeformableTest.
>
>
> >
> > Hello
> >
> > How can I work with a binary image and the original image?
> > In your example the image already exist .I transform the images from vtk
> to
> > itk. The binary image can be accessed by itkImporter1->GetOutput() and
the
> > origal image can be accessed by itkImporter->GetOutput().
> >
> > As I didn't understand the following lines of code in your example
> > completely, I would ask you to tell me whether my interpretation is
> correct:
> > 1 size[0] = 36;
> > 2: size[1] = 36;
> > 3: size[2] = 36;
> >
> > 4: start[0] = 18;
> > 5: start[1] = 18;
> > 6: start[2] = 18;
> >
> > Interpretation:
> > Do 1-3 represent the size of the bounding box / search region?
> > Do 4-6 represent the origin of the bounding box / search region?
> >
> > It would be a great help for me if you could arrange to take a look at
the
> > following piece of code. It's almost completely your example, except the
> > market(*) lines.
> >
> >
> >
> > * binaryImageType::Pointer biimg = itkImporter1->GetOutput();
> > //=binaryImageType::New();
> > myGradientImageType::Pointer gdimg=myGradientImageType::New();
> >
> > typedef itk::ImageRegionIteratorWithIndex<myImageType>
> > myIteratorType;
> > typedef itk::ImageRegionIteratorWithIndex<myGradientImageType>
> > myGradientIteratorType;
> >
> > binaryImageType::SizeType bisize={{WIDTH,HEIGHT,DEPTH}};
> > binaryImageType::IndexType biindex;
> > binaryImageType::RegionType biregion;
> > biindex.Fill(0);
> > biregion.SetSize(bisize);
> > biregion.SetIndex(biindex);
> >
> > myGradientImageType::SizeType gdsize={{WIDTH,HEIGHT,DEPTH}};
> > myGradientImageType::IndexType gdindex;
> > myGradientImageType::RegionType gdregion;
> > gdindex.Fill(0);
> > gdregion.SetSize(gdsize);
> > gdregion.SetIndex(gdindex);
> >
> > biimg->SetLargestPossibleRegion( biregion );
> > biimg->SetBufferedRegion( biregion );
> > biimg->SetRequestedRegion( biregion );
> > biimg->Allocate();
> >
> > gdimg->SetLargestPossibleRegion( gdregion );
> > gdimg->SetBufferedRegion( gdregion );
> > gdimg->SetRequestedRegion( gdregion );
> > gdimg->Allocate();
> >
> > // image
> > * myImageType::Pointer inputImage =
> > itkImporter->GetOutput();//myImageType::New();
> >
> > mySizeType size={{WIDTH,HEIGHT,DEPTH}};
> > myIndexType start;
> > start.Fill(0);
> >
> > myRegionType region;
> > region.SetIndex( start );
> > region.SetSize( size );
> >
> > // Initialize Image A
> > inputImage->SetLargestPossibleRegion( region );
> > inputImage->SetBufferedRegion( region );
> > inputImage->SetRequestedRegion( region );
> > inputImage->Allocate();
> >
> > itk::ImageRegionIteratorWithIndex <myImageType> it(inputImage,
> > region);
> > it.GoToBegin();
> > itk::ImageRegionIteratorWithIndex <binaryImageType> bit(biimg,
> > biregion);
> > bit.GoToBegin();
> >
> >
> /*
> > while( !it.IsAtEnd() )
> > {
> > it.Set( 0.0 );
> > bit.Set( 0 );
> > ++it;
> > ++bit;
> > }
> >
> > * size[0] = 20;
> > * size[1] = 20;
> > * size[2] = 6;
> >
> > * start[0] = 232;
> > * start[1] = 119;
> > * start[2] = 0;
> >
> > // Create one iterator for an internal region
> > region.SetSize( size );
> > region.SetIndex( start );
> > biregion.SetSize( size );
> > biregion.SetIndex( start );
> > itk::ImageRegionIteratorWithIndex <myImageType> itb( inputImage,
> > region );
> > itk::ImageRegionIteratorWithIndex <binaryImageType> bitb( biimg,
> > biregion );
> >
> > // Initialize the content the internal region
> > while( !itb.IsAtEnd() )
> > {
> > itb.Set( 100.0 );
> > bitb.Set ( 255 );
> > ++itb;
> > ++bitb;
> > }
> */
> >
> >
> >
> > Thanks in advance.
> >
> > Waltraut
> >
> >
>
> _______________________________________________
> Insight-users mailing list
> Insight-users@public.kitware.com
> http://public.kitware.com/mailman/listinfo/insight-users