[Insight-users] LaplacianImageFiler

Luis Ibanez luis . ibanez at kitware . com
Mon, 27 Oct 2003 16:57:38 -0500


This is a multi-part message in MIME format.
--------------080506060105050006030403
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit


Hi Bing,

The Laplacian filter does support the use of ImageAdaptors.

Please look at the attached file that presents an example
of adapting an Image of Offset to a Laplacian filter.

----

Some of your typedef statements may be inconsistent.

Could you please post the relevant sections from the
original code. The code snippets in your previous email
may not be enough for finding the source of the problem.

Thanks


   Luis


--------------------------

Bing Jian wrote:
> Hi, Everyone,
> 
>    Does anybody attemp to let LaplacianFilter accept an adaptor which
> extracts one component from vector image as input and produce scalar
> image as output? I have following code to do such thing, but got
> errors.
> 
>    typedef itk::ImageAdaptor <VectorImageType,
> 		VectorPixelAccessor > ImageAdaptorType;
>    ImageAdaptorType::Pointer adaptor = ImageAdaptorType::New();
> 
>  where VectorImageType is defined as Image<vector<double,2>,2>
>        And in VectorPixelAccessor
> 	typedef itk::Vector<double,2>   InternalType;
> 	typedef       double      ExternalType;
> 
>  Then I try to apply LaplacianFilter on the output of adaptor.
> 
>    typedef itk::Image<double,2> RealImageType;
> 
>    typedef itk::LaplacianImageFilter<
> 		ImageAdaptorType,
> 		RealImageType >    LaplacianFilter;
>    LaplacianFilter::Pointer lapFilter = LaplacianFilter::New();
> 
>  The error I got is:
> 
> D:\Library\repository\itk\Insight\Code\Common\itkZeroFluxNeumannBoundaryCondition.txx(36)
> : error C2440: 'return' : cannot convert from 'class itk::Vector<double,2>' to 'double'
>         No user-defined-conversion operator available that can perform
> this conversion, or the operator cannot be called
> 
>    Does laplacianFilter require the input and output to be same type?
> 
>    Thanks in advance!
> 
> 



--------------080506060105050006030403
Content-Type: text/plain;
 name="ImageAdaptor.cxx"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="ImageAdaptor.cxx"

/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    $RCSfile: ImageAdaptor3.cxx,v $
  Language:  C++
  Date:      $Date: 2003/09/10 14:29:51 $
  Version:   $Revision: 1.10 $

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www . itk . org/HTML/Copyright . htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even 
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif


#include "itkImage.h"
#include "itkImageAdaptor.h"
#include "itkCovariantVector.h"
#include "itkImageRegionIteratorWithIndex.h"
#include "itkGradientRecursiveGaussianImageFilter.h"
#include "itkLaplacianImageFilter.h"



//
// ADAPTOR FOR THE OFFSET IMAGES INTO SCALARS
//
class OffsetPixelAccessor  
{
public:
  typedef itk::Offset<3>   InternalType;
  typedef       float      ExternalType;

  void operator=( const OffsetPixelAccessor & vpa )
    {
      m_Index = vpa.m_Index;
    }
  ExternalType Get( const InternalType & input ) const 
    {
      return static_cast<ExternalType>( input[ m_Index ] );
    }
  void SetIndex( unsigned int index )
    {
      m_Index = index;
    }
private:
  unsigned int m_Index;
};





//
// ADAPTOR FOR THE VECTOR IMAGES INTO SCALARS
//
class VectorPixelAccessor  
{
public:
  typedef itk::CovariantVector<float,3>   InternalType;
  typedef                      float      ExternalType;

  void operator=( const VectorPixelAccessor & vpa )
    {
      m_Index = vpa.m_Index;
    }
  ExternalType Get( const InternalType & input ) const 
    {
      return static_cast<ExternalType>( input[ m_Index ] );
    }
  void SetIndex( unsigned int index )
    {
      m_Index = index;
    }
private:
  unsigned int m_Index;
};






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

  const   unsigned int   Dimension = 3;

  typedef itk::Offset<Dimension>                     OffsetPixelType;
  typedef itk::Image< OffsetPixelType, Dimension >   OffsetImageType;
  typedef OffsetImageType::Pointer                   OffsetImagePointer;

  OffsetImagePointer  offsetImage = OffsetImageType::New();

  typedef itk::ImageAdaptor<  
                         OffsetImageType, 
                         OffsetPixelAccessor 
                                           >         OffsetImageAdaptorType;

  OffsetImageAdaptorType::Pointer  offsetAdaptor =
                                         OffsetImageAdaptorType::New();

  typedef itk::CovariantVector< float, Dimension  >   VectorPixelType; 
  typedef itk::Image< VectorPixelType, Dimension  >   VectorImageType;
  typedef VectorImageType::Pointer                    VectorImagePointer;

  typedef itk::GradientRecursiveGaussianImageFilter< 
                                        OffsetImageAdaptorType,
                                        VectorImageType> GradientFilterType;

  GradientFilterType::Pointer gradient = GradientFilterType::New();


  typedef itk::Image< float, Dimension > LaplacianImageType;
  typedef itk::LaplacianImageFilter< OffsetImageAdaptorType, 
                                     LaplacianImageType > LaplacianFilterType;


  typedef itk::ImageAdaptor<  VectorImageType, 
                              VectorPixelAccessor > ImageAdaptorType;

  ImageAdaptorType::Pointer adaptor = ImageAdaptorType::New();

  VectorPixelAccessor  accessor;
  

  // CREATE THE N * N image for the Jacobian of the Offset
  typedef itk::Image< float, Dimension >  ScalarOutputImageType;
  typedef ScalarOutputImageType::Pointer  ScalarOutputImagePointer;

  ScalarOutputImagePointer  outputImages[ 9 ];
 
  for(unsigned int i=0; i<9; i++)
    {
    outputImages[i] = ScalarOutputImageType::New();
    outputImages[i]->SetRegions( offsetImage->GetBufferedRegion() );
    outputImages[i]->Allocate();
    }


  for(unsigned int indexToProcess = 0; indexToProcess< Dimension; indexToProcess++)
    {
    accessor.SetIndex( indexToProcess );
    adaptor->SetPixelAccessor( accessor );
    gradient->SetInput( offsetAdaptor );
    gradient->Update();
    adaptor->SetImage( gradient->GetOutput() );
    VectorImagePointer  vectorImage = gradient->GetOutput();
    for(unsigned int component=0; component < Dimension; component++)
      {
      ScalarOutputImagePointer outputImage = outputImages[ component ];
      typedef itk::ImageRegionIteratorWithIndex< ScalarOutputImageType > ScalarIterator;
      typedef itk::ImageRegionIteratorWithIndex< VectorImageType       > VectorIterator;
      ScalarIterator scalarIter( outputImage, outputImage->GetBufferedRegion() );
      VectorIterator vectorIter( vectorImage, vectorImage->GetBufferedRegion() );
      scalarIter.GoToBegin();
      vectorIter.GoToBegin();
      while( !scalarIter.IsAtEnd() ) 
        {
        scalarIter.Set( vectorIter.Value()[ component ] );
        ++scalarIter;
        ++vectorIter;
        }
      }
    }
 


  return 0;
}




--------------080506060105050006030403--