1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://www.centreleonberard.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the copyright notices for more information.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
18 #ifndef _clitkExtractImageFilter_txx
19 #define _clitkExtractImageFilter_txx
21 #include "clitkExtractImageFilter.h"
22 #include "itkImageRegionIterator.h"
23 #include "itkImageRegionConstIterator.h"
24 #include "itkObjectFactory.h"
25 #include "itkExtractImageFilterRegionCopier.h"
26 #include "itkProgressReporter.h"
35 template <class TInputImage, class TOutputImage>
36 ExtractImageFilter<TInputImage,TOutputImage>
37 ::ExtractImageFilter()
45 template <class TInputImage, class TOutputImage>
47 ExtractImageFilter<TInputImage,TOutputImage>
48 ::PrintSelf(std::ostream& os, itk::Indent indent) const
50 Superclass::PrintSelf(os,indent);
52 os << indent << "ExtractionRegion: " << m_ExtractionRegion << std::endl;
53 os << indent << "OutputImageRegion: " << m_OutputImageRegion << std::endl;
57 template<class TInputImage, class TOutputImage>
59 ExtractImageFilter<TInputImage,TOutputImage>
60 ::CallCopyOutputRegionToInputRegion(InputImageRegionType &destRegion,
61 const OutputImageRegionType &srcRegion)
63 ExtractImageFilterRegionCopierType extractImageRegionCopier;
64 extractImageRegionCopier(destRegion, srcRegion, m_ExtractionRegion);
68 template <class TInputImage, class TOutputImage>
70 ExtractImageFilter<TInputImage,TOutputImage>
71 ::SetExtractionRegion(InputImageRegionType extractRegion)
73 m_ExtractionRegion = extractRegion;
75 unsigned int nonzeroSizeCount = 0;
76 InputImageSizeType inputSize = extractRegion.GetSize();
77 OutputImageSizeType outputSize;
78 OutputImageIndexType outputIndex;
81 * check to see if the number of non-zero entries in the extraction region
82 * matches the number of dimensions in the output image.
84 for (unsigned int i = 0; i < InputImageDimension; ++i)
88 outputSize[nonzeroSizeCount] = inputSize[i];
89 outputIndex[nonzeroSizeCount] = extractRegion.GetIndex()[i];
94 if (nonzeroSizeCount != OutputImageDimension)
96 itkExceptionMacro("Extraction Region not consistent with output image");
99 m_OutputImageRegion.SetSize(outputSize);
100 m_OutputImageRegion.SetIndex(outputIndex);
107 * ExtractImageFilter can produce an image which is a different resolution
108 * than its input image. As such, ExtractImageFilter needs to provide an
109 * implementation for GenerateOutputInformation() in order to inform
110 * the pipeline execution model. The original documentation of this
113 * \sa ProcessObject::GenerateOutputInformaton()
115 template <class TInputImage, class TOutputImage>
117 ExtractImageFilter<TInputImage,TOutputImage>
118 ::GenerateOutputInformation()
120 // do not call the superclass' implementation of this method since
121 // this filter allows the input and the output to be of different dimensions
123 // get pointers to the input and output
124 typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
125 typename Superclass::InputImageConstPointer inputPtr = this->GetInput();
127 if ( !outputPtr || !inputPtr)
132 // Set the output image size to the same value as the extraction region.
133 outputPtr->SetLargestPossibleRegion( m_OutputImageRegion );
135 // Set the output spacing and origin
136 const itk::ImageBase<InputImageDimension> *phyData;
139 = dynamic_cast<const itk::ImageBase<InputImageDimension>*>(this->GetInput());
143 // Copy what we can from the image from spacing and origin of the input
144 // This logic needs to be augmented with logic that select which
145 // dimensions to copy
148 const typename InputImageType::SpacingType&
149 inputSpacing = inputPtr->GetSpacing();
150 const typename InputImageType::DirectionType&
151 inputDirection = inputPtr->GetDirection();
152 const typename InputImageType::PointType&
153 inputOrigin = inputPtr->GetOrigin();
155 typename OutputImageType::SpacingType outputSpacing;
156 typename OutputImageType::DirectionType outputDirection;
157 typename OutputImageType::PointType outputOrigin;
159 if ( static_cast<unsigned int>(OutputImageDimension) >
160 static_cast<unsigned int>(InputImageDimension ) )
162 // copy the input to the output and fill the rest of the
163 // output with zeros.
164 for (i=0; i < InputImageDimension; ++i)
166 outputSpacing[i] = inputSpacing[i];
167 outputOrigin[i] = inputOrigin[i];
168 for (unsigned int dim = 0; dim < InputImageDimension; ++dim)
170 outputDirection[i][dim] = inputDirection[i][dim];
173 for (; i < OutputImageDimension; ++i)
175 outputSpacing[i] = 1.0;
176 outputOrigin[i] = 0.0;
177 for (unsigned int dim = 0; dim < InputImageDimension; ++dim)
179 outputDirection[i][dim] = 0.0;
181 outputDirection[i][i] = 1.0;
186 // copy the non-collapsed part of the input spacing and origing to the output
187 int nonZeroCount = 0;
188 for (i=0; i < InputImageDimension; ++i)
190 if (m_ExtractionRegion.GetSize()[i])
192 outputSpacing[nonZeroCount] = inputSpacing[i];
193 outputOrigin[nonZeroCount] = inputOrigin[i];
194 int nonZeroCount2 = 0;
195 for (unsigned int dim = 0; dim < InputImageDimension; ++dim)
197 if (m_ExtractionRegion.GetSize()[dim])
199 outputDirection[nonZeroCount][nonZeroCount2] =
200 inputDirection[i][dim];
209 // set the spacing and origin
210 outputPtr->SetSpacing( outputSpacing );
211 outputPtr->SetDirection( outputDirection );
212 outputPtr->SetOrigin( outputOrigin );
213 outputPtr->SetNumberOfComponentsPerPixel(inputPtr->GetNumberOfComponentsPerPixel() );
217 // pointer could not be cast back down
218 itkExceptionMacro(<< "itk::ExtractImageFilter::GenerateOutputInformation "
219 << "cannot cast input to "
220 << typeid(itk::ImageBase<InputImageDimension>*).name() );
225 * ExtractImageFilter can be implemented as a multithreaded filter.
226 * Therefore, this implementation provides a ThreadedGenerateData()
227 * routine which is called for each processing thread. The output
228 * image data is allocated automatically by the superclass prior to
229 * calling ThreadedGenerateData(). ThreadedGenerateData can only
230 * write to the portion of the output image specified by the
231 * parameter "outputRegionForThread"
233 * \sa ImageToImageFilter::ThreadedGenerateData(),
234 * ImageToImageFilter::GenerateData()
236 template <class TInputImage, class TOutputImage>
238 ExtractImageFilter<TInputImage,TOutputImage>
239 ::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
242 itkDebugMacro(<<"Actually executing");
244 // Get the input and output pointers
245 typename Superclass::InputImageConstPointer inputPtr = this->GetInput();
246 typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
248 // support progress methods/callbacks
249 itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
251 // Define the portion of the input to walk for this thread
252 InputImageRegionType inputRegionForThread;
253 this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread);
255 // Define the iterators.
256 typedef itk::ImageRegionIterator<TOutputImage> OutputIterator;
257 typedef itk::ImageRegionConstIterator<TInputImage> InputIterator;
259 OutputIterator outIt(outputPtr, outputRegionForThread);
260 InputIterator inIt(inputPtr, inputRegionForThread);
262 // walk the output region, and sample the input image
263 while( !outIt.IsAtEnd() )
265 // copy the input pixel to the output
266 outIt.Set( static_cast<OutputImagePixelType>(inIt.Get()));
269 progress.CompletedPixel();
273 } // end namespace clitk