[Insight-users] How to buid code for individual template function or class

Baoyun Li baoyun_li123 at yahoo.com
Tue Feb 24 10:38:00 EST 2009


Dear All:

I trying to use some function template in my code. The below code is reading an image and do isotropic resampling. Now I put main function and function template in signle .cxx file. The code can be run.

1: I want to seperate my function template with main function. If I put the whole implementation of templation function in .h file, I can make the exctable file.
2: If I want have individual implementation file .txx or .cxx( I tried all) and plus the header file, the code cannot be compiled and showed undefined reference to the template function. I did a google search, seems G++ requires to put all the implementation in the header.
3: I double the above requirement greatly. Since many of ITK template class has .txx and .h file. Can somebody teach me how can I compile the code when the .txx and .h and main code are seperate files.

Thanks 
Baoyun


#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif
#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif

#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
// Software Guide : BeginCodeSnippet
#include "itkResampleImageFilter.h"
#include "itkRecursiveGaussianImageFilter.h"
// Software Guide : EndCodeSnippet



// Software Guide : BeginCodeSnippet
#include "itkIdentityTransform.h"
#include "itkLinearInterpolateImageFunction.h"
#include "itkAffineTransform.h"
// Software Guide : EndCodeSnippet
// Software Guide : BeginCodeSnippet
#include "itkIntensityWindowingImageFilter.h"
#include "itkCastImageFilter.h"
// Software Guide : EndCodeSnippet
template <class TInputFilter, class TInternalFilter, class TScale>
void ConfidenceConnected( TInputFilter* InputFilter, TInternalFilter* InternalFilter, TScale scale)
{
  
  //typedef typename TInputFilter::OutputImageType InputImageType;
  typedef typename TInputFilter::OutputImageType OutputImageType;
  typedef typename TInternalFilter::OutputImageType InternalImageType;
  typedef typename TInternalFilter::InputImageType InputImageType;
}

template <class TInputFilter, class TInternalFilter, class TScale>
void IsotropicResample( TInputFilter* InputFilter, TInternalFilter* InternalFilter, TScale scale)
{
  
  //typedef typename TInputFilter::OutputImageType InputImageType;
  typedef typename TInputFilter::OutputImageType OutputImageType;
  typedef typename TInternalFilter::OutputImageType InternalImageType;
  typedef typename TInternalFilter::InputImageType InputImageType;
   //typedef  TInputFilter InputImageType;
  typedef itk::ImageFileWriter< InternalImageType >  WriterType1;
  typename WriterType1::Pointer writer1=WriterType1::New();
    typedef itk::CastImageFilter< InputImageType,InternalImageType> CastingFilterType1;
    typename CastingFilterType1::Pointer caster11 = CastingFilterType1::New();
    typedef itk::CastImageFilter< InternalImageType,OutputImageType> CastingFilterType2;
    typename CastingFilterType1::Pointer caster21 = CastingFilterType1::New();
    typedef itk::RecursiveGaussianImageFilter< 
                                InternalImageType,
                                 InternalImageType > GaussianFilterType;
   
   
  
  InputFilter->Update();
  //InternalFilter->SetInput(InputFilter->GetOutput());
  //InternalFilter->Update();
  typename InputImageType::ConstPointer inputImage = InputFilter->GetOutput();
  typename InputImageType::SpacingType inputSpacing= inputImage->GetSpacing();
  
  const double isoSpacing = sqrt( inputSpacing[2] * inputSpacing[0] )*scale;
  caster11->SetInput(InputFilter->GetOutput());
  typedef itk::ResampleImageFilter<
                InternalImageType, OutputImageType >  ResampleFilterType;
  typename  ResampleFilterType::Pointer resampler = ResampleFilterType::New();
 
  typename GaussianFilterType::Pointer smootherX = GaussianFilterType::New();
  typename GaussianFilterType::Pointer smootherY = GaussianFilterType::New();
  typename GaussianFilterType::Pointer smootherZ = GaussianFilterType::New();
 if(inputSpacing[0]<isoSpacing&&inputSpacing[3]<isoSpacing)
    {
       smootherX->SetInput( caster11->GetOutput() );
       smootherY->SetInput( smootherX->GetOutput() );
       smootherZ->SetInput( smootherY->GetOutput());
       resampler->SetInput(smootherZ->GetOutput());
       
       smootherX->SetDirection( 0 );
       smootherY->SetDirection( 1 );
       smootherZ->SetDirection( 2 );
      smootherX->SetSigma( isoSpacing );
      smootherY->SetSigma( isoSpacing );
      smootherZ->SetSigma( isoSpacing );
      
      smootherX->SetNormalizeAcrossScale( false );
      smootherY->SetNormalizeAcrossScale( false );
      smootherZ->SetNormalizeAcrossScale( false );
      
    }

if(inputSpacing[0]<isoSpacing&&inputSpacing[3]>isoSpacing)
    {
       typename GaussianFilterType::Pointer smootherX = GaussianFilterType::New();
       typename GaussianFilterType::Pointer smootherY = GaussianFilterType::New();
       smootherX->SetInput( caster11->GetOutput() );
       smootherY->SetInput( smootherX->GetOutput() );
       resampler->SetInput(smootherY->GetOutput());
       smootherX->SetDirection( 0 );
       smootherY->SetDirection( 1 );
      smootherX->SetSigma( isoSpacing );
      smootherY->SetSigma( isoSpacing );

      smootherX->SetNormalizeAcrossScale( false );
      smootherY->SetNormalizeAcrossScale( false );
      
      
    }

if(inputSpacing[0]>=isoSpacing&&inputSpacing[3]>=isoSpacing)
    {
       
       resampler->SetInput(caster11->GetOutput());
    }
 
  const unsigned int Dimension=3;
  typedef itk::AffineTransform<double, Dimension> TransformType;
  typename TransformType::Pointer transform = TransformType::New();
   resampler->SetTransform(transform);
    typedef itk::LinearInterpolateImageFunction< 
                           InternalImageType, double >  InterpolatorType;
   typename InterpolatorType::Pointer interpolator = InterpolatorType::New();
   resampler->SetInterpolator( interpolator );
   resampler->SetDefaultPixelValue( -1024 );
   typename OutputImageType::SpacingType spacing;
// 
    spacing[0] = isoSpacing;
    spacing[1] = isoSpacing;
    spacing[2] = isoSpacing;
// // 
    resampler->SetOutputSpacing( spacing );
    resampler->SetOutputOrigin( inputImage->GetOrigin() );
    resampler->SetOutputDirection( inputImage->GetDirection() );
// 
// 
    typename InputImageType::SizeType   inputSize = 
                     inputImage->GetLargestPossibleRegion().GetSize();
//   
   typedef typename InputImageType::SizeType::SizeValueType SizeValueType;
// 
   const double dx = inputSize[0] * inputSpacing[0] / isoSpacing;
   const double dy = inputSize[1] * inputSpacing[1] / isoSpacing;
   const double dz = (inputSize[2] - 1 ) * inputSpacing[2] / isoSpacing;
   typename InputImageType::SizeType   size;
// 
   size[0] = static_cast<SizeValueType>( dx );
   size[1] = static_cast<SizeValueType>( dy );
   size[2] = static_cast<SizeValueType>( dz );
// 
   resampler->SetSize( size );
   InternalFilter->SetInput(resampler->GetOutput());
   writer1->SetFileName("../data/out_test.hdr");
   writer1->SetInput(InternalFilter->GetOutput());
 
 // inputSpacing = inputImage->GetSpacing();
 // std::cout << inputImage->GetSpacing()<< std::endl;

     
// 
//  // InternalFilter->SetInput(InputFilter->GetOutput());
//    
    try
       {
      writer1->Update();
       }
     catch( itk::ExceptionObject & excep )
      {
       std::cerr << "Exception caught !" << std::endl;
       std::cerr << excep << std::endl;
       }
 
// 

};

int main( int argc, char * argv[] )
{
  if( argc < 3 )
     {
    std::cerr << "Usage: " << std::endl;
     std::cerr << argv[0] << "  inputImageFile  outputImageFile  lower upper " << std::endl; 
     return EXIT_FAILURE;
     }

  const     unsigned int    Dimension = 3;
  typedef   short  InputPixelType;
  typedef   float           InternalPixelType;
  typedef itk::Image< InputPixelType,    Dimension >   InputImageType;
  typedef itk::Image< InternalPixelType, Dimension >   InternalImageType;
  typedef   short   OutputPixelType;
  typedef itk::Image< OutputPixelType,   Dimension >   OutputImageType;
// Software Guide : EndCodeSnippet

  typedef itk::ImageFileReader< InputImageType  >  ReaderType;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[1] );
  typedef itk::ImageFileWriter< InternalImageType >  WriterType1;
  typedef itk::ImageFileWriter< OutputImageType >  WriterType;
  
  InternalImageType::Pointer isotropic1=InternalImageType::New();

  try 
    {
    reader->Update();
    }
  catch( itk::ExceptionObject & excep )
    {
    std::cerr << "Exception caught!" << std::endl;
    std::cerr << excep << std::endl;
    }

typedef itk::CastImageFilter< InputImageType,InternalImageType> CastingFilterType1;
  CastingFilterType1::Pointer caster11 = CastingFilterType1::New();
 
  typedef itk::CastImageFilter< InternalImageType,OutputImageType> CastingFilterType2;
  CastingFilterType1::Pointer caster21 = CastingFilterType1::New();
   
  double scale=1.0;
  IsotropicResample <ReaderType,CastingFilterType1,double> (reader,caster11,scale);
 
  WriterType1::Pointer writer1 = WriterType1::New();
  writer1->SetFileName( argv[2] );
   writer1->SetInput(caster11->GetOutput());
  
  try 
    {
    writer1->Update();
    }
  catch( itk::ExceptionObject & excep )
    {
    std::cerr << "Exception caught !" << std::endl;
    std::cerr << excep << std::endl;
    }

  return EXIT_SUCCESS;
}



      
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20090224/91b4bce7/attachment-0001.htm>


More information about the Insight-users mailing list