template<class TFilter>
{
public:
using Self = CommandIterationUpdate;
itkNewMacro( Self );
protected:
CommandIterationUpdate() = default;
public:
{
}
{
const auto * filter = static_cast< const TFilter * >( object );
if( typeid( event ) != typeid( itk::IterationEvent ) )
{ return; }
std::cout << filter->GetElapsedIterations() << ": ";
std::cout << filter->GetRMSChange() << " ";
std::cout << filter->GetCurrentParameters() << std::endl;
}
};
int main( int argc, char *argv[] )
{
if( argc < 18 )
{
std::cerr << "Missing Parameters " << std::endl;
std::cerr << "Usage: " << argv[0];
std::cerr << " inputImage outputImage";
std::cerr << " seed1X seed1Y";
std::cerr << " seed2X seed2Y";
std::cerr << " seed3X seed3Y";
std::cerr << " initialDistance";
std::cerr << " sigma";
std::cerr << " propagationScaling shapePriorScaling";
std::cerr << " meanShapeImage numberOfModes shapeModeFilePattern";
std::cerr << " startX startY" << std::endl;
return EXIT_FAILURE;
}
using InternalPixelType = float;
using OutputPixelType = unsigned char;
InternalImageType,
OutputImageType >;
ThresholdingFilterType::Pointer thresholder = ThresholdingFilterType::New();
thresholder->SetLowerThreshold( -1000.0 );
thresholder->SetUpperThreshold( 0.0 );
thresholder->SetOutsideValue( 0 );
thresholder->SetInsideValue( 255 );
ReaderType::Pointer reader = ReaderType::New();
WriterType::Pointer writer = WriterType::New();
reader->SetFileName( argv[1] );
writer->SetFileName( argv[2] );
InternalImageType,
OutputImageType >;
InternalImageType,
InternalImageType >;
SmoothingFilterType::Pointer smoothing = SmoothingFilterType::New();
InternalImageType,
InternalImageType >;
GradientFilterType::Pointer gradientMagnitude = GradientFilterType::New();
InternalImageType,
InternalImageType >;
FastMarchingFilterType::Pointer fastMarching = FastMarchingFilterType::New();
using GeodesicActiveContourFilterType =
InternalImageType, InternalImageType >;
GeodesicActiveContourFilterType::Pointer geodesicActiveContour =
GeodesicActiveContourFilterType::New();
using CenterFilterType =
CenterFilterType::Pointer center = CenterFilterType::New();
center->CenterImageOn();
InternalImageType,
InternalImageType >;
ReciprocalFilterType::Pointer reciprocal = ReciprocalFilterType::New();
const double propagationScaling = std::stod( argv[11] );
const double shapePriorScaling = std::stod( argv[12] );
geodesicActiveContour->SetPropagationScaling( propagationScaling );
geodesicActiveContour->SetShapePriorScaling( shapePriorScaling );
geodesicActiveContour->SetCurvatureScaling( 1.0 );
geodesicActiveContour->SetAdvectionScaling( 1.0 );
geodesicActiveContour->SetMaximumRMSError( 0.005 );
geodesicActiveContour->SetNumberOfIterations( 400 );
geodesicActiveContour->SetNumberOfLayers( 4 );
center->SetInput( reader->GetOutput() );
smoothing->SetInput( center->GetOutput() );
gradientMagnitude->SetInput( smoothing->GetOutput() );
reciprocal->SetInput( gradientMagnitude->GetOutput() );
geodesicActiveContour->SetInput( fastMarching->GetOutput() );
geodesicActiveContour->SetFeatureImage( reciprocal->GetOutput() );
thresholder->SetInput( geodesicActiveContour->GetOutput() );
writer->SetInput( thresholder->GetOutput() );
smoothing->SetTimeStep( 0.125 );
smoothing->SetNumberOfIterations( 5 );
smoothing->SetConductanceParameter( 9.0 );
const double sigma = std::stod( argv[10] );
gradientMagnitude->SetSigma( sigma );
using NodeContainer = FastMarchingFilterType::NodeContainer;
using NodeType = FastMarchingFilterType::NodeType;
NodeContainer::Pointer seeds = NodeContainer::New();
seedPosition[0] = std::stoi( argv[3] );
seedPosition[1] = std::stoi( argv[4] );
const double initialDistance = std::stod( argv[9] );
NodeType node;
const double seedValue = - initialDistance;
node.SetValue( seedValue );
node.SetIndex( seedPosition );
seeds->Initialize();
seeds->InsertElement( 0, node );
seedPosition[0] = std::stoi( argv[5] );
seedPosition[1] = std::stoi( argv[6] );
node.SetIndex( seedPosition );
seeds->InsertElement( 1, node );
seedPosition[0] = std::stoi( argv[7] );
seedPosition[1] = std::stoi( argv[8] );
node.SetIndex( seedPosition );
seeds->InsertElement( 2, node );
fastMarching->SetTrialPoints( seeds );
fastMarching->SetSpeedConstant( 1.0 );
CastFilterType::Pointer caster1 = CastFilterType::New();
CastFilterType::Pointer caster2 = CastFilterType::New();
CastFilterType::Pointer caster3 = CastFilterType::New();
CastFilterType::Pointer caster4 = CastFilterType::New();
WriterType::Pointer writer1 = WriterType::New();
WriterType::Pointer writer2 = WriterType::New();
WriterType::Pointer writer3 = WriterType::New();
WriterType::Pointer writer4 = WriterType::New();
caster1->SetInput( smoothing->GetOutput() );
writer1->SetInput( caster1->GetOutput() );
writer1->SetFileName("GeodesicActiveContourShapePriorImageFilterOutput1.png");
caster1->SetOutputMinimum( 0 );
caster1->SetOutputMaximum( 255 );
writer1->Update();
caster2->SetInput( gradientMagnitude->GetOutput() );
writer2->SetInput( caster2->GetOutput() );
writer2->SetFileName("GeodesicActiveContourShapePriorImageFilterOutput2.png");
caster2->SetOutputMinimum( 0 );
caster2->SetOutputMaximum( 255 );
writer2->Update();
caster3->SetInput( reciprocal->GetOutput() );
writer3->SetInput( caster3->GetOutput() );
writer3->SetFileName("GeodesicActiveContourShapePriorImageFilterOutput3.png");
caster3->SetOutputMinimum( 0 );
caster3->SetOutputMaximum( 255 );
writer3->Update();
caster4->SetInput( fastMarching->GetOutput() );
writer4->SetInput( caster4->GetOutput() );
writer4->SetFileName("GeodesicActiveContourShapePriorImageFilterOutput4.png");
caster4->SetOutputMinimum( 0 );
caster4->SetOutputMaximum( 255 );
fastMarching->SetOutputRegion(
center->GetOutput()->GetBufferedRegion() );
fastMarching->SetOutputSpacing(
center->GetOutput()->GetSpacing() );
fastMarching->SetOutputOrigin(
center->GetOutput()->GetOrigin() );
const unsigned int numberOfPCAModes = std::stoi( argv[14] );
double,
InternalImageType >;
ShapeFunctionType::Pointer shape = ShapeFunctionType::New();
shape->SetNumberOfPrincipalComponents( numberOfPCAModes );
ReaderType::Pointer meanShapeReader = ReaderType::New();
meanShapeReader->SetFileName( argv[13] );
meanShapeReader->Update();
std::vector<InternalImageType::Pointer> shapeModeImages( numberOfPCAModes );
fileNamesCreator->SetStartIndex( 0 );
fileNamesCreator->SetEndIndex( numberOfPCAModes - 1 );
fileNamesCreator->SetSeriesFormat( argv[15] );
const std::vector<std::string> & shapeModeFileNames =
fileNamesCreator->GetFileNames();
for (unsigned int k = 0; k < numberOfPCAModes; ++k )
{
ReaderType::Pointer shapeModeReader = ReaderType::New();
shapeModeReader->SetFileName( shapeModeFileNames[k].c_str() );
shapeModeReader->Update();
shapeModeImages[k] = shapeModeReader->GetOutput();
}
shape->SetMeanImage( meanShapeReader->GetOutput() );
shape->SetPrincipalComponentImages( shapeModeImages );
ShapeFunctionType::ParametersType pcaStandardDeviations( numberOfPCAModes );
pcaStandardDeviations.Fill( 1.0 );
shape->SetPrincipalComponentStandardDeviations( pcaStandardDeviations );
TransformType::Pointer transform = TransformType::New();
shape->SetTransform( transform );
InternalImageType,
InternalPixelType >;
CostFunctionType::Pointer costFunction = CostFunctionType::New();
CostFunctionType::WeightsType weights;
weights[0] = 1.0;
weights[1] = 20.0;
weights[2] = 1.0;
weights[3] = 1.0;
costFunction->SetWeights( weights );
CostFunctionType::ArrayType mean( shape->GetNumberOfShapeParameters() );
CostFunctionType::ArrayType stddev( shape->GetNumberOfShapeParameters() );
mean.Fill( 0.0 );
stddev.Fill( 1.0 );
costFunction->SetShapeParameterMeans( mean );
costFunction->SetShapeParameterStandardDeviations( stddev );
OptimizerType::Pointer optimizer = OptimizerType::New();
GeneratorType::Pointer generator = GeneratorType::New();
generator->Initialize( 20020702 );
optimizer->SetNormalVariateGenerator( generator );
OptimizerType::ScalesType scales( shape->GetNumberOfParameters() );
scales.Fill( 1.0 );
for( unsigned int k = 0; k < numberOfPCAModes; k++ )
{
scales[k] = 20.0;
}
scales[numberOfPCAModes] = 350.0;
optimizer->SetScales( scales );
double initRadius = 1.05;
double grow = 1.1;
double shrink = pow(grow, -0.25);
optimizer->Initialize(initRadius, grow, shrink);
optimizer->SetEpsilon(1.0
e-6);
optimizer->SetMaximumIteration(15);
ShapeFunctionType::ParametersType parameters(
shape->GetNumberOfParameters() );
parameters.Fill( 0.0 );
parameters[numberOfPCAModes + 1] = std::stod( argv[16] );
parameters[numberOfPCAModes + 2] = std::stod( argv[17] );
geodesicActiveContour->SetShapeFunction( shape );
geodesicActiveContour->SetCostFunction( costFunction );
geodesicActiveContour->SetOptimizer( optimizer );
geodesicActiveContour->SetInitialParameters( parameters );
using CommandType = CommandIterationUpdate<GeodesicActiveContourFilterType>;
CommandType::Pointer observer = CommandType::New();
geodesicActiveContour->AddObserver( itk::IterationEvent(), observer );
try
{
writer->Update();
}
{
std::cerr << "Exception caught !" << std::endl;
std::cerr << excep << std::endl;
return EXIT_FAILURE;
}
std::cout << std::endl;
std::cout << "Max. no. iterations: " << geodesicActiveContour->GetNumberOfIterations() << std::endl;
std::cout << "Max. RMS error: " << geodesicActiveContour->GetMaximumRMSError() << std::endl;
std::cout << std::endl;
std::cout << "No. elpased iterations: " << geodesicActiveContour->GetElapsedIterations() << std::endl;
std::cout << "RMS change: " << geodesicActiveContour->GetRMSChange() << std::endl;
std::cout << "Parameters: " << geodesicActiveContour->GetCurrentParameters() << std::endl;
writer4->Update();
InternalWriterType::Pointer mapWriter = InternalWriterType::New();
mapWriter->SetInput( fastMarching->GetOutput() );
mapWriter->SetFileName("GeodesicActiveContourShapePriorImageFilterOutput4.mha");
mapWriter->Update();
InternalWriterType::Pointer speedWriter = InternalWriterType::New();
speedWriter->SetInput( reciprocal->GetOutput() );
speedWriter->SetFileName("GeodesicActiveContourShapePriorImageFilterOutput3.mha");
speedWriter->Update();
InternalWriterType::Pointer gradientWriter = InternalWriterType::New();
gradientWriter->SetInput( gradientMagnitude->GetOutput() );
gradientWriter->SetFileName("GeodesicActiveContourShapePriorImageFilterOutput2.mha");
gradientWriter->Update();
ShapeFunctionType,
InternalImageType,
InternalImageType >;
EvaluatorFilterType::Pointer evaluator = EvaluatorFilterType::New();
evaluator->SetInput( geodesicActiveContour->GetOutput() );
evaluator->SetFunction( shape );
shape->SetParameters( geodesicActiveContour->GetInitialParameters() );
thresholder->SetInput( evaluator->GetOutput() );
writer->SetFileName( "GeodesicActiveContourShapePriorImageFilterOutput5.png" );
writer->Update();
shape->SetParameters( geodesicActiveContour->GetCurrentParameters() );
evaluator->Modified();
writer->SetFileName( "GeodesicActiveContourShapePriorImageFilterOutput6.png" );
writer->Update();
return EXIT_SUCCESS;
}