Medical Imaging Interaction Toolkit  2018.04.99-c3229764
Medical Imaging Interaction Toolkit
mitkImage.h
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #ifndef MITKIMAGE_H_HEADER_INCLUDED_C1C2FCD2
14 #define MITKIMAGE_H_HEADER_INCLUDED_C1C2FCD2
15 
16 #include "mitkBaseData.h"
17 #include "mitkImageAccessorBase.h"
18 #include "mitkImageDataItem.h"
19 #include "mitkImageDescriptor.h"
20 #include "mitkImageVtkAccessor.h"
21 #include "mitkLevelWindow.h"
22 #include "mitkPlaneGeometry.h"
23 #include "mitkSlicedData.h"
24 #include <MitkCoreExports.h>
26 
27 // DEPRECATED
28 #include <mitkTimeSlicedGeometry.h>
29 
30 #ifndef __itkHistogram_h
31 #include <itkHistogram.h>
32 #endif
33 
34 class vtkImageData;
35 
36 namespace itk
37 {
38  template <class T>
40 }
41 
42 namespace mitk
43 {
44  class SubImageSelector;
45  class ImageTimeSelector;
46 
47  class ImageStatisticsHolder;
48 
74  {
75  friend class SubImageSelector;
76 
77  friend class ImageAccessorBase;
78  friend class ImageVtkAccessor;
79  friend class ImageVtkReadAccessor;
80  friend class ImageVtkWriteAccessor;
81  friend class ImageReadAccessor;
82  friend class ImageWriteAccessor;
83 
84  public:
86 
87  itkFactorylessNewMacro(Self);
88 
89  itkCloneMacro(Self);
90 
93  typedef itk::Statistics::Histogram<double> HistogramType;
95 
99  {
103  DontManageMemory = ReferenceMemory
104  };
105 
111  typedef std::vector<ImageDataItemPointer> ImageDataItemPointerArray;
112 
113  public:
117  const mitk::PixelType GetPixelType(int n = 0) const;
118 
122  unsigned int GetDimension() const;
123 
129  unsigned int GetDimension(int i) const;
130 
137  DEPRECATED(virtual void *GetData());
138 
139  public:
145  DEPRECATED(double GetPixelValueByIndex(const itk::Index<3> &position,
146  unsigned int timestep = 0,
147  unsigned int component = 0));
148 
154  double GetPixelValueByWorldCoordinate(const mitk::Point3D &position,
155  unsigned int timestep = 0,
156  unsigned int component = 0);
157 
161  virtual vtkImageData *GetVtkImageData(int t = 0, int n = 0);
162  virtual const vtkImageData *GetVtkImageData(int t = 0, int n = 0) const;
163 
167  bool IsSliceSet(int s = 0, int t = 0, int n = 0) const override;
168 
172  bool IsVolumeSet(int t = 0, int n = 0) const override;
173 
177  bool IsChannelSet(int n = 0) const override;
178 
191  virtual bool SetSlice(const void *data, int s = 0, int t = 0, int n = 0);
192 
205  virtual bool SetVolume(const void *data, int t = 0, int n = 0);
206 
219  virtual bool SetChannel(const void *data, int n = 0);
220 
230  virtual bool SetImportSlice(
231  void *data, int s = 0, int t = 0, int n = 0, ImportMemoryManagementType importMemoryManagement = CopyMemory);
232 
242  virtual bool SetImportVolume(void *data,
243  int t = 0,
244  int n = 0,
245  ImportMemoryManagementType importMemoryManagement = CopyMemory);
246 
247  virtual bool SetImportVolume(const void *const_data, int t = 0, int n = 0);
248 
258  virtual bool SetImportChannel(void *data,
259  int n = 0,
260  ImportMemoryManagementType importMemoryManagement = CopyMemory);
261 
266  virtual void Initialize(const mitk::PixelType &type,
267  unsigned int dimension,
268  const unsigned int *dimensions,
269  unsigned int channels = 1);
270 
279  virtual void Initialize(const mitk::PixelType &type,
280  const mitk::BaseGeometry &geometry,
281  unsigned int channels = 1,
282  int tDim = 1);
283 
290  DEPRECATED(virtual void Initialize(const mitk::PixelType & /*type*/,
291  const mitk::TimeSlicedGeometry * /*geometry*/,
292  unsigned int /*channels = 1*/,
293  int /*tDim=1*/))
294  {
295  }
296 
305  virtual void Initialize(const mitk::PixelType &type,
306  const mitk::TimeGeometry &geometry,
307  unsigned int channels = 1,
308  int tDim = -1);
309 
320  DEPRECATED(virtual void Initialize(const mitk::PixelType &type,
321  int sDim,
322  const mitk::PlaneGeometry &geometry2d,
323  bool flipped,
324  unsigned int channels = 1,
325  int tDim = 1));
326 
327  virtual void Initialize(const mitk::PixelType &type,
328  int sDim,
329  const mitk::PlaneGeometry &geometry2d,
330  unsigned int channels = 1,
331  int tDim = 1);
332 
338  virtual void Initialize(const mitk::Image *image);
339 
340  virtual void Initialize(const mitk::ImageDescriptor::Pointer inDesc);
341 
354  virtual void Initialize(vtkImageData *vtkimagedata, int channels = 1, int tDim = -1, int sDim = -1, int pDim = -1);
355 
367  template <typename itkImageType>
368  void InitializeByItk(const itkImageType *itkimage, int channels = 1, int tDim = -1, int sDim = -1)
369  {
370  if (itkimage == nullptr)
371  return;
372 
373  MITK_DEBUG << "Initializing MITK image from ITK image.";
374  // build array with dimensions in each direction with at least 4 entries
375  m_Dimension = itkimage->GetImageDimension();
376  unsigned int i, *tmpDimensions = new unsigned int[m_Dimension > 4 ? m_Dimension : 4];
377  for (i = 0; i < m_Dimension; ++i)
378  tmpDimensions[i] = itkimage->GetLargestPossibleRegion().GetSize().GetSize()[i];
379  if (m_Dimension < 4)
380  {
381  unsigned int *p;
382  for (i = 0, p = tmpDimensions + m_Dimension; i < 4 - m_Dimension; ++i, ++p)
383  *p = 1;
384  }
385 
386  // overwrite number of slices if sDim is set
387  if ((m_Dimension > 2) && (sDim >= 0))
388  tmpDimensions[2] = sDim;
389  // overwrite number of time points if tDim is set
390  if ((m_Dimension > 3) && (tDim >= 0))
391  tmpDimensions[3] = tDim;
392 
393  // rough initialization of Image
394  // mitk::PixelType importType = ImportItkPixelType( itkimage::PixelType );
395 
396  Initialize(
397  MakePixelType<itkImageType>(itkimage->GetNumberOfComponentsPerPixel()), m_Dimension, tmpDimensions, channels);
398  const typename itkImageType::SpacingType &itkspacing = itkimage->GetSpacing();
399 
400  MITK_DEBUG << "ITK spacing " << itkspacing;
401  // access spacing of itk::Image
402  Vector3D spacing;
403  FillVector3D(spacing, itkspacing[0], 1.0, 1.0);
404  if (m_Dimension >= 2)
405  spacing[1] = itkspacing[1];
406  if (m_Dimension >= 3)
407  spacing[2] = itkspacing[2];
408 
409  // access origin of itk::Image
410  Point3D origin;
411  const typename itkImageType::PointType &itkorigin = itkimage->GetOrigin();
412  MITK_DEBUG << "ITK origin " << itkorigin;
413  FillVector3D(origin, itkorigin[0], 0.0, 0.0);
414  if (m_Dimension >= 2)
415  origin[1] = itkorigin[1];
416  if (m_Dimension >= 3)
417  origin[2] = itkorigin[2];
418 
419  // access direction of itk::Imagm_PixelType = new mitk::PixelType(type);e and include spacing
420  const typename itkImageType::DirectionType &itkdirection = itkimage->GetDirection();
421  MITK_DEBUG << "ITK direction " << itkdirection;
422  mitk::Matrix3D matrix;
423  matrix.SetIdentity();
424  unsigned int j, itkDimMax3 = (m_Dimension >= 3 ? 3 : m_Dimension);
425  // check if spacing has no zero entry and itkdirection has no zero columns
426  bool itkdirectionOk = true;
427  mitk::ScalarType columnSum;
428  for (j = 0; j < itkDimMax3; ++j)
429  {
430  columnSum = 0.0;
431  for (i = 0; i < itkDimMax3; ++i)
432  {
433  columnSum += fabs(itkdirection[i][j]);
434  }
435  if (columnSum < mitk::eps)
436  {
437  itkdirectionOk = false;
438  }
439  if ((spacing[j] < -mitk::eps) // (normally sized) negative value
440  &&
441  (j == 2) && (m_Dimensions[2] == 1))
442  {
443  // Negative spacings can occur when reading single DICOM slices with ITK via GDCMIO
444  // In these cases spacing is not determind by ITK correctly (because it distinguishes correctly
445  // between slice thickness and inter slice distance -- slice distance is meaningless for
446  // single slices).
447  // I experienced that ITK produced something meaningful nonetheless because is is
448  // evaluating the tag "(0018,0088) Spacing between slices" as a fallback. This tag is not
449  // reliable (http://www.itk.org/pipermail/insight-users/2005-September/014711.html)
450  // but gives at least a hint.
451  // In real world cases I experienced that this tag contained the correct inter slice distance
452  // with a negative sign, so we just invert such negative spacings.
453  MITK_WARN << "Illegal value of itk::Image::GetSpacing()[" << j << "]=" << spacing[j]
454  << ". Using inverted value " << -spacing[j];
455  spacing[j] = -spacing[j];
456  }
457  else if (spacing[j] < mitk::eps) // value near zero
458  {
459  MITK_ERROR << "Illegal value of itk::Image::GetSpacing()[" << j << "]=" << spacing[j]
460  << ". Using 1.0 instead.";
461  spacing[j] = 1.0;
462  }
463  }
464  if (itkdirectionOk == false)
465  {
466  MITK_ERROR << "Illegal matrix returned by itk::Image::GetDirection():" << itkdirection
467  << " Using identity instead.";
468  for (i = 0; i < itkDimMax3; ++i)
469  for (j = 0; j < itkDimMax3; ++j)
470  if (i == j)
471  matrix[i][j] = spacing[j];
472  else
473  matrix[i][j] = 0.0;
474  }
475  else
476  {
477  for (i = 0; i < itkDimMax3; ++i)
478  for (j = 0; j < itkDimMax3; ++j)
479  matrix[i][j] = itkdirection[i][j] * spacing[j];
480  }
481 
482  // re-initialize PlaneGeometry with origin and direction
483  PlaneGeometry *planeGeometry = static_cast<PlaneGeometry *>(GetSlicedGeometry(0)->GetPlaneGeometry(0));
484  planeGeometry->SetOrigin(origin);
485  planeGeometry->GetIndexToWorldTransform()->SetMatrix(matrix);
486 
487  // re-initialize SlicedGeometry3D
488  SlicedGeometry3D *slicedGeometry = GetSlicedGeometry(0);
489  slicedGeometry->InitializeEvenlySpaced(planeGeometry, m_Dimensions[2]);
490  slicedGeometry->SetSpacing(spacing);
491 
492  // re-initialize TimeGeometry
493  ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New();
494  timeGeometry->Initialize(slicedGeometry, m_Dimensions[3]);
495  SetTimeGeometry(timeGeometry);
496 
497  // clean-up
498  delete[] tmpDimensions;
499 
500  this->Initialize();
501  }
502 
507  virtual bool IsValidSlice(int s = 0, int t = 0, int n = 0) const;
508 
513  virtual bool IsValidVolume(int t = 0, int n = 0) const;
514 
519  virtual bool IsValidChannel(int n = 0) const;
520 
526  bool IsRotated() const;
527 
533  unsigned int *GetDimensions() const;
534 
535  ImageDescriptor::Pointer GetImageDescriptor() const { return m_ImageDescriptor; }
536  ChannelDescriptor GetChannelDescriptor(int id = 0) const { return m_ImageDescriptor->GetChannelDescriptor(id); }
539  void SetGeometry(BaseGeometry *aGeometry3D) override;
540 
544  virtual ImageDataItemPointer GetSliceData(int s = 0,
545  int t = 0,
546  int n = 0,
547  void *data = nullptr,
548  ImportMemoryManagementType importMemoryManagement = CopyMemory) const;
549 
553  virtual ImageDataItemPointer GetVolumeData(int t = 0,
554  int n = 0,
555  void *data = nullptr,
556  ImportMemoryManagementType importMemoryManagement = CopyMemory) const;
557 
561  virtual ImageDataItemPointer GetChannelData(int n = 0,
562  void *data = nullptr,
563  ImportMemoryManagementType importMemoryManagement = CopyMemory) const;
564 
568  DEPRECATED(ScalarType GetScalarValueMin(int t = 0) const);
569 
575  DEPRECATED(ScalarType GetScalarValueMax(int t = 0) const);
576 
582  DEPRECATED(ScalarType GetScalarValue2ndMin(int t = 0) const);
583 
589  DEPRECATED(ScalarType GetScalarValueMinNoRecompute(unsigned int t = 0) const);
590 
596  DEPRECATED(ScalarType GetScalarValue2ndMinNoRecompute(unsigned int t = 0) const);
597 
603  DEPRECATED(ScalarType GetScalarValue2ndMax(int t = 0) const);
604 
610  DEPRECATED(ScalarType GetScalarValueMaxNoRecompute(unsigned int t = 0) const);
611 
617  DEPRECATED(ScalarType GetScalarValue2ndMaxNoRecompute(unsigned int t = 0) const);
618 
624  DEPRECATED(ScalarType GetCountOfMinValuedVoxels(int t = 0) const);
625 
631  DEPRECATED(ScalarType GetCountOfMaxValuedVoxels(int t = 0) const);
632 
638  DEPRECATED(unsigned int GetCountOfMaxValuedVoxelsNoRecompute(unsigned int t = 0) const);
639 
645  DEPRECATED(unsigned int GetCountOfMinValuedVoxelsNoRecompute(unsigned int t = 0) const);
646 
653  StatisticsHolderPointer GetStatistics() const { return m_ImageStatistics; }
654  protected:
656 
658 
659  int GetSliceIndex(int s = 0, int t = 0, int n = 0) const;
660 
661  int GetVolumeIndex(int t = 0, int n = 0) const;
662 
663  void ComputeOffsetTable();
664 
665  virtual bool IsValidTimeStep(int t) const;
666 
667  void Expand(unsigned int timeSteps) override;
668 
669  virtual ImageDataItemPointer AllocateSliceData(
670  int s = 0,
671  int t = 0,
672  int n = 0,
673  void *data = nullptr,
674  ImportMemoryManagementType importMemoryManagement = CopyMemory) const;
675 
676  virtual ImageDataItemPointer AllocateVolumeData(
677  int t = 0, int n = 0, void *data = nullptr, ImportMemoryManagementType importMemoryManagement = CopyMemory) const;
678 
679  virtual ImageDataItemPointer AllocateChannelData(
680  int n = 0, void *data = nullptr, ImportMemoryManagementType importMemoryManagement = CopyMemory) const;
681 
682  Image();
683 
684  Image(const Image &other);
685 
686  ~Image() override;
687 
688  void Clear() override;
689 
691  void Initialize() override;
692 
693  void PrintSelf(std::ostream &os, itk::Indent indent) const override;
694 
695  mutable ImageDataItemPointerArray m_Channels;
696  mutable ImageDataItemPointerArray m_Volumes;
697  mutable ImageDataItemPointerArray m_Slices;
698  mutable itk::SimpleFastMutexLock m_ImageDataArraysLock;
699 
700  unsigned int m_Dimension;
701 
702  unsigned int *m_Dimensions;
703 
705 
706  size_t *m_OffsetTable;
707  ImageDataItemPointer m_CompleteData;
708 
709  // Image statistics Holder replaces the former implementation directly inside this class
710  friend class ImageStatisticsHolder;
711  StatisticsHolderPointer m_ImageStatistics;
712 
713  private:
714  ImageDataItemPointer GetSliceData_unlocked(
715  int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const;
716  ImageDataItemPointer GetVolumeData_unlocked(int t,
717  int n,
718  void *data,
719  ImportMemoryManagementType importMemoryManagement) const;
720  ImageDataItemPointer GetChannelData_unlocked(int n,
721  void *data,
722  ImportMemoryManagementType importMemoryManagement) const;
723 
724  ImageDataItemPointer AllocateSliceData_unlocked(
725  int s, int t, int n, void *data, ImportMemoryManagementType importMemoryManagement) const;
726  ImageDataItemPointer AllocateVolumeData_unlocked(int t,
727  int n,
728  void *data,
729  ImportMemoryManagementType importMemoryManagement) const;
730  ImageDataItemPointer AllocateChannelData_unlocked(int n,
731  void *data,
732  ImportMemoryManagementType importMemoryManagement) const;
733 
734  bool IsSliceSet_unlocked(int s, int t, int n) const;
735  bool IsVolumeSet_unlocked(int t, int n) const;
736  bool IsChannelSet_unlocked(int n) const;
737 
739  mutable std::vector<ImageAccessorBase *> m_Readers;
741  mutable std::vector<ImageAccessorBase *> m_Writers;
743  mutable std::vector<ImageAccessorBase *> m_VtkReaders;
744 
746  itk::SimpleFastMutexLock m_ReadWriteLock;
748  itk::SimpleFastMutexLock m_VtkReadersLock;
749  };
750 
772  const mitk::Image *leftHandSide, const mitk::Image *rightHandSide, ScalarType eps, bool verbose));
773 
792  MITKCORE_EXPORT bool Equal(const mitk::Image &leftHandSide,
793  const mitk::Image &rightHandSide,
794  ScalarType eps,
795  bool verbose);
796 
797 } // namespace mitk
798 
799 #endif /* MITKIMAGE_H_HEADER_INCLUDED_C1C2FCD2 */
itk::SmartPointer< ImageDataItem > ImageDataItemPointer
Definition: mitkImage.h:89
unsigned int * m_Dimensions
Definition: mitkImage.h:702
MITKCORE_EXPORT const ScalarType eps
void SetSpacing(const mitk::Vector3D &aSpacing, bool enforceSetSpacing=false)
Set the spacing (m_Spacing).
#define MITKCORE_EXPORT
Base of all data objects.
Definition: mitkBaseData.h:42
#define MITK_ERROR
Definition: mitkLogMacros.h:20
double ScalarType
ImageDataItemPointerArray m_Slices
Definition: mitkImage.h:697
vcl_size_t * m_OffsetTable
Definition: mitkImage.h:706
#define MITK_DEBUG
Definition: mitkLogMacros.h:22
DataCollection - Class to facilitate loading/accessing structured data.
ImageDataItemPointerArray m_Channels
Definition: mitkImage.h:695
StatisticsHolderPointer GetStatistics() const
Returns a pointer to the ImageStatisticsHolder object that holds all statistics information for the i...
Definition: mitkImage.h:653
An object which holds all essential information about a single channel of an Image.
ImageVtkAccessor class provides any image read access which is required by Vtk methods.
void FillVector3D(Tout &out, mitk::ScalarType x, mitk::ScalarType y, mitk::ScalarType z)
Definition: mitkArray.h:106
ImageDataItemPointerArray m_Volumes
Definition: mitkImage.h:696
ChannelDescriptor GetChannelDescriptor(int id=0) const
Definition: mitkImage.h:536
itk::Statistics::Histogram< double > HistogramType
Definition: mitkImage.h:93
#define DEPRECATED(func)
Definition: mitkCommon.h:179
itk::SimpleFastMutexLock m_ImageDataArraysLock
Definition: mitkImage.h:698
mitk::ImageStatisticsHolder * StatisticsHolderPointer
Definition: mitkImage.h:94
StatisticsHolderPointer m_ImageStatistics
Definition: mitkImage.h:711
virtual void InitializeEvenlySpaced(mitk::PlaneGeometry *geometry2D, unsigned int slices)
Completely initialize this instance as evenly-spaced with slices parallel to the provided PlaneGeomet...
class ITK_EXPORT Image
#define MITK_WARN
Definition: mitkLogMacros.h:19
Super class of data objects consisting of slices.
std::vector< ImageDataItemPointer > ImageDataItemPointerArray
Vector container of SmartPointers to ImageDataItems; Class is only for internal usage to allow conven...
Definition: mitkImage.h:111
#define mitkClassMacro(className, SuperClassName)
Definition: mitkCommon.h:40
void SetOrigin(const Point3D &origin)
Set the origin, i.e. the upper-left corner of the plane.
Image class for storing images.
Definition: mitkImage.h:73
unsigned int m_Dimension
Definition: mitkImage.h:700
itk::MutexLockHolder< itk::SimpleFastMutexLock > MutexHolder
Definition: mitkImage.h:655
Describes the geometry of a data object consisting of slices.
#define mitkCloneMacro(classname)
Definition: mitkCommon.h:158
Class holding the statistics informations about a single mitk::Image.
ImageVtkReadAccessor class provides any image read access which is required by Vtk methods...
mitk::AffineTransform3D * GetIndexToWorldTransform()
Get the transformation used to convert from index to world coordinates.
Base class of all classes providing access to parts of an image.
ImageWriteAccessor class to get locked write-access for a particular image part.
Describes a two-dimensional, rectangular plane.
ImageDescriptor::Pointer GetImageDescriptor() const
Definition: mitkImage.h:535
ImageReadAccessor class to get locked read access for a particular image part.
ImageVtkWriteAccessor class provides any image write access which is required by Vtk methods...
ImageDataItemPointer m_CompleteData
Definition: mitkImage.h:707
MITKCORE_EXPORT bool Equal(const mitk::Image &leftHandSide, const mitk::Image &rightHandSide, ScalarType eps, bool verbose)
Equal A function comparing two images for beeing equal in meta- and imagedata.
ImportMemoryManagementType
Definition: mitkImage.h:98
BaseGeometry Describes the geometry of a data object.
void InitializeByItk(const itkImageType *itkimage, int channels=1, int tDim=-1, int sDim=-1)
Definition: mitkImage.h:368
Class for defining the data type of pixels.
Definition: mitkPixelType.h:51
ImageDescriptor::Pointer m_ImageDescriptor
Definition: mitkImage.h:704