ImageRegistrationMethodv4 crashes Unexpectedly

Hello,
I am relatively new ITK user and I am trying to implement affine registration in C++. After going through examples, I was able to put together a reasonable solution. However, when I run it it crashes unexpectedly with the following call stack:

ITK-5.2/itkImageConstIteratorWithIndex.hxx:103:18: runtime error: applying non-zero offset 4194300 to null pointer
::ImageConstIteratorWithIndex ITK-5.2/itkImageConstIteratorWithIndex.hxx:103
::ImageRandomConstIteratorWithIndex ITK-5.2/itkImageRandomConstIteratorWithIndex.hxx:41
::SetMetricSamplePoints() ITK-5.2/itkImageRegistrationMethodv4.hxx:1028
::InitializeRegistrationAtEachLevel(unsigned long) ITK-5.2/itkImageRegistrationMethodv4.hxx:734
 

Looking through the header files/source code, it appears to me that this is something to do with VirtualDomainImage. I am a little surprised by this, since my understanding was that mapping between fixed image and VirtualDomainImage was identity by default and I don’t have to specify that explicitly. Am I missing something? I would greatly appreciate your help. Thank you, in advance!

For completeness, my source code is listed below.

using ImageType = itk::Image<float, 2>;
using TransformType = itk::AffineTransform<double, 2>;
using MetricType = itk::CorrelationImageToImageMetricv4<ImageType, ImageType>;
using RegistrationType = itk::ImageRegistrationMethodv4<ImageType, ImageType>;
using OptimizerType = itk::RegularStepGradientDescentOptimizerv4<double>;
using TransformInitializerType =
    itk::CenteredTransformInitializer<TransformType, ImageType, ImageType>;
using InterpolatorType = itk::LinearInterpolateImageFunction<ImageType, double>;

affine_transform(const ImageType::Pointer fixedImage, const ImageType::Pointer movingImage) {
  auto initialTransform = TransformType::New();
  auto transformInitializer = TransformInitializerType::New();
  transformInitializer->SetFixedImage(fixedImage);
  transformInitializer->SetMovingImage(movingImage);
  transformInitializer->SetTransform(initialTransform);
  transformInitializer->GeometryOn();
  transformInitializer->InitializeTransform();

  auto optimizer = OptimizerType::New();
  optimizer->SetLearningRate(4);
  optimizer->SetMinimumStepLength(0.001);
  optimizer->SetNumberOfIterations(200);
  optimizer->SetRelaxationFactor(0.5);
  optimizer->SetGradientMagnitudeTolerance(1e-4);
  
  auto metric = MetricType::New();
  auto fixedIinterpolator = InterpolatorType::New();
  auto movingInterpolator = InterpolatorType::New();
  metric->SetFixedInterpolator(fixedIinterpolator);
  metric->SetMovingInterpolator(movingInterpolator);

  auto scaleEstimator =
      itk::RegistrationParameterScalesFromPhysicalShift<MetricType>::New();
  scaleEstimator->SetCentralRegionRadius(5);
  scaleEstimator->SetSmallParameterVariation(0.01);
  scaleEstimator->SetMetric(metric);
  scaleEstimator->SetTransformForward(true);
  optimizer->SetScalesEstimator(scaleEstimator);

  auto registration = RegistrationType::New();
  registration->SetInitialTransform(initialTransform);
  registration->SetMovingInitialTransform(initialTransform);
  registration->SetMetric(metric);
  registration->SetOptimizer(optimizer);
  registration->SetFixedImage(fixedImage);
  registration->SetMovingImage(movingImage);
  registration->SetInPlace(true);
  registration->SetNumberOfLevels(1);
  
  registration->SetMetricSamplingStrategy(itk::ImageRegistrationMethodv4Enums::MetricSamplingStrategy::RANDOM);
  registration->SetMetricSamplingPercentage(0.01);

  auto identityTransform = TransformType::New();
  identityTransform->SetIdentity();
  registration->SetFixedInitialTransform(identityTransform);

   try {
    registration->Update();
    } catch (const itk::ExceptionObject& err) {
      std::cerr << "ExceptionObject caught !" << std::endl;
      std::cerr << err << std::endl;
      return NULL;
   }
  
  initialTransform->Register();
  return initialTransform.GetPointer();
}