Orfeo Toolbox  3.16
itkImageBase.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkImageBase.txx,v $
5  Language: C++
6  Date: $Date: 2010-01-21 15:51:32 $
7  Version: $Revision: 1.63 $
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  Portions of this code are covered under the VTK copyright.
13  See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.htm for details.
14 
15  This software is distributed WITHOUT ANY WARRANTY; without even
16  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
17  PURPOSE. See the above copyright notices for more information.
18 
19 =========================================================================*/
20 #ifndef __itkImageBase_txx
21 #define __itkImageBase_txx
22 
23 #include "itkImageBase.h"
24 
25 #include "itkFastMutexLock.h"
26 #include "itkProcessObject.h"
27 #include "itkSpatialOrientation.h"
28 #include <string.h>
29 
30 namespace itk
31 {
32 
36 template<unsigned int VImageDimension>
39 {
40  memset( m_OffsetTable, 0, (VImageDimension+1)*sizeof(unsigned long) );
41  m_Spacing.Fill(1.0);
42  m_Origin.Fill(0.0);
43  m_Direction.SetIdentity();
44  m_IndexToPhysicalPoint.SetIdentity();
45  m_PhysicalPointToIndex.SetIdentity();
46 }
47 
48 
52 template<unsigned int VImageDimension>
53 void
56 {
57  //
58  // We don't modify ourselves because the "ReleaseData" methods depend upon
59  // no modification when initialized. Otherwise BUG: 8490 will
60  // reoccur.
61  //
62  // DO NOT CALL ANY METHODS WHICH MODIFY OURSELVES
63 
64  // Call the superclass which should initialize the BufferedRegion ivar.
65  Superclass::Initialize();
66 
67  // Clear the offset table
68  memset( m_OffsetTable, 0, (VImageDimension+1)*sizeof(unsigned long) );
69 
70  // Clear the BufferedRegion ivar
71  this->InitializeBufferedRegion();
72 }
73 
74 
78 template<unsigned int VImageDimension>
81 {
82 }
83 
84 
85 //----------------------------------------------------------------------------
86 template<unsigned int VImageDimension>
87 void
89 ::SetSpacing(const SpacingType & spacing )
90 {
91  itkDebugMacro("setting Spacing to " << spacing);
92  if( this->m_Spacing != spacing )
93  {
94  this->m_Spacing = spacing;
95  this->ComputeIndexToPhysicalPointMatrices();
96  this->Modified();
97  }
98 }
99 
100 
101 //----------------------------------------------------------------------------
102 template<unsigned int VImageDimension>
103 void
105 ::SetSpacing(const double spacing[VImageDimension] )
106 {
107  SpacingType s(spacing);
108  this->SetSpacing(s);
109 }
110 
111 
112 //----------------------------------------------------------------------------
113 template<unsigned int VImageDimension>
114 void
116 ::SetSpacing(const float spacing[VImageDimension] )
117 {
118  Vector<float, VImageDimension> sf(spacing);
119  SpacingType s;
120  s.CastFrom( sf );
121  this->SetSpacing(s);
122 }
123 
124 //----------------------------------------------------------------------------
125 template<unsigned int VImageDimension>
126 void
128 ::SetOrigin(const double origin[VImageDimension] )
129 {
130  PointType p(origin);
131  this->SetOrigin( p );
132 }
133 
134 
135 //----------------------------------------------------------------------------
136 template<unsigned int VImageDimension>
137 void
139 ::SetOrigin(const float origin[VImageDimension] )
140 {
142  PointType p;
143  p.CastFrom( of );
144  this->SetOrigin( p );
145 }
146 
147 //----------------------------------------------------------------------------
148 template<unsigned int VImageDimension>
149 void
151 ::SetDirection(const DirectionType direction )
152 {
153  bool modified = false;
154  for (unsigned int r = 0; r < VImageDimension; r++)
155  {
156  for (unsigned int c = 0; c < VImageDimension; c++)
157  {
158  if (m_Direction[r][c] != direction[r][c])
159  {
160  m_Direction[r][c] = direction[r][c];
161  modified = true;
162  }
163  }
164  }
165 
166  if (modified)
167  {
168  this->ComputeIndexToPhysicalPointMatrices();
169  }
170 }
171 
172 //----------------------------------------------------------------------------
173 template<unsigned int VImageDimension>
174 void
177 {
178  DirectionType scale;
179 
180  for (unsigned int i=0; i < VImageDimension; i++)
181  {
182  if (this->m_Spacing[i] == 0.0)
183  {
184  itkExceptionMacro("A spacing of 0 is not allowed: Spacing is " << this->m_Spacing);
185  }
186  scale[i][i] = this->m_Spacing[i];
187  }
188 
189  if (vnl_determinant(this->m_Direction.GetVnlMatrix()) == 0.0)
190  {
191  itkExceptionMacro(<< "Bad direction, determinant is 0. Direction is " << this->m_Direction);
192  }
193 
194  this->m_IndexToPhysicalPoint = this->m_Direction * scale;
195  this->m_PhysicalPointToIndex = m_IndexToPhysicalPoint.GetInverse();
196 
197  this->Modified();
198 }
199 
200 //----------------------------------------------------------------------------
201 template<unsigned int VImageDimension>
202 void
205 {
206  // vxl_uint_64 num=1;
207  OffsetValueType num=1;
208  const SizeType& bufferSize = this->GetBufferedRegion().GetSize();
209 
210  // m_OffsetTable[0] = (OffsetValueType)num;
211  m_OffsetTable[0] = num;
212  for (unsigned int i=0; i < VImageDimension; i++)
213  {
214  num *= bufferSize[i];
215  // m_OffsetTable[i+1] = (OffsetValueType)num;
216  m_OffsetTable[i+1] = num;
217  }
218  // if( num > NumericTraits<SizeValueType>::max() )
219  // {
220  // itkExceptionMacro(<< "Requested number of pixels (" << num
221  // << ") is greater than the largest possible number of pixels (" << NumericTraits<SizeValueType>::max() << ").");
222  // }
223 }
224 
225 
226 //----------------------------------------------------------------------------
227 template<unsigned int VImageDimension>
228 void
231 {
232  if( this->GetSource() )
233  {
234  this->GetSource()->UpdateOutputInformation();
235  }
236  else
237  {
238  // If we don't have a source, we should set our Image to span our
239  // buffer (by setting our LargestPossibleRegion to equal our
240  // BufferedRegion). However, if the buffer is empty, we leave the
241  // LargestPossibleRegion at its prior value. This allows InPlace
242  // filters to overwrite their inputs safely (taking ownership of
243  // the pixel buffers), yet respond to subsequent requests for
244  // information.
245  if( this->GetBufferedRegion().GetNumberOfPixels() > 0)
246  {
247  this->SetLargestPossibleRegion( this->GetBufferedRegion() );
248  }
249  }
250 
251  // Now we should know what our largest possible region is. If our
252  // requested region was not set yet, (or has been set to something
253  // invalid - with no data in it ) then set it to the largest possible
254  // region.
255  if ( this->GetRequestedRegion().GetNumberOfPixels() == 0)
256  {
257  this->SetRequestedRegionToLargestPossibleRegion();
258  }
259 }
260 
261 template<unsigned int VImageDimension>
262 void
265 {
266  // If the requested region does not contain any pixels then there is
267  // no reason to Update the output data. This is needed so that
268  // filters don't need to update all inputs. This occours in
269  // ImageBase as oppose to DataObject, but cause this statement
270  // requires the specific GetNumberOfPixels methods ( as oppose to a
271  // generic Region::IsEmpty method ).
272  //
273  // Also note, the check of the largest possible region is needed so
274  // that an exception will be thrown in the process object when no
275  // input has been set. ( This part of the statement could be removed
276  // if this check happened earlier in the pipeline )
277  if( this->GetRequestedRegion().GetNumberOfPixels() > 0
278  || this->GetLargestPossibleRegion().GetNumberOfPixels() == 0 )
279  {
280  this->Superclass::UpdateOutputData();
281  }
282 // if ITK_LEGACY_SILENT or ITK_LEGACY_REMOVE is enabled then we don't
283 // print the waring message
284 #if !defined(ITK_LEGACY_SILENT) && !defined(ITK_LEGACY_REMOVE)
285  else
286  {
287  // Let us try to give a warning of this change in behavior.
288  itkDebugMacro(<<"Not executing UpdateOutputData due to zero pixel condition RequestedRegion:"
289  << this->GetRequestedRegion() << " BufferedRegion: " << this->GetBufferedRegion());
290  }
291 #endif // !ITK_LEGACY_SILENT && !ITK_LEGACY_REMOVE
292 }
293 
294 //----------------------------------------------------------------------------
295 template<unsigned int VImageDimension>
296 void
299 {
300  this->SetRequestedRegion( this->GetLargestPossibleRegion() );
301 }
302 
303 //----------------------------------------------------------------------------
304 template<unsigned int VImageDimension>
305 void
308 {
309  // Standard call to the superclass' method
310  Superclass::CopyInformation(data);
311 
312  if (data)
313  {
314  // Attempt to cast data to an ImageBase
315  const ImageBase<VImageDimension> *imgData;
316 
317  try
318  {
319  imgData = dynamic_cast<const ImageBase<VImageDimension>*>(data);
320  }
321  catch( ... )
322  {
323  return;
324  }
325 
326  if( imgData )
327  {
328  // Copy the meta data for this data type
329  this->SetLargestPossibleRegion( imgData->GetLargestPossibleRegion() );
330  this->SetSpacing( imgData->GetSpacing() );
331  this->SetOrigin( imgData->GetOrigin() );
332  this->SetDirection(imgData->GetDirection() );
333  this->SetNumberOfComponentsPerPixel(
334  imgData->GetNumberOfComponentsPerPixel() );
335  }
336  else
337  {
338  // pointer could not be cast back down
339  itkExceptionMacro( << "itk::ImageBase::CopyInformation() cannot cast "
340  << typeid(data).name() << " to "
341  << typeid(const ImageBase*).name() );
342  }
343  }
344 }
345 
346 
347 //----------------------------------------------------------------------------
348 template<unsigned int VImageDimension>
349 void
351 ::Graft(const DataObject *data)
352 {
353  typedef ImageBase<VImageDimension> ImageBaseType;
354 
355  const ImageBaseType * image;
356 
357  try
358  {
359  image = dynamic_cast< const ImageBaseType * >( data );
360  }
361  catch( ... )
362  {
363  return;
364  }
365 
366  if( !image )
367  {
368  return;
369  }
370 
371  // Copy the meta-information
372  this->CopyInformation( image );
373 
374  // Copy the remaining region information. Subclasses are
375  // responsible for copying the pixel container.
376  this->SetBufferedRegion( image->GetBufferedRegion() );
377  this->SetRequestedRegion( image->GetRequestedRegion() );
378 
379 }
380 
381 
382 //----------------------------------------------------------------------------
383 template<unsigned int VImageDimension>
384 bool
387 {
388  unsigned int i;
389  const IndexType &requestedRegionIndex = this->GetRequestedRegion().GetIndex();
390  const IndexType &bufferedRegionIndex = this->GetBufferedRegion().GetIndex();
391 
392  const SizeType& requestedRegionSize = this->GetRequestedRegion().GetSize();
393  const SizeType& bufferedRegionSize = this->GetBufferedRegion().GetSize();
394 
395  for (i=0; i< VImageDimension; i++)
396  {
397  if ( (requestedRegionIndex[i] < bufferedRegionIndex[i]) ||
398  ((requestedRegionIndex[i] + static_cast<OffsetValueType>(requestedRegionSize[i]))
399  > (bufferedRegionIndex[i] + static_cast<OffsetValueType>(bufferedRegionSize[i]))) )
400  {
401  return true;
402  }
403  }
404 
405  return false;
406 }
407 
408 
409 //----------------------------------------------------------------------------
410 template<unsigned int VImageDimension>
411 bool
414 {
415  bool retval = true;
416  unsigned int i;
417 
418  // Is the requested region within the LargestPossibleRegion?
419  // Note that the test is indeed against the largest possible region
420  // rather than the buffered region; see DataObject::VerifyRequestedRegion.
421  const IndexType &requestedRegionIndex = this->GetRequestedRegion().GetIndex();
422  const IndexType &largestPossibleRegionIndex
423  = this->GetLargestPossibleRegion().GetIndex();
424 
425  const SizeType& requestedRegionSize = this->GetRequestedRegion().GetSize();
426  const SizeType& largestPossibleRegionSize
427  = this->GetLargestPossibleRegion().GetSize();
428 
429  for (i=0; i< VImageDimension; i++)
430  {
431  if ( (requestedRegionIndex[i] < largestPossibleRegionIndex[i]) ||
432  ((requestedRegionIndex[i] + static_cast<long>(requestedRegionSize[i]))
433  > (largestPossibleRegionIndex[i]+static_cast<long>(largestPossibleRegionSize[i]))))
434  {
435  retval = false;
436  }
437  }
438 
439  return retval;
440 }
441 
442 //----------------------------------------------------------------------------
443 template<unsigned int VImageDimension>
444 void
447 {
448  if (m_BufferedRegion != region)
449  {
450  m_BufferedRegion = region;
451  this->ComputeOffsetTable();
452  this->Modified();
453  }
454 }
455 
456 
457 //----------------------------------------------------------------------------
458 template<unsigned int VImageDimension>
459 void
462 {
463  //
464  // We don't modify ourselves because the "ReleaseData" methods depend upon
465  // no modification when initialized.
466  //
467  // Otherwise BUG: 8490 will reoccur
468 
469  m_BufferedRegion = RegionType();
470  this->ComputeOffsetTable();
471 
472 }
473 
474 
475 //----------------------------------------------------------------------------
476 template<unsigned int VImageDimension>
477 void
480 {
481  if (m_RequestedRegion != region)
482  {
483  m_RequestedRegion = region;
484  }
485 }
486 
487 //----------------------------------------------------------------------------
488 template<unsigned int VImageDimension>
489 void
492 {
493  ImageBase *imgData;
494 
495  imgData = dynamic_cast<ImageBase*>(data);
496 
497  if (imgData)
498  {
499  // only copy the RequestedRegion if the parameter object is an image
500  this->SetRequestedRegion( imgData->GetRequestedRegion() );
501  }
502 }
503 
504 //----------------------------------------------------------------------------
505 template<unsigned int VImageDimension>
506 void
509 {
510  if (m_LargestPossibleRegion != region)
511  {
512  m_LargestPossibleRegion = region;
513  this->Modified();
514  }
515 }
516 
517 //----------------------------------------------------------------------------
518 template<unsigned int VImageDimension>
519 unsigned int
522 {
523  // Returns the number of components in the image. Note that for most images
524  // this is 1. Even for Image< RGBPixel< T >, 3 >.
525  // This is > 1 only for time-series images such as itk::VectorImage.
526  return 1;
527 }
528 
529 //----------------------------------------------------------------------------
530 template<unsigned int VImageDimension>
531 void
534 { // does nothing (always 1 )
535 }
536 
540 template<unsigned int VImageDimension>
541 void
543 ::PrintSelf(std::ostream& os, Indent indent) const
544 {
545  Superclass::PrintSelf(os,indent);
546 
547  os << indent << "LargestPossibleRegion: " << std::endl;
548  this->GetLargestPossibleRegion().PrintSelf(os, indent.GetNextIndent());
549 
550  os << indent << "BufferedRegion: " << std::endl;
551  this->GetBufferedRegion().PrintSelf(os, indent.GetNextIndent());
552 
553  os << indent << "RequestedRegion: " << std::endl;
554  this->GetRequestedRegion().PrintSelf(os, indent.GetNextIndent());
555 
556  os << indent << "Spacing: " << this->GetSpacing() << std::endl;
557 
558  os << indent << "Origin: " << this->GetOrigin() << std::endl;\
559 
560  os << indent << "Direction: " << std::endl << this->GetDirection() << std::endl;
561 
562  os << indent << "IndexToPointMatrix: " << std::endl;
563  os << indent << this->m_IndexToPhysicalPoint << std::endl;
564 
565  os << indent << "PointToIndexMatrix: " << std::endl;
566  os << indent << this->m_PhysicalPointToIndex << std::endl;
567 }
568 
569 } // end namespace itk
570 
571 #endif

Generated at Sat Feb 2 2013 23:42:40 for Orfeo Toolbox with doxygen 1.8.1.1