How to fix the problem of "Too many samples map outside moving image buffer"

registration

(Jounly) #1

Hi, I am using MattesMutualInformationImageToImageMetricv4 as the metric in the registration frame. However, it always fails and throws the exception of
“Too many samples map outside moving image buffer. There are only 3528 valid points out of 655492 total points. The images do not sufficiently overlap. They need to be initialized to have more overlap before this metric will work. For instance, you can align the image centers by translation.”
At first, I thought it was because the two images were not overlapped enough, so I used the CenteredTransformInitializer to initialize the transform. However, it didn’t help. Then I set the moving image and fix image as the same image, that should be 100% overlap, however, still the same exception. So I am very confused about this. Hope anyone can give me any advice on this issue, thanks in advance! To help you analyze, below is my code.

typedef itk::Euler3DTransform TransformType;
TransformType::Pointer transform = TransformType::New();

// optimizer type
typedef itk::OnePlusOneEvolutionaryOptimizerv4<double> OptimizerType;
OptimizerType::Pointer optimizer = OptimizerType::New();

// metrics
typedef itk::MattesMutualInformationImageToImageMetricv4<ImageType2,
                                                         ImageType2>
    MetricsType;
MetricsType::Pointer metric = MetricsType::New();

// registration type
typedef itk::ImageRegistrationMethodv4<ImageType2, ImageType2>
    RegistrationType;
RegistrationType::Pointer registration = RegistrationType::New();

// set up transform
typedef itk::CenteredTransformInitializer<TransformType, ImageType2,
                                          ImageType2>
    CenterInitializerType;
CenterInitializerType::Pointer centerInitializer =
    CenterInitializerType::New();
centerInitializer->SetTransform(transform);
centerInitializer->SetFixedImage(movingImage);
centerInitializer->SetMovingImage(movingImage);
centerInitializer->MomentsOn();
centerInitializer->InitializeTransform();
// set up optimizer
typedef itk::Statistics::NormalVariateGenerator GeneratorType;
GeneratorType::Pointer generator = GeneratorType::New();
generator->Initialize(23);

optimizer->SetNormalVariateGenerator(generator);
optimizer->Initialize(10);
optimizer->SetEpsilon(1.0);
optimizer->SetMaximumIteration(4000);

// set up metrics
metric->SetMovingImage(movingImage);
metric->SetFixedImage(movingImage);
metric->SetNumberOfHistogramBins(50);
metric->UseFixedImageGradientFilterOff();
metric->UseMovingImageGradientFilterOff();
// set up registration
registration->SetOptimizer(optimizer);
registration->SetMetric(metric);
registration->SetMetricSamplingPercentage(0.7);
RegistrationType::MetricSamplingStrategyType samplingStrategy =
    RegistrationType::REGULAR;
registration->SetMetricSamplingStrategy(samplingStrategy);
registration->SetMovingImage(movingImage);
registration->SetFixedImage(movingImage);
registration->SetNumberOfThreads(1);
registration->SetInitialTransform(transform);
registration->InPlaceOn();

const unsigned int numberOfLevels = 1;

RegistrationType::ShrinkFactorsArrayType shrinkFactorsPerLevel;
shrinkFactorsPerLevel.SetSize(1);
shrinkFactorsPerLevel[0] = 1;

RegistrationType::SmoothingSigmasArrayType smoothingSigmasPerLevel;
smoothingSigmasPerLevel.SetSize(1);
smoothingSigmasPerLevel[0] = 0;

registration->SetNumberOfLevels(numberOfLevels);
registration->SetSmoothingSigmasPerLevel(smoothingSigmasPerLevel);
registration->SetShrinkFactorsPerLevel(shrinkFactorsPerLevel);

try {
  registration->Update();
  qDebug() << "Registration completed!";
  qDebug() << "Optimizer stop condition: "
           << registration->GetOptimizer()->GetValue();
} catch (itk::ExceptionObject &err) {
  qDebug() << "ExceptionObject caught !";
  qDebug() << err.GetDescription();
}