template <class TFilter>
{
public:
using Self = CommandIterationUpdate;
itkNewMacro(Self);
protected:
CommandIterationUpdate() = default;
public:
void
{
}
void
{
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;
using ThresholdingFilterType =
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]);
using CastFilterType =
using SmoothingFilterType =
InternalImageType>;
SmoothingFilterType::Pointer smoothing = SmoothingFilterType::New();
using GradientFilterType =
InternalImageType>;
GradientFilterType::Pointer gradientMagnitude = GradientFilterType::New();
using FastMarchingFilterType =
FastMarchingFilterType::Pointer fastMarching =
FastMarchingFilterType::New();
using GeodesicActiveContourFilterType =
InternalImageType,
InternalImageType>;
GeodesicActiveContourFilterType::Pointer geodesicActiveContour =
GeodesicActiveContourFilterType::New();
using CenterFilterType =
CenterFilterType::Pointer center = CenterFilterType::New();
center->CenterImageOn();
using ReciprocalFilterType =
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]);
using ShapeFunctionType =
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);
using CostFunctionType =
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();
}
catch (const itk::ExceptionObject & excep)
{
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();
using EvaluatorFilterType =
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;
}