Orfeo Toolbox  3.16
itkPasteImageFilter.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkPasteImageFilter.txx,v $
5  Language: C++
6  Date: $Date: 2009-07-14 11:49:10 $
7  Version: $Revision: 1.12 $
8 
9  Copyright (c) Insight Software Consortium. All rights reserved.
10  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11 
12  This software is distributed WITHOUT ANY WARRANTY; without even
13  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  PURPOSE. See the above copyright notices for more information.
15 
16 =========================================================================*/
17 #ifndef __itkPasteImageFilter_txx
18 #define __itkPasteImageFilter_txx
19 
20 #include "itkPasteImageFilter.h"
21 #include "itkImageRegionIterator.h"
23 #include "itkObjectFactory.h"
24 #include "itkProgressReporter.h"
25 
26 
27 namespace itk
28 {
29 
33 template <class TInputImage, class TSourceImage, class TOutputImage>
36 {
38 
39  this->InPlaceOff();
40  m_DestinationIndex.Fill(0);
41 }
42 
43 template <class TInputImage, class TSourceImage, class TOutputImage>
44 void
47 {
48  // Process object is not const-correct so the const casting is required.
49  this->SetNthInput(1, const_cast<SourceImageType *>( src ));
50 }
51 
52 template <class TInputImage, class TSourceImage, class TOutputImage>
56 {
57  const SourceImageType * sourceImage =
58  dynamic_cast< const SourceImageType * >( this->ProcessObject::GetInput(1) );
59  return sourceImage;
60 }
61 
62 template <class TInputImage, class TSourceImage, class TOutputImage>
63 void
66 {
67  // Process object is not const-correct so the const casting is required.
68  this->SetNthInput(0, const_cast<InputImageType *>( src ));
69 }
70 
71 template <class TInputImage, class TSourceImage, class TOutputImage>
75 {
76  const InputImageType * destinationImage =
77  dynamic_cast< const InputImageType * >( this->ProcessObject::GetInput(0) );
78  return destinationImage;
79 }
80 
84 template <class TInputImage, class TSourceImage, class TOutputImage>
85 void
87 ::PrintSelf(std::ostream& os, Indent indent) const
88 {
89  Superclass::PrintSelf(os,indent);
90 
91  os << indent << "DestinationIndex: " << m_DestinationIndex << std::endl;
92  os << indent << "SourceRegion: " << m_SourceRegion << std::endl;
93 }
94 
98 template <class TInputImage, class TSourceImage, class TOutputImage>
99 void
102 {
103  // call the superclass' implementation of this method
104  Superclass::GenerateInputRequestedRegion();
105 
106  // get the pointers for the inputs and output
107  InputImagePointer destPtr = const_cast< InputImageType * >( this->GetInput() );
108  SourceImagePointer sourcePtr = const_cast< SourceImageType * >( this->GetSourceImage() );
109  OutputImagePointer outputPtr = this->GetOutput();
110 
111  if( !destPtr || !sourcePtr || !outputPtr )
112  {
113  return;
114  }
115 
116  // second input must include the SourceRegion
117  sourcePtr->SetRequestedRegion( m_SourceRegion );
118 
119  // first input must match the output requested region
120  destPtr->SetRequestedRegion( outputPtr->GetRequestedRegion() );
121 }
122 
135 template <class TInputImage, class TSourceImage, class TOutputImage>
136 void
138 ::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
139  int threadId)
140 {
141  itkDebugMacro(<<"Actually executing");
142 
143  // Get the input and output pointers
144  typename Superclass::InputImageConstPointer destPtr = this->GetInput();
145  SourceImageConstPointer sourcePtr = this->GetSourceImage();
146  typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
147 
148  // support progress methods/callbacks
149  ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
150 
151  // What is the region on the destination image would be overwritten by the source?
152  // Do we need to use the source image at all for the region generated by this thread?
153 
154  bool useSource;
155  SourceImageRegionType sourceRegionInDestinationImage;
156  SourceImageRegionType sourceRegionInDestinationImageCropped;
157  sourceRegionInDestinationImage.SetIndex( m_DestinationIndex );
158  sourceRegionInDestinationImage.SetSize( m_SourceRegion.GetSize() );
159 
160  if ( sourceRegionInDestinationImage.Crop( outputRegionForThread ) )
161  {
162  // paste region is inside this thread
163  useSource = true;
164  sourceRegionInDestinationImageCropped = sourceRegionInDestinationImage;
165  }
166  else
167  {
168  // paste region is outside this thread
169  useSource = false;
170  }
171 
172  // If the source image needs to be used to generate the output image, does the
173  // destination image need to be used? i.e. will the source region completely
174  // overlap the destination region for this thread?
175  bool useOnlySource;
176  if ( useSource && (sourceRegionInDestinationImageCropped == outputRegionForThread) )
177  {
178  // sourceRegionInDestinationImage completely overlaps the output
179  // region for this thread, so we'll only copy data from the source
180  useOnlySource = true;
181  }
182  else
183  {
184  // sourceRegionInDestinationImage only partially overlaps the
185  // output region for this thread so we need to copy from both
186  // inputs
187  useOnlySource = false;
188  }
189 
190  // If the source needs to be used, what part of the source needs to copied
191  // by this thread?
192  SourceImageRegionType sourceRegionInSourceImageCropped;
193  if ( useSource )
194  {
195  // what is the proposed shift from destination to source?
196  Offset<InputImageDimension> originalOffsetFromDestinationToSource;
197  originalOffsetFromDestinationToSource = m_SourceRegion.GetIndex() - m_DestinationIndex;
198 
199  // transform the cropped index back into the source image
200  InputImageIndexType sourceIndexInSourceImageCropped;
201  sourceIndexInSourceImageCropped = sourceRegionInDestinationImageCropped.GetIndex()
202  + originalOffsetFromDestinationToSource;
203 
204  // set the values in the region
205  sourceRegionInSourceImageCropped.SetIndex( sourceIndexInSourceImageCropped );
206  sourceRegionInSourceImageCropped.SetSize( sourceRegionInDestinationImageCropped.GetSize() );
207  }
208 
209 
210  // Define iterators types
211  typedef ImageRegionIterator<OutputImageType> OutputIterator;
212  typedef ImageRegionConstIterator<InputImageType> InputIterator;
213  typedef ImageRegionConstIterator<SourceImageType> SourceIterator;
214 
215  // There are three cases that we need to consider:
216  //
217  // 1. source region does not impact this thread, so copy data from
218  // from the destination image to the output
219  //
220  // 2. source region completely overlaps the output region for this
221  // thread, so copy data from the source image to the output
222  //
223  // 3. source region partially overlaps the output region for this
224  // thread, so copy data as needed from both the source and
225  // destination.
226  //
227  if ( !useSource && !(this->GetInPlace() && this->CanRunInPlace()))
228  {
229  // paste region is outside this thread, so just copy the destination
230  // input to the output
231  OutputIterator outIt(outputPtr, outputRegionForThread);
232  InputIterator destIt(destPtr, outputRegionForThread);
233 
234  // walk the output region, and sample the destination image
235  while( !outIt.IsAtEnd() )
236  {
237  // copy the input pixel to the output
238  outIt.Set( static_cast<OutputImagePixelType>(destIt.Get()) );
239  ++outIt;
240  ++destIt;
241  progress.CompletedPixel();
242  }
243  }
244  else if ( useOnlySource )
245  {
246  // paste region completely overlaps the output region
247  // for this thread, so copy data from the second input
248  // to the output
249  OutputIterator outIt(outputPtr, outputRegionForThread);
250  SourceIterator sourceIt(sourcePtr, sourceRegionInSourceImageCropped);
251 
252  // walk the output region, and sample the source image
253  while( !outIt.IsAtEnd() )
254  {
255  // copy the input pixel to the output
256  outIt.Set( static_cast<OutputImagePixelType>( sourceIt.Get()) );
257  ++outIt;
258  ++sourceIt;
259  progress.CompletedPixel();
260  }
261  }
262  else
263  {
264  // paste region partially overlaps the output region for the
265  // thread, so we need copy data from both inputs as necessary. the
266  // following code could be optimized. this case could be
267  // decomposed further such the output is broken into a set of
268  // regions where each region would get data from either the
269  // destination or the source images (but not both). but for the
270  // sake of simplicity and running under the assumption that the
271  // source image is smaller than the destination image, we'll just
272  // copy the destination to the output then overwrite the
273  // appropriate output pixels with the source.
274 
275  // Copy destination to output
276  //
277  OutputIterator outIt(outputPtr, outputRegionForThread);
278  InputIterator destIt(destPtr, outputRegionForThread);
279 
280  // walk the output region, and sample the destination image
281  if (!(this->GetInPlace() && this->CanRunInPlace()))
282  {
283  while( !outIt.IsAtEnd() )
284  {
285  // copy the input pixel to the output
286  outIt.Set( static_cast<OutputImagePixelType>(destIt.Get()) );
287  ++outIt;
288  ++destIt;
289  progress.CompletedPixel();
290  }
291  }
292 
293  // Copy source to output
294  //
295  SourceIterator sourceIt(sourcePtr, sourceRegionInSourceImageCropped);
296 
297  // reset the output iterator to walk the section of the image covered
298  // by the source image
299  outIt = OutputIterator(outputPtr, sourceRegionInDestinationImageCropped);
300 
301  // walk the output region, and sample the source image
302  while( !outIt.IsAtEnd() )
303  {
304  // copy the input pixel to the output
305  outIt.Set( static_cast<OutputImagePixelType>(sourceIt.Get()) );
306  ++outIt;
307  ++sourceIt;
308  progress.CompletedPixel();
309  }
310 
311  }
312 }
313 
314 } // end namespace itk
315 
316 #endif

Generated at Sat Feb 2 2013 23:58:45 for Orfeo Toolbox with doxygen 1.8.1.1