17 #ifndef __itkMultiResolutionPyramidImageFilter_txx
18 #define __itkMultiResolutionPyramidImageFilter_txx
29 #include "vnl/vnl_math.h"
37 template <
class TInputImage,
class TOutputImage>
42 this->SetNumberOfLevels( 2 );
44 m_UseShrinkImageFilter =
false;
51 template <
class TInputImage,
class TOutputImage>
57 if( m_NumberOfLevels == num )
65 m_NumberOfLevels = num;
66 if( m_NumberOfLevels < 1 ) m_NumberOfLevels = 1;
74 unsigned int startfactor = 1;
75 startfactor = startfactor << ( m_NumberOfLevels - 1 );
78 this->SetStartingShrinkFactors( startfactor );
81 this->SetNumberOfRequiredOutputs( m_NumberOfLevels );
83 unsigned int numOutputs =
static_cast<unsigned int>( this->GetNumberOfOutputs() );
85 if( numOutputs < m_NumberOfLevels )
88 for( idx = numOutputs; idx < m_NumberOfLevels; idx++ )
91 this->MakeOutput( idx );
92 this->SetNthOutput( idx, output.
GetPointer() );
96 else if( numOutputs > m_NumberOfLevels )
99 for( idx = m_NumberOfLevels; idx < numOutputs; idx++ )
102 this->GetOutputs()[idx];
103 this->RemoveOutput( output );
113 template <
class TInputImage,
class TOutputImage>
117 unsigned int factor )
120 unsigned int array[ImageDimension];
121 for(
unsigned int dim = 0; dim < ImageDimension; ++dim )
126 this->SetStartingShrinkFactors( array );
134 template <
class TInputImage,
class TOutputImage>
138 unsigned int * factors )
141 for(
unsigned int dim = 0; dim < ImageDimension; ++dim )
143 m_Schedule[0][dim] = factors[dim];
144 if( m_Schedule[0][dim] == 0 )
146 m_Schedule[0][dim] = 1;
150 for(
unsigned int level = 1; level < m_NumberOfLevels; ++level )
152 for(
unsigned int dim = 0; dim < ImageDimension; ++dim )
154 m_Schedule[level][dim] = m_Schedule[level-1][dim] / 2;
155 if( m_Schedule[level][dim] == 0 )
157 m_Schedule[level][dim] = 1;
170 template <
class TInputImage,
class TOutputImage>
175 return ( m_Schedule.data_block() );
182 template <
class TInputImage,
class TOutputImage>
189 if( schedule.rows() != m_NumberOfLevels ||
190 schedule.columns() != ImageDimension )
192 itkDebugMacro(<<
"Schedule has wrong dimensions" );
196 if( schedule == m_Schedule )
202 unsigned int level, dim;
203 for( level = 0; level < m_NumberOfLevels; level++ )
205 for( dim = 0; dim < ImageDimension; dim++ )
208 m_Schedule[level][dim] = schedule[level][dim];
214 m_Schedule[level][dim] = vnl_math_min(
215 m_Schedule[level][dim], m_Schedule[level-1][dim] );
218 if( m_Schedule[level][dim] < 1 )
220 m_Schedule[level][dim] = 1;
231 template <
class TInputImage,
class TOutputImage>
237 unsigned int ilevel, idim;
238 for( ilevel = 0; ilevel < schedule.rows() - 1; ilevel++ )
240 for( idim = 0; idim < schedule.columns(); idim++ )
242 if( schedule[ilevel][idim] == 0 )
246 if( ( schedule[ilevel][idim] % schedule[ilevel+1][idim] ) > 0 )
259 template <
class TInputImage,
class TOutputImage>
275 typename CasterType::Pointer caster = CasterType::New();
276 typename SmootherType::Pointer smoother = SmootherType::New();
278 typename ImageToImageType::Pointer shrinkerFilter;
282 typename ResampleShrinkerType::Pointer resampleShrinker;
283 typename ShrinkerType::Pointer shrinker;
285 if(this->GetUseShrinkImageFilter())
287 shrinker = ShrinkerType::New();
288 shrinkerFilter = shrinker.GetPointer();
292 resampleShrinker = ResampleShrinkerType::New();
294 LinearInterpolatorType;
295 typename LinearInterpolatorType::Pointer interpolator =
296 LinearInterpolatorType::New();
297 resampleShrinker->SetInterpolator( interpolator );
298 resampleShrinker->SetDefaultPixelValue( 0 );
299 shrinkerFilter = resampleShrinker.GetPointer();
302 caster->SetInput( inputPtr );
304 smoother->SetUseImageSpacing(
false );
305 smoother->SetInput( caster->GetOutput() );
306 smoother->SetMaximumError( m_MaximumError );
308 shrinkerFilter->SetInput( smoother->GetOutput() );
310 unsigned int ilevel, idim;
311 unsigned int factors[ImageDimension];
312 double variance[ImageDimension];
314 for( ilevel = 0; ilevel < m_NumberOfLevels; ilevel++ )
316 this->UpdateProgress( static_cast<float>( ilevel ) /
317 static_cast<float>( m_NumberOfLevels ) );
321 outputPtr->SetBufferedRegion( outputPtr->GetRequestedRegion() );
322 outputPtr->Allocate();
325 for( idim = 0; idim < ImageDimension; idim++ )
327 factors[idim] = m_Schedule[ilevel][idim];
328 variance[idim] = vnl_math_sqr( 0.5 *
329 static_cast<float>( factors[idim] ) );
332 if(!this->GetUseShrinkImageFilter())
335 IdentityTransformType;
336 typename IdentityTransformType::Pointer identityTransform =
337 IdentityTransformType::New();
338 resampleShrinker->SetOutputParametersFromImage( outputPtr );
339 resampleShrinker->SetTransform(identityTransform);
343 shrinker->SetShrinkFactors(factors);
346 smoother->SetVariance( variance );
348 shrinkerFilter->GraftOutput( outputPtr );
351 shrinkerFilter->Modified();
352 shrinkerFilter->UpdateLargestPossibleRegion();
353 this->GraftNthOutput( ilevel, shrinkerFilter->GetOutput() );
360 template <
class TInputImage,
class TOutputImage>
365 Superclass::PrintSelf(os,indent);
367 os << indent <<
"MaximumError: " << m_MaximumError << std::endl;
368 os << indent <<
"No. levels: " << m_NumberOfLevels << std::endl;
369 os << indent <<
"Schedule: " << std::endl;
370 os << m_Schedule << std::endl;
371 os <<
"Use ShrinkImageFilter= " << m_UseShrinkImageFilter << std::endl;
378 template <
class TInputImage,
class TOutputImage>
385 Superclass::GenerateOutputInformation();
392 itkExceptionMacro( <<
"Input has not been set" );
395 const typename InputImageType::PointType&
396 inputOrigin = inputPtr->GetOrigin();
397 const typename InputImageType::SpacingType&
398 inputSpacing = inputPtr->GetSpacing();
399 const typename InputImageType::DirectionType&
400 inputDirection = inputPtr->GetDirection();
401 const typename InputImageType::SizeType& inputSize =
402 inputPtr->GetLargestPossibleRegion().GetSize();
403 const typename InputImageType::IndexType& inputStartIndex =
404 inputPtr->GetLargestPossibleRegion().GetIndex();
406 typedef typename OutputImageType::SizeType SizeType;
407 typedef typename SizeType::SizeValueType SizeValueType;
408 typedef typename OutputImageType::IndexType IndexType;
409 typedef typename IndexType::IndexValueType IndexValueType;
412 typename OutputImageType::PointType outputOrigin;
413 typename OutputImageType::SpacingType outputSpacing;
415 IndexType outputStartIndex;
419 for(
unsigned int ilevel = 0; ilevel < m_NumberOfLevels; ilevel++ )
421 outputPtr = this->GetOutput( ilevel );
422 if( !outputPtr ) {
continue; }
424 for(
unsigned int idim = 0; idim < OutputImageType::ImageDimension; idim++ )
426 const double shrinkFactor =
static_cast<double>( m_Schedule[ilevel][idim] );
427 outputSpacing[idim] = inputSpacing[idim] * shrinkFactor;
429 outputSize[idim] =
static_cast<SizeValueType
>(
430 vcl_floor(static_cast<double>(inputSize[idim]) / shrinkFactor ) );
431 if( outputSize[idim] < 1 ) { outputSize[idim] = 1; }
433 outputStartIndex[idim] =
static_cast<IndexValueType
>(
434 vcl_ceil(static_cast<double>(inputStartIndex[idim]) / shrinkFactor ) );
438 =(inputDirection*(outputSpacing-inputSpacing))*0.5;
439 for(
unsigned int idim = 0; idim < OutputImageType::ImageDimension; idim++ )
441 outputOrigin[idim]=inputOrigin[idim]+outputOriginOffset[idim];
444 typename OutputImageType::RegionType outputLargestPossibleRegion;
445 outputLargestPossibleRegion.SetSize( outputSize );
446 outputLargestPossibleRegion.SetIndex( outputStartIndex );
448 outputPtr->SetLargestPossibleRegion( outputLargestPossibleRegion );
449 outputPtr->SetOrigin ( outputOrigin );
450 outputPtr->SetSpacing( outputSpacing );
451 outputPtr->SetDirection( inputDirection );
459 template <
class TInputImage,
class TOutputImage>
465 Superclass::GenerateOutputRequestedRegion( refOutput );
471 typedef typename OutputImageType::SizeType SizeType;
472 typedef typename SizeType::SizeValueType SizeValueType;
473 typedef typename OutputImageType::IndexType IndexType;
474 typedef typename IndexType::IndexValueType IndexValueType;
475 typedef typename OutputImageType::RegionType RegionType;
477 TOutputImage * ptr =
static_cast<TOutputImage*
>( refOutput );
480 itkExceptionMacro( <<
"Could not cast refOutput to TOutputImage*." );
483 unsigned int ilevel, idim;
485 if ( ptr->GetRequestedRegion() == ptr->GetLargestPossibleRegion() )
490 for( ilevel = 0; ilevel < m_NumberOfLevels; ilevel++ )
492 if( ilevel == refLevel ) {
continue; }
493 if( !this->GetOutput(ilevel) ) {
continue; }
494 this->GetOutput(ilevel)->SetRequestedRegionToLargestPossibleRegion();
501 IndexType outputIndex;
503 RegionType outputRegion;
504 IndexType baseIndex = ptr->GetRequestedRegion().GetIndex();
505 SizeType baseSize = ptr->GetRequestedRegion().GetSize();
507 for( idim = 0; idim < TOutputImage::ImageDimension; idim++ )
509 unsigned int factor = m_Schedule[refLevel][idim];
510 baseIndex[idim] *=
static_cast<IndexValueType
>( factor );
511 baseSize[idim] *=
static_cast<SizeValueType
>( factor );
514 for( ilevel = 0; ilevel < m_NumberOfLevels; ilevel++ )
516 if( ilevel == refLevel ) {
continue; }
517 if( !this->GetOutput(ilevel) ) {
continue; }
519 for( idim = 0; idim < TOutputImage::ImageDimension; idim++ )
522 double factor =
static_cast<double>( m_Schedule[ilevel][idim] );
524 outputSize[idim] =
static_cast<SizeValueType
>(
525 vcl_floor(static_cast<double>(baseSize[idim]) / factor ) );
526 if( outputSize[idim] < 1 ) { outputSize[idim] = 1; }
528 outputIndex[idim] =
static_cast<IndexValueType
>(
529 vcl_ceil(static_cast<double>(baseIndex[idim]) / factor ) );
533 outputRegion.SetIndex( outputIndex );
534 outputRegion.SetSize( outputSize );
537 outputRegion.Crop( this->GetOutput( ilevel )->
538 GetLargestPossibleRegion() );
540 this->GetOutput( ilevel )->SetRequestedRegion( outputRegion );
550 template <
class TInputImage,
class TOutputImage>
556 Superclass::GenerateInputRequestedRegion();
563 itkExceptionMacro( <<
"Input has not been set." );
567 typedef typename OutputImageType::SizeType SizeType;
568 typedef typename SizeType::SizeValueType SizeValueType;
569 typedef typename OutputImageType::IndexType IndexType;
570 typedef typename IndexType::IndexValueType IndexValueType;
571 typedef typename OutputImageType::RegionType RegionType;
573 unsigned int refLevel = m_NumberOfLevels - 1;
574 SizeType baseSize = this->GetOutput(refLevel)->GetRequestedRegion().GetSize();
575 IndexType baseIndex = this->GetOutput(refLevel)->GetRequestedRegion().GetIndex();
576 RegionType baseRegion;
579 for( idim = 0; idim < ImageDimension; idim++ )
581 unsigned int factor = m_Schedule[refLevel][idim];
582 baseIndex[idim] *=
static_cast<IndexValueType
>( factor );
583 baseSize[idim] *=
static_cast<SizeValueType
>( factor );
585 baseRegion.SetIndex( baseIndex );
586 baseRegion.SetSize( baseSize );
589 typedef typename TOutputImage::PixelType OutputPixelType;
592 OperatorType *oper =
new OperatorType;
594 typename TInputImage::SizeType radius;
596 RegionType inputRequestedRegion = baseRegion;
599 for( idim = 0; idim < TInputImage::ImageDimension; idim++ )
602 oper->SetVariance( vnl_math_sqr( 0.5 * static_cast<float>(
603 m_Schedule[refLevel][idim] ) ) );
604 oper->SetMaximumError( m_MaximumError );
605 oper->CreateDirectional();
606 radius[idim] = oper->GetRadius()[idim];
610 inputRequestedRegion.PadByRadius( radius );
613 inputRequestedRegion.Crop( inputPtr->GetLargestPossibleRegion() );
616 inputPtr->SetRequestedRegion( inputRequestedRegion );