Issues with bounded deformable registration [SOLVED]

Hello,

I’ve been utilizing a module in an image processing program 3D Slicer and it has the ability to perform BSpline Registration when the registration is unbounded or when the image’s physical coordinates can move without limit. When I impose a bound the program runs to completion, but the returned transform produced by the module has no appreciable affect on the image and I can’t visibly detect a difference. I’ve tried different values for this parameter and nothing will cause the program to produce a transformation which visibly changes anything when applied to images/models/etc.

The source code for the part of the module is here:

typedef typename itk::LBFGSBOptimizerv4 LBFGSBOptimizerType;
typedef typename LBFGSBOptimizerType::Pointer LBFGSBOptimizerTypePointer;
typedef typename LBFGSBOptimizerType::BoundSelectionType OptimizerBoundSelectionType;
typedef typename LBFGSBOptimizerType::BoundValueType OptimizerBoundValueType;

  LBFGSBOptimizerTypePointer      LBFGSBoptimizer     = LBFGSBOptimizerType::New();

  // TODO:  For control points outside the fixed image mask, it might be good to
  // constrian
  // the parameters to something different than those control points inside the
  // fixed image mask.

  OptimizerBoundSelectionType boundSelect( bsplineTx->GetNumberOfParameters() );
  if( std::abs(m_MaxBSplineDisplacement) < 1e-12 )
    {
    boundSelect.Fill( LBFGSBOptimizerType::UNBOUNDED );
    }
  else
    {
    boundSelect.Fill( LBFGSBOptimizerType::BOTHBOUNDED );
    }
  OptimizerBoundValueType upperBound( bsplineTx->GetNumberOfParameters() );
  upperBound.Fill(m_MaxBSplineDisplacement);
  OptimizerBoundValueType lowerBound( bsplineTx->GetNumberOfParameters() );
  lowerBound.Fill(-m_MaxBSplineDisplacement);

  LBFGSBoptimizer->SetBoundSelection(boundSelect);
  //std::cout << "PRE : " << LBFGSBoptimizer->GetUpperBound().size() << " " << upperBound.size() << std::endl;
  LBFGSBoptimizer->SetUpperBound(upperBound);
  //std::cout << "POST: " << LBFGSBoptimizer->GetUpperBound().size() << " " << upperBound.size() << std::endl;

  //std::cout << "PRE : " << LBFGSBoptimizer->GetLowerBound().size() << " " << lowerBound.size() << std::endl;
  LBFGSBoptimizer->SetLowerBound(lowerBound);
  //std::cout << "POST: " << LBFGSBoptimizer->GetLowerBound().size() << " " << lowerBound.size() << std::endl;

I’ve looked for any source code to verify that this is how to set the bounds since the ITK examples don’t seem to utilize bounds for deformable registration examples. The code that the module uses looks correct to me, but I don’t have anything to compare to. If anybody has been successful in imposing bounds while using deformable registration, that would be extremely helpful to me.

I’ve figured out the issue. The code provided was functional, however a parameter “CostFunctionConvergenceFactor” had to be altered for me when applying a value for Maximum B-Spline Displacement. I had to decrease this by a factor of 100 to get results as it seemed that with the higher factor that the registration would converge immediately without changing.

2 Likes