#ifndef __itkSliceBySliceImageFilter_txx #define __itkSliceBySliceImageFilter_txx #include "itkSliceBySliceImageFilter.h" #include "itkProgressReporter.h" namespace itk { template SliceBySliceImageFilter ::SliceBySliceImageFilter() { m_InputFilter = NULL; m_OutputFilter = NULL; m_Dimension = ImageDimension - 1; } template void SliceBySliceImageFilter ::GenerateInputRequestedRegion() { // call the superclass' implementation of this method Superclass::GenerateInputRequestedRegion(); for( int i=0; iGetNumberOfInputs(); i++) { typename InputImageType::Pointer inputPtr = const_cast< InputImageType * >( this->GetInput( i ) ); if ( !inputPtr ) { return; } inputPtr->SetRequestedRegion(inputPtr->GetLargestPossibleRegion()); } } template void SliceBySliceImageFilter ::EnlargeOutputRequestedRegion(DataObject *) { for( int i=0; iGetNumberOfOutputs(); i++) { this->GetOutput( i )->SetRequestedRegion( this->GetOutput( i )->GetLargestPossibleRegion() ); } } template void SliceBySliceImageFilter ::SetFilter( InputFilterType * filter ) { OutputFilterType * outputFilter = dynamic_cast< OutputFilterType * >( filter ); if( outputFilter == NULL && filter != NULL ) { // TODO: can it be replaced by a concept check ? itkExceptionMacro("Wrong output filter type. Use SetOutputFilter() and SetInputFilter() instead of SetFilter() when input and output filter types are different."); } this->SetInputFilter( filter ); this->SetOutputFilter( outputFilter ); } template void SliceBySliceImageFilter ::SetInputFilter( InputFilterType * filter ) { if( m_InputFilter.GetPointer() != filter ) { this->Modified(); m_InputFilter = filter; // adapt the number of inputs and outputs this->SetNumberOfRequiredInputs( filter->GetNumberOfValidRequiredInputs() ); } } template void SliceBySliceImageFilter ::SetOutputFilter( OutputFilterType * filter ) { if( m_OutputFilter.GetPointer() != filter ) { this->Modified(); m_OutputFilter = filter; // adapt the number of inputs and outputs this->SetNumberOfRequiredOutputs( filter->GetNumberOfOutputs() ); } } template void SliceBySliceImageFilter ::GenerateData() { if( !m_InputFilter || !m_OutputFilter ) { itkExceptionMacro("Filters must be set."); } for( int i=1; iGetNumberOfInputs(); i++) { if ( this->GetInput()->GetRequestedRegion().GetSize() != this->GetInput( i )->GetRequestedRegion().GetSize() ) { itkExceptionMacro( << "Inputs must have the same size." ); } } this->AllocateOutputs(); RegionType requestedRegion = this->GetOutput()->GetRequestedRegion(); IndexType requestedIndex = requestedRegion.GetIndex(); SizeType requestedSize = requestedRegion.GetSize(); InternalRegionType internalRegion; InternalSizeType internalSize; InternalIndexType internalIndex; for( int i=0; i internalInputs; internalInputs.resize( this->GetNumberOfInputs() ); for( int i=0; iGetNumberOfInputs(); i++) { internalInputs[i] = InternalInputImageType::New(); internalInputs[i]->SetRegions( internalRegion ); internalInputs[i]->Allocate(); m_InputFilter->SetInput( i, internalInputs[i] ); } ProgressReporter progress(this, 0, requestedSize[m_Dimension]); // std::cout << "start: " << requestedIndex[m_Dimension] << " end: " << requestedSize[m_Dimension] - requestedIndex[m_Dimension] << std::endl; for( int slice=requestedIndex[m_Dimension]; slice < requestedSize[m_Dimension] - requestedIndex[m_Dimension]; slice++ ) { // std::cout << "slice: " << slice << std::endl; // copy the current slice to the input image typedef ImageRegionIterator< InternalInputImageType > InputIteratorType; typename std::vector< InputIteratorType > inputIterators; inputIterators.resize( this->GetNumberOfInputs() ); for( int i=0; iGetNumberOfInputs(); i++) { inputIterators[i] = InputIteratorType( internalInputs[i], internalRegion ); inputIterators[i].GoToBegin(); } while( !inputIterators[0].IsAtEnd() ) { IndexType idx; const InternalIndexType & iidx = inputIterators[0].GetIndex(); for( int i=0; i= m_Dimension ) { idx[i+1] = iidx[i]; } else { idx[i] = iidx[i]; } } idx[ m_Dimension ] = slice; for( int i=0; iGetNumberOfInputs(); i++) { inputIterators[i].Set( this->GetInput( i )->GetPixel( idx ) ); ++(inputIterators[i]); } } // run the filter on the current slice m_InputFilter->Modified(); m_OutputFilter->Modified(); // should not be needed, but may help in some cases m_OutputFilter->UpdateLargestPossibleRegion(); progress.CompletedPixel(); // and copy the output slice to the output image typedef ImageRegionConstIterator< InternalOutputImageType > OutputIteratorType; typename std::vector< OutputIteratorType > outputIterators; outputIterators.resize( this->GetNumberOfOutputs() ); for( int i=0; iGetNumberOfOutputs(); i++) { outputIterators[i] = OutputIteratorType( m_OutputFilter->GetOutput( i ), internalRegion ); outputIterators[i].GoToBegin(); } while( !outputIterators[0].IsAtEnd() ) { IndexType idx; const InternalIndexType & iidx = outputIterators[0].GetIndex(); for( int i=0; i= m_Dimension ) { idx[i+1] = iidx[i]; } else { idx[i] = iidx[i]; } } idx[ m_Dimension ] = slice; for( int i=0; iGetNumberOfOutputs(); i++) { this->GetOutput( i )->SetPixel( idx, outputIterators[i].Get() ); ++(outputIterators[i]); } } this->InvokeEvent( IterationEvent() ); } } template void SliceBySliceImageFilter ::PrintSelf(std::ostream &os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "Dimension: " << m_Dimension << std::endl; } } #endif