17 #ifndef __itkRecursiveSeparableImageFilter_txx
18 #define __itkRecursiveSeparableImageFilter_txx
31 template <
typename TInputImage,
typename TOutputImage>
36 this->SetNumberOfRequiredOutputs( 1 );
37 this->SetNumberOfRequiredInputs( 1 );
44 template <
typename TInputImage,
typename TOutputImage>
51 const_cast< TInputImage * >(input) );
58 template <
typename TInputImage,
typename TOutputImage>
63 return dynamic_cast<const TInputImage *
>(
71 template <
typename TInputImage,
typename TOutputImage>
87 scratch[0] =
RealType( outV1 * m_N0 + outV1 * m_N1 + outV1 * m_N2 + outV1 * m_N3 );
88 scratch[1] =
RealType( data[1] * m_N0 + outV1 * m_N1 + outV1 * m_N2 + outV1 * m_N3 );
89 scratch[2] =
RealType( data[2] * m_N0 + data[1] * m_N1 + outV1 * m_N2 + outV1 * m_N3 );
90 scratch[3] =
RealType( data[3] * m_N0 + data[2] * m_N1 + data[1] * m_N2 + outV1 * m_N3 );
93 scratch[0] -=
RealType( outV1 * m_BN1 + outV1 * m_BN2 + outV1 * m_BN3 + outV1 * m_BN4 );
94 scratch[1] -=
RealType( scratch[0] * m_D1 + outV1 * m_BN2 + outV1 * m_BN3 + outV1 * m_BN4 );
95 scratch[2] -=
RealType( scratch[1] * m_D1 + scratch[0] * m_D2 + outV1 * m_BN3 + outV1 * m_BN4 );
96 scratch[3] -=
RealType( scratch[2] * m_D1 + scratch[1] * m_D2 + scratch[0] * m_D3 + outV1 * m_BN4 );
101 for(
unsigned int i=4; i<ln; i++ )
103 scratch[i] =
RealType( data[i] * m_N0 + data[i-1] * m_N1 + data[i-2] * m_N2 + data[i-3] * m_N3 );
104 scratch[i] -=
RealType( scratch[i-1] * m_D1 + scratch[i-2] * m_D2 + scratch[i-3] * m_D3 + scratch[i-4] * m_D4 );
110 for(
unsigned int i=0; i<ln; i++ )
112 outs[i] = scratch[i];
127 scratch[ln-1] =
RealType( outV2 * m_M1 + outV2 * m_M2 + outV2 * m_M3 + outV2 * m_M4);
128 scratch[ln-2] =
RealType( data[ln-1] * m_M1 + outV2 * m_M2 + outV2 * m_M3 + outV2 * m_M4);
129 scratch[ln-3] =
RealType( data[ln-2] * m_M1 + data[ln-1] * m_M2 + outV2 * m_M3 + outV2 * m_M4);
130 scratch[ln-4] =
RealType( data[ln-3] * m_M1 + data[ln-2] * m_M2 + data[ln-1] * m_M3 + outV2 * m_M4);
133 scratch[ln-1] -=
RealType( outV2 * m_BM1 + outV2 * m_BM2 + outV2 * m_BM3 + outV2 * m_BM4);
134 scratch[ln-2] -=
RealType( scratch[ln-1] * m_D1 + outV2 * m_BM2 + outV2 * m_BM3 + outV2 * m_BM4);
135 scratch[ln-3] -=
RealType( scratch[ln-2] * m_D1 + scratch[ln-1] * m_D2 + outV2 * m_BM3 + outV2 * m_BM4);
136 scratch[ln-4] -=
RealType( scratch[ln-3] * m_D1 + scratch[ln-2] * m_D2 + scratch[ln-1] * m_D3 + outV2 * m_BM4);
141 for(
unsigned int i=ln-4; i>0; i-- )
143 scratch[i-1] =
RealType( data[i] * m_M1 + data[i+1] * m_M2 + data[i+2] * m_M3 + data[i+3] * m_M4 );
144 scratch[i-1] -=
RealType( scratch[i] * m_D1 + scratch[i+1] * m_D2 + scratch[i+2] * m_D3 + scratch[i+3] * m_D4 );
150 for(
unsigned int i=0; i<ln; i++ )
152 outs[i] += scratch[i];
160 template <
typename TInputImage,
typename TOutputImage>
165 TOutputImage *out =
dynamic_cast<TOutputImage*
>(output);
173 if ( this->m_Direction >= outputRegion.GetImageDimension() )
175 itkExceptionMacro(
"Direction selected for filtering is greater than ImageDimension")
179 outputRegion.SetIndex( m_Direction, largestOutputRegion.GetIndex(m_Direction) );
180 outputRegion.SetSize( m_Direction, largestOutputRegion.GetSize(m_Direction) );
182 out->SetRequestedRegion( outputRegion );
187 template <
typename TInputImage,
typename TOutputImage>
194 const typename TOutputImage::SizeType& requestedRegionSize
195 = outputPtr->GetRequestedRegion().GetSize();
198 typename TOutputImage::IndexType splitIndex;
199 typename TOutputImage::SizeType splitSize;
202 splitRegion = outputPtr->GetRequestedRegion();
203 splitIndex = splitRegion.GetIndex();
204 splitSize = splitRegion.GetSize();
208 splitAxis = outputPtr->GetImageDimension() - 1;
209 while (requestedRegionSize[splitAxis] == 1 || splitAxis == (
int)m_Direction)
214 itkDebugMacro(
" Cannot Split");
220 typename TOutputImage::SizeType::SizeValueType range = requestedRegionSize[splitAxis];
221 int valuesPerThread = (int)vcl_ceil(range/(
double)num);
222 int maxThreadIdUsed = (int)vcl_ceil(range/(
double)valuesPerThread) - 1;
225 if (i < maxThreadIdUsed)
227 splitIndex[splitAxis] += i*valuesPerThread;
228 splitSize[splitAxis] = valuesPerThread;
230 if (i == maxThreadIdUsed)
232 splitIndex[splitAxis] += i*valuesPerThread;
234 splitSize[splitAxis] = splitSize[splitAxis] - i*valuesPerThread;
238 splitRegion.SetIndex( splitIndex );
239 splitRegion.SetSize( splitSize );
241 itkDebugMacro(
" Split Piece: " << splitRegion );
243 return maxThreadIdUsed + 1;
247 template <
typename TInputImage,
typename TOutputImage>
254 typename TInputImage::ConstPointer inputImage( this->GetInputImage () );
255 typename TOutputImage::Pointer outputImage( this->GetOutput() );
257 const unsigned int imageDimension = inputImage->GetImageDimension();
259 if( this->m_Direction >= imageDimension )
261 itkExceptionMacro(
"Direction selected for filtering is greater than ImageDimension");
264 const typename InputImageType::SpacingType & pixelSize
265 = inputImage->GetSpacing();
267 this->SetUp( pixelSize[m_Direction] );
269 RegionType region = outputImage->GetRequestedRegion();
271 const unsigned int ln = region.GetSize()[ this->m_Direction ];
275 itkExceptionMacro(
"The number of pixels along direction " << this->m_Direction <<
" is less than 4. This filter requires a minimum of four pixels along the dimension to be processed.");
285 template <
typename TInputImage,
typename TOutputImage>
290 typedef typename TOutputImage::PixelType OutputPixelType;
297 typename TInputImage::ConstPointer inputImage( this->GetInputImage () );
298 typename TOutputImage::Pointer outputImage( this->GetOutput() );
300 RegionType region = outputRegionForThread;
302 InputConstIteratorType inputIterator( inputImage, region );
303 OutputIteratorType outputIterator( outputImage, region );
305 inputIterator.SetDirection( this->m_Direction );
306 outputIterator.SetDirection( this->m_Direction );
309 const unsigned int ln = region.GetSize()[ this->m_Direction ];
319 catch( std::bad_alloc & )
321 itkExceptionMacro(
"Problem allocating memory for internal computations");
328 catch( std::bad_alloc & )
331 itkExceptionMacro(
"Problem allocating memory for internal computations");
338 catch( std::bad_alloc &)
342 itkExceptionMacro(
"Problem allocating memory for internal computations");
345 inputIterator.GoToBegin();
346 outputIterator.GoToBegin();
348 const typename TInputImage::OffsetValueType * offsetTable = inputImage->GetOffsetTable();
350 const unsigned int numberOfLinesToProcess = offsetTable[ TInputImage::ImageDimension ] / ln;
356 while( !inputIterator.IsAtEnd() && !outputIterator.IsAtEnd() )
359 while( !inputIterator.IsAtEndOfLine() )
361 inps[i++] = inputIterator.Get();
365 this->FilterDataArray( outs, inps, scratch, ln );
368 while( !outputIterator.IsAtEndOfLine() )
370 outputIterator.Set( static_cast<OutputPixelType>( outs[j++] ) );
374 inputIterator.NextLine();
375 outputIterator.NextLine();
405 template <
typename TInputImage,
typename TOutputImage>
410 Superclass::PrintSelf(os,indent);
412 os << indent <<
"Direction: " << m_Direction << std::endl;