📄 itkrecursivegaussianimagefilterstest.cxx
字号:
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile: itkRecursiveGaussianImageFiltersTest.cxx,v $
Language: C++
Date: $Date: 2005-01-20 15:21:16 $
Version: $Revision: 1.14 $
Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
// Disable warning for long symbol names in this file only
#ifdef _MSC_VER
#pragma warning ( disable : 4786 )
#endif
#include <itkImage.h>
#include <itkRecursiveGaussianImageFilter.h>
#include <itkImageRegionIteratorWithIndex.h>
#include <itkImageRegionConstIterator.h>
int itkRecursiveGaussianImageFiltersTest(int, char* [] )
{
{ // 3D test
// Define the dimension of the images
const unsigned int myDimension = 3;
// Declare the types of the images
typedef itk::Image<float, myDimension> myImageType;
// Declare the type of the index to access images
typedef itk::Index<myDimension> myIndexType;
// Declare the type of the size
typedef itk::Size<myDimension> mySizeType;
// Declare the type of the Region
typedef itk::ImageRegion<myDimension> myRegionType;
// Create the image
myImageType::Pointer inputImage = myImageType::New();
// Define their size, and start index
mySizeType size;
size[0] = 100;
size[1] = 100;
size[2] = 100;
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();
// Declare Iterator types apropriated for each image
typedef itk::ImageRegionIteratorWithIndex<myImageType> myIteratorType;
// Create one iterator for the Input Image A (this is a light object)
myIteratorType it( inputImage, inputImage->GetRequestedRegion() );
// Initialize the content of Image A
std::cout << "Input Image initialization " << std::endl;
while( !it.IsAtEnd() )
{
it.Set( 0.0 );
++it;
}
size[0] = 60;
size[1] = 60;
size[2] = 60;
start[0] = 20;
start[1] = 20;
start[2] = 20;
// Create one iterator for an internal region
region.SetSize( size );
region.SetIndex( start );
myIteratorType itb( inputImage, region );
// Initialize the content the internal region
while( !itb.IsAtEnd() )
{
itb.Set( 100.0 );
++itb;
}
// Declare the type for the Gaussian filter
typedef itk::RecursiveGaussianImageFilter<
myImageType,
myImageType
> myGaussianFilterType;
// Create a Filter
myGaussianFilterType::Pointer filter = myGaussianFilterType::New();
// Connect the input images
filter->SetInput( inputImage );
filter->SetDirection( 2 ); // apply along Z
filter->SetOrder( myGaussianFilterType::ZeroOrder );
// Execute the filter
std::cout << "Executing Smoothing filter...";
filter->Update();
std::cout << " Done !" << std::endl;
// Create a Filter
myGaussianFilterType::Pointer filter1 = myGaussianFilterType::New();
// Connect the input images
filter1->SetInput( inputImage );
filter1->SetDirection( 2 ); // apply along Z
filter1->SetOrder( myGaussianFilterType::FirstOrder );
// Execute the filter1
std::cout << "Executing First Derivative filter...";
filter1->Update();
std::cout << " Done !" << std::endl;
// Create a Filter
myGaussianFilterType::Pointer filter2 = myGaussianFilterType::New();
// Connect the input images
filter2->SetInput( inputImage );
filter2->SetDirection( 2 ); // apply along Z
filter2->SetOrder( myGaussianFilterType::SecondOrder );
// Execute the filter2
std::cout << "Executing Second Derivative filter...";
filter2->Update();
std::cout << " Done !" << std::endl;
}
{ // Test normalizations factors using a 1D image
std::cout << "Test normalizations factors using a 1-D image" << std::endl;
typedef float PixelType;
typedef itk::Image< PixelType, 1 > ImageType;
typedef ImageType::SizeType SizeType;
typedef ImageType::IndexType IndexType;
typedef ImageType::RegionType RegionType;
typedef ImageType::SpacingType SpacingType;
typedef itk::NumericTraits< PixelType >::RealType PixelRealType;
SizeType size;
size[0] = 21;
IndexType start;
start[0] = 0;
RegionType region;
region.SetIndex( start );
region.SetSize( size );
SpacingType spacing;
spacing[0] = 1.0;
ImageType::Pointer inputImage = ImageType::New();
inputImage->SetRegions( region );
inputImage->Allocate();
inputImage->SetSpacing( spacing );
inputImage->FillBuffer( itk::NumericTraits< PixelType >::Zero );
IndexType index;
index[0] = ( size[0] - 1 ) / 2; // the middle pixel
inputImage->SetPixel( index, static_cast< PixelType >( 1000.0 ) );
typedef itk::RecursiveGaussianImageFilter<
ImageType, ImageType > FilterType;
FilterType::Pointer filter = FilterType::New();
filter->SetInput( inputImage );
std::cout << "Testing normalization across scales... ";
{ // begin of test for normalization across scales
filter->SetNormalizeAcrossScale( true );
const double sigmaA = 2.0;
filter->SetSigma( sigmaA );
filter->Update();
const PixelType valueA = filter->GetOutput()->GetPixel( index );
const double sigmaB = 4.0;
filter->SetSigma( sigmaB );
filter->Update();
const PixelType valueB = filter->GetOutput()->GetPixel( index );
if( fabs( (valueB - valueA) / valueA ) > 1e-4 )
{
std::cout << "FAILED !" << std::endl;
std::cerr << "Error, Normalization across scales is failing" << std::endl;
std::cerr << "Central pixel at sigma = " << sigmaA << " = " << valueA << std::endl;
std::cerr << "Central pixel at sigma = " << sigmaB << " = " << valueB << std::endl;
return EXIT_FAILURE;
}
else
{
std::cout << "PASSED !" << std::endl;
}
} // end of test for normalization across scales
std::cout << "Testing derivatives normalization " << std::endl;
{ // begin of test for normalization among derivatives
filter->SetNormalizeAcrossScale( false );
// Since one side of the Gaussian is monotonic we can
// use the middle-value theorem: The value of the derivative at
// index[0] - 2 must be bounded by the estimation of the derivative
// at index[0] -1 and index[0] -3. In the following we compute an
// estimation of derivatives by partial differences at this two
// positions and use them as bounds for the value of the first order
// derivative returned by the filter.
const double sigmaC = 3.0;
filter->SetSigma( sigmaC );
filter->SetZeroOrder();
filter->Update();
index[0] = ( size[0] - 1 ) / 2; // the middle pixel
const PixelRealType valueA = filter->GetOutput()->GetPixel( index );
index[0] -= 2;
const PixelRealType valueB = filter->GetOutput()->GetPixel( index );
index[0] -= 2;
const PixelRealType valueC = filter->GetOutput()->GetPixel( index );
const PixelRealType derivativeLowerBound = ( valueA - valueB ) / 2.0;
const PixelRealType derivativeUpperBound = ( valueB - valueC ) / 2.0;
// Now let's get the first derivative value computed by the filter
filter->SetFirstOrder();
filter->Update();
index[0] = ( size[0] - 1 ) / 2; // the middle pixel
index[0] -= 2;
const PixelRealType derivativeValue = filter->GetOutput()->GetPixel( index );
std::cout << " first derivative normalization... ";
if( ( derivativeLowerBound > derivativeValue ) ||
( derivativeUpperBound < derivativeValue ) )
{
std::cout << "FAILED !" << std::endl;
std::cerr << "The value of the first derivative at index " << index[0] << std::endl;
std::cerr << "is = " << derivativeValue << std::endl;
std::cerr << "which is outside the bounds = [ " << derivativeLowerBound;
std::cerr << " : " << derivativeUpperBound << " ] " << std::endl;
return EXIT_FAILURE;
}
else
{
std::cout << "PASSED !" << std::endl;
}
// Now do the similar testing between First Derivative and Second
// derivative.
filter->SetFirstOrder();
filter->Update();
index[0] = ( size[0] - 1 ) / 2; // the middle pixel
const PixelRealType value1A = filter->GetOutput()->GetPixel( index );
index[0] -= 2;
const PixelRealType value1B = filter->GetOutput()->GetPixel( index );
index[0] -= 2;
const PixelRealType value1C = filter->GetOutput()->GetPixel( index );
// NOTE that the second derivative in this region is monotonic but decreasing.
const PixelRealType secondDerivativeLowerBound = ( value1A - value1B ) / 2.0;
const PixelRealType secondDerivativeUpperBound = ( value1B - value1C ) / 2.0;
// Now let's get the second derivative value computed by the filter
filter->SetSecondOrder();
filter->Update();
index[0] = (( size[0] - 1 ) / 2) - 2; // where to sample the second derivative
const PixelRealType secondDerivativeValue = filter->GetOutput()->GetPixel( index );
std::cout << " second derivative normalization... ";
if( ( secondDerivativeLowerBound > secondDerivativeValue ) ||
( secondDerivativeUpperBound < secondDerivativeValue ) )
{
std::cout << "FAILED !" << std::endl;
std::cerr << "The value of the second derivative at index " << index[0] << std::endl;
std::cerr << "is = " << secondDerivativeValue << std::endl;
std::cerr << "which is outside the bounds = [ " << secondDerivativeLowerBound;
std::cerr << " : " << secondDerivativeUpperBound << " ] " << std::endl;
return EXIT_FAILURE;
}
else
{
std::cout << "PASSED !" << std::endl;
}
} // end of test for normalization among derivatives
// Print out all the values for the zero, first and second order
filter->SetNormalizeAcrossScale( false );
filter->SetSigma( 2.0 );
ImageType::ConstPointer outputImage = filter->GetOutput();
typedef itk::ImageRegionConstIterator< ImageType > IteratorType;
IteratorType it( outputImage, outputImage->GetBufferedRegion() );
std::cout << std::endl << std::endl;
std::cout << "Smoothed image " << std::endl;
filter->SetZeroOrder();
filter->Update();
it.GoToBegin();
while( ! it.IsAtEnd() )
{
std::cout << it.Get() << std::endl;
++it;
}
// Now compute the first derivative
std::cout << std::endl << std::endl;
std::cout << "First Derivative " << std::endl;
filter->SetFirstOrder();
filter->Update();
it.GoToBegin();
while( ! it.IsAtEnd() )
{
std::cout << it.Get() << std::endl;
++it;
}
// Now compute the first derivative
std::cout << std::endl << std::endl;
std::cout << "Second Derivative " << std::endl;
filter->SetSecondOrder();
filter->Update();
it.GoToBegin();
while( ! it.IsAtEnd() )
{
std::cout << it.Get() << std::endl;
++it;
}
}
// All objects should be automatically destroyed at this point
return EXIT_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -