[Insight-users] VectorImage Registration Metric
Karthik Krishnan
karthik.krishnan at kitware.com
Wed Jul 2 16:47:14 EDT 2008
Kevin H. Hobbs wrote:
> Hi Luis,
>
> I just got a chance to return to my project that requires me to register
> two channel images.
>
> I'm continuing the thread :
>
> http://www.itk.org/pipermail/insight-users/2008-May/025666.html
>
> You wrote a class to facilitate this, and posted it in the NAMIC
> sandbox :
>
> http://www.na-mic.org/svn/NAMICSandBox/trunk/VectorImageRegistrationMethod/
>
> Thank you very much for this class!
>
> My choice to use an itk::VectorImage was based in part on memory usage.
> The images are large (about 1GB for two channels) even with a pixel type
> of unsigned char. As I understand it an image of vectors stores at least
> a pointer at each position in the image. That sounds like it would use
> all of my 4GB of RAM without ever loading any data.
>
> However, the documentation for itk::VectorImage says that they are used
> the same way.
>
> I pared my program down just to the minimum to show the compile problem
> I'm getting and attached it.
>
> The program compiles fine when I use an image of vectors in the template
> for the metric like so :
>
> typedef itk::Vector< PixelType, 2 > V_PixelType;
> typedef itk::Image< V_PixelType, Dimension > V_ImageType;
>
> typedef itk::VectorMeanSquaresImageToImageMetric
> < V_ImageType, V_ImageType > MetricType;
>
> But when I try to compile the program as it is in the attachment with:
>
> typedef itk::VectorImage< PixelType, Dimension > ImageType;
>
> typedef itk::VectorMeanSquaresImageToImageMetric
> < ImageType, ImageType > MetricType;
>
> I get the following output:
>
> /home/kevin/kitware/Insight/Code/Common/itkVectorInterpolateImageFunction.h: In instantiation of ‘itk::VectorInterpolateImageFunction<itk::VectorImage<unsigned char, 3u>, double>’:
> /home/kevin/Documents/VectorImageRegistrationMethod/Source/itkVectorImageToImageMetric.h:110: instantiated from ‘itk::VectorImageToImageMetric<itk::VectorImage<unsigned char, 3u>, itk::VectorImage<unsigned char, 3u> >’
> /home/kevin/Documents/VectorImageRegistrationMethod/Source/itkVectorMeanSquaresImageToImageMetric.h:50: instantiated from ‘itk::VectorMeanSquaresImageToImageMetric<itk::VectorImage<unsigned char, 3u>, itk::VectorImage<unsigned char, 3u> >’
> /home/kevin/Documents/stg_anatomy/align_rot_vect.cxx:25: instantiated from here
> /home/kevin/kitware/Insight/Code/Common/itkVectorInterpolateImageFunction.h:65: error: ‘Dimension’ is not a member of ‘itk::VariableLengthVector<unsigned char>’
> /home/kevin/kitware/Insight/Code/Common/itkImageConstIteratorWithIndex.h: In member function ‘const typename TImage::PixelType& itk::ImageConstIteratorWithIndex<TImage>::Value() const [with TImage = itk::VectorImage<unsigned char, 3u>]’:
> /home/kevin/Documents/VectorImageRegistrationMethod/Source/itkVectorMeanSquaresImageToImageMetric.txx:203: instantiated from ‘void itk::VectorMeanSquaresImageToImageMetric<TFixedImage, TMovingImage>::GetDerivative(const typename itk::VectorImageToImageMetric<TFixedImage, TMovingImage>::TransformParametersType&, typename itk::VectorImageToImageMetric<TFixedImage, TMovingImage>::DerivativeType&) const [with TFixedImage = itk::VectorImage<unsigned char, 3u>, TMovingImage = itk::VectorImage<unsigned char, 3u>]’
> /home/kevin/Documents/stg_anatomy/align_rot_vect.cxx:27: instantiated from here
> /home/kevin/kitware/Insight/Code/Common/itkImageConstIteratorWithIndex.h:241: warning: returning reference to temporary
>
> Were these not meant to go together,
No they are not, in their current state, although the fix is fairly easy.
The interpolator used (itk::VectorInterpolateImageFunction) is not
designed to work with itk::VectorImage, because of certain assumptions
it makes.
The fix is to replace this interpolator with your own interpolator that
is designed to work with itk::VectorImage. The following might.. (not
compiled..)
template <
class TInputImage,
class TCoordRep = float,
class TPixelType = ITK_TYPENAME TInputImage::PixelType
>
class ITK_EXPORT VectorImageInterpolateImageFunction :
public ImageFunction<
TInputImage,
VariableLengthVector< ITK_TYPENAME NumericTraits<typename
TPixelType::ValueType>::RealType >,
TCoordRep >
{
/** Dimension underlying input image. */
itkStaticConstMacro(ImageDimension, unsigned int,
TInputImage::ImageDimension);
/** Standard class typedefs. */
typedef VectorImageInterpolateImageFunction Self;
typedef ImageFunction<TInputImage,
VariableLengthVector<double >, TCoordRep > Superclass;
typedef SmartPointer<Self> Pointer;
typedef SmartPointer<const Self> ConstPointer;
/** Run-time type information (and related methods). */
itkTypeMacro(VectorImageInterpolateImageFunction, ImageFunction);
/** InputImageType typedef support. */
typedef typename Superclass::InputImageType InputImageType;
typedef typename InputImageType::PixelType PixelType;
typedef typename PixelType::ValueType ValueType;
typedef typename NumericTraits<ValueType>::RealType RealType;
/** Point typedef support. */
typedef typename Superclass::PointType PointType;
/** Index typedef support. */
typedef typename Superclass::IndexType IndexType;
/** ContinuousIndex typedef support. */
typedef typename Superclass::ContinuousIndexType ContinuousIndexType;
/** Output type is FixedArray<RealType,Dimension>. */
typedef typename Superclass::OutputType OutputType;
/** CoordRep typedef support. */
typedef TCoordRep CoordRepType;
/** Returns the interpolated image intensity at a
* specified point position. No bounds checking is done.
* The point is assume to lie within the image buffer.
* ImageFunction::IsInsideBuffer() can be used to check bounds before
* calling the method. */
virtual OutputType Evaluate( const PointType& point ) const
{
ContinuousIndexType index;
this->GetInputImage()->TransformPhysicalPointToContinuousIndex(
point, index );
return ( this->EvaluateAtContinuousIndex( index ) );
}
/** Interpolate the image at a continuous index position
*
* Returns the interpolated image intensity at a
* specified index position. No bounds checking is done.
* The point is assume to lie within the image buffer.
*
* Subclasses must override this method.
*
* ImageFunction::IsInsideBuffer() can be used to check bounds before
* calling the method. */
virtual OutputType EvaluateAtContinuousIndex(
const ContinuousIndexType & index ) const = 0;
/** Interpolate the image at an index position.
* Simply returns the image value at the
* specified index position. No bounds checking is done.
* The point is assume to lie within the image buffer.
*
* ImageFunction::IsInsideBuffer() can be used to check bounds before
* calling the method. */
virtual OutputType EvaluateAtIndex( const IndexType & index ) const
{
PixelType input = this->GetInputImage()->GetPixel( index );
OutputType output(input.GetSize());
for( unsigned int k = 0; k < input.GetSize(); k++ )
{
output[k] = static_cast<double>( input[k] );
}
return ( output );
}
protected:
VectorImageInterpolateImageFunction() {}
~VectorImageInterpolateImageFunction() {}
void PrintSelf(std::ostream& os, Indent indent) const
{ Superclass::PrintSelf( os, indent ); }
private:
VectorImageInterpolateImageFunction(const Self&); //purposely not
implemented
void operator=(const Self&); //purposely not implemented
};
Try it out and please let us know.....
Also swap out the typedef for the interpolator in
itk::VectorImageToImageMetric with this new interpolator.
> or did I do something stupid?
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Insight-users mailing list
> Insight-users at itk.org
> http://www.itk.org/mailman/listinfo/insight-users
--
--
Karthik Krishnan
R & D Engineer,
Kitware Inc,
Ph: +1 518 3713971 x119
Fax: +1 518 3714573
More information about the Insight-users
mailing list