[ITK Community] [Insight-users] c++ code for getting the inverse displacement field form Demon's registration

Tim Bhatnagar tim.bhatnagar at gmail.com
Thu Jan 2 16:32:08 EST 2014


Hello all,

Would anyone have a WORKING c++/source file that successfully
generates/acquires the inverse displacement field from a Demon's non-rigid
registration field?

Many users have been helping me in achieving this, though I'm worried that
I'm losing some of the finer points in my code implementation.. this is
what I have so far, and it compiles, but the program always crashes at the
same point, after a negative index is created for my new field...

any help is much appreciated.. my c++ code is below:

#include "itkInverseDisplacementFieldImageFilter.h"
#include "itkImageFileWriter.h"
#include "itkImageFileReader.h"
#include "itkFilterWatcher.h"
#include "itkVectorScaleImageFilter.h"
#include "itkImage.h"
#include "itkArray.h"

int main( int argc, char * argv[] )
{

  if( argc < 4 )
    {
    std::cerr << "Missing Parameters " << std::endl;
    std::cerr << "Usage: " << argv[0];
    std::cerr << "inputDemonsField subSampFactor outputInvertedField" <<
std::endl;
    return EXIT_FAILURE;
    }

  const     unsigned int Dimension = 3;
  typedef   float VectorComponentType;

  typedef   itk::Vector< VectorComponentType, Dimension > VectorType;

  typedef itk::Image< VectorType,  Dimension > DisplacementFieldType;

  typedef itk::Array< VectorType > ArrayType;

  typedef itk::InverseDisplacementFieldImageFilter<
    DisplacementFieldType,
    DisplacementFieldType
    >  FilterType;

  FilterType::Pointer filter = FilterType::New();

  FilterWatcher watcher(filter);

  // Read a DisplacementField
  typedef itk::ImageFileReader<  DisplacementFieldType  > ReaderType;

  ReaderType::Pointer reader = ReaderType::New();

  reader->SetFileName( argv[1] );

  reader->Update();


  // Obtaining an input displacement field
  DisplacementFieldType::Pointer field = reader->GetOutput();

  DisplacementFieldType::RegionType inputRegion;
  DisplacementFieldType::SizeType inputSize;
  DisplacementFieldType::DirectionType inputDirection;
  DisplacementFieldType::PointType inputOrigin;
  DisplacementFieldType::SpacingType inputSpacing;

  inputRegion = field->GetLargestPossibleRegion();
  inputSize = field->GetLargestPossibleRegion().GetSize();
  inputDirection =  field->GetDirection();
  inputOrigin =  field->GetOrigin();
  inputSpacing =  field->GetSpacing();
  inputRegion.SetIndex(field->GetLargestPossibleRegion().GetIndex());

  DisplacementFieldType::Pointer outField = DisplacementFieldType::New();




   itk::ImageRegionIteratorWithIndex< DisplacementFieldType > it( field,
inputRegion );

   filter->SetOutputSpacing( field->GetSpacing() );
   filter->SetOutputOrigin( field->GetOrigin() );
   filter->SetSize( inputSize );

  filter->SetInput( field );
  filter->SetSubsamplingFactor( atof(argv[2]) );

  try
    {
    filter->UpdateLargestPossibleRegion();
    }
  catch( itk::ExceptionObject & excp )
    {
    std::cerr << "Exception thrown " << std::endl;
    std::cerr << excp << std::endl;
    }

  // Make template to ensure proper indexing of new def field

  DisplacementFieldType::Pointer outField = filter->GetOutput();
  DisplacementFieldType::RegionType outputRegion;

   outputRegion.SetIndex( inputRegion.GetIndex() );

  // Write an image for regression testing
  typedef itk::ImageFileWriter<  DisplacementFieldType  > WriterType;

  WriterType::Pointer writer = WriterType::New();

  outField->Update();
  writer->SetInput (outField );
  writer->SetFileName( argv[3] );

  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & excp )
    {
    std::cerr << "Exception thrown by writer" << std::endl;
    std::cerr << excp << std::endl;
    return EXIT_FAILURE;
    }




  // Now, test for loop invariant (acts as filter validation)
  // f^-1(f(p1) + p1 ) - f(p1)  = 0
  it.GoToBegin();
  while( !it.IsAtEnd() )
    {

    DisplacementFieldType::PointType p1;
    field->TransformIndexToPhysicalPoint(it.GetIndex(), p1);

    DisplacementFieldType::PixelType fp1 = it.Get();

    DisplacementFieldType::PointType p2;
    p2[0] = p1[0] + fp1[0];
    p2[1] = p1[1] + fp1[1];
    p2[2] = p1[2] + fp1[2];

    DisplacementFieldType::IndexType id2;
    outField->TransformPhysicalPointToIndex(p2,id2);
    //filter->GetOutput()->TransformPhysicalPointToIndex(p2,id2);
    std::cerr << "hurrah" << id2 << std::endl;
    DisplacementFieldType::PixelType fp2 = outField->GetPixel(id2);
    //DisplacementFieldType::PixelType fp2 =
filter->GetOutput()->GetPixel(id2);
    std::cerr << "hurrah2" << std::endl;


    if(vcl_abs(fp2[0] + fp1[0]) > 100.000
       || vcl_abs(fp2[1] + fp1[1]) > 100.000
       || vcl_abs(fp2[2] + fp1[2]) > 100.000)
      {
      std::cerr<<"Loop invariant not satisfied for index
"<<it.GetIndex()<<" : f^-1(f(p1) + p1 ) + f(p1)  = 0"<<   std::endl;
      std::cerr<<"f(p1) = "<<fp1<<std::endl;
      std::cerr<<"f^-1(f(p1) + p1 ) = "<<fp2<<std::endl;
      std::cerr<<"diff: "<<fp1[0]+fp2[0]<<", "<<fp1[1]+fp2[1]<<",
"<<fp1[2]+fp2[2]<<std::endl;
    //  return EXIT_FAILURE;
      }
    ++it;
    }

  return EXIT_SUCCESS;

}

-- 
Tim Bhatnagar
PhD Candidate
Orthopaedic Injury Biomechanics Group
Department of Mechanical Engineering
University of British Columbia

Rm 5000 - 818 West 10th Ave.
Vancouver, BC
Canada
V5Z 1M9

Ph: (604) 675-8845
Fax: (604) 675-8820
Web: oibg.mech.ubc.ca
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/community/attachments/20140102/e364ed55/attachment.html>
-------------- next part --------------
_____________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html

Kitware offers ITK Training Courses, for more information visit:
http://www.kitware.com/products/protraining.php

Please keep messages on-topic and check the ITK FAQ at:
http://www.itk.org/Wiki/ITK_FAQ

Follow this link to subscribe/unsubscribe:
http://www.itk.org/mailman/listinfo/insight-users


More information about the Community mailing list