Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkCropTimestepsImageFilter.cpp
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 
14 
15 #include <mitkImage.h>
17 #include <mitkImageTimeSelector.h>
18 #include <mitkImageReadAccessor.h>
19 
20 
21  void mitk::CropTimestepsImageFilter::VerifyInputImage(const mitk::Image* inputImage) const
22  {
23  if (!inputImage->IsInitialized())
24  mitkThrow() << "Input image is not initialized.";
25 
26  if (!inputImage->IsVolumeSet())
27  mitkThrow() << "Input image volume is not set.";
28 
29  auto geometry = inputImage->GetGeometry();
30 
31  if (nullptr == geometry || !geometry->IsValid())
32  mitkThrow() << "Input image has invalid geometry.";
33 
34  if (inputImage->GetDimension() != 4) {
35  mitkThrow() << "CropTimestepsImageFilter only works with 2D+t and 3D+t images.";
36  }
37 
38  if (inputImage->GetTimeSteps() ==1) {
39  mitkThrow() << "Input image has only one timestep.";
40  }
41 
42  if (!geometry->GetImageGeometry())
43  mitkThrow() << "Geometry of input image is not an image geometry.";
44  }
45 
46  void mitk::CropTimestepsImageFilter::GenerateOutputInformation()
47  {
48  Image::ConstPointer input = this->GetInput();
49  Image::Pointer output = this->GetOutput();
50  if (m_LowerBoundaryTimestep > m_UpperBoundaryTimestep) {
51  mitkThrow() << "lower timestep is larger than upper timestep.";
52  }
53  if (m_UpperBoundaryTimestep == std::numeric_limits<unsigned int>::max()) {
54  m_UpperBoundaryTimestep = input->GetTimeSteps();
55  }
56  else if (m_UpperBoundaryTimestep > input->GetTimeSteps()) {
57  m_UpperBoundaryTimestep = input->GetTimeSteps();
58  MITK_WARN << "upper boundary timestep set to " << m_UpperBoundaryTimestep;
59  }
60  m_DesiredRegion = ComputeDesiredRegion();
61  unsigned int dimension = input->GetDimension();
62  auto dimensions = new unsigned int[dimension];
63  itk2vtk(m_DesiredRegion.GetSize(), dimensions);
64  if (dimension > 3)
65  memcpy(dimensions + 3, input->GetDimensions() + 3, (dimension - 3) * sizeof(unsigned int));
66 
67  dimensions[3] = m_UpperBoundaryTimestep - m_LowerBoundaryTimestep;
68 
69  // create basic slicedGeometry that will be initialized below
70  output->Initialize(mitk::PixelType(input->GetPixelType()), dimension, dimensions);
71  delete[] dimensions;
72  auto newTimeGeometry = AdaptTimeGeometry(input->GetTimeGeometry(), m_LowerBoundaryTimestep, m_UpperBoundaryTimestep);
73  output->SetTimeGeometry(newTimeGeometry);
74  output->SetPropertyList(input->GetPropertyList());
75  }
76 
77  mitk::SlicedData::RegionType mitk::CropTimestepsImageFilter::ComputeDesiredRegion() const
78  {
79  auto desiredRegion = this->GetInput()->GetLargestPossibleRegion();
80  auto index = desiredRegion.GetIndex();
81  auto size = desiredRegion.GetSize();
82  unsigned int timeDimension = 3;
83  index[timeDimension] = m_LowerBoundaryTimestep;
84  size[timeDimension] = m_UpperBoundaryTimestep - m_LowerBoundaryTimestep;
85  desiredRegion.SetIndex(index);
86  desiredRegion.SetSize(size);
87  return desiredRegion;
88  }
89 
90  mitk::TimeGeometry::Pointer mitk::CropTimestepsImageFilter::AdaptTimeGeometry(mitk::TimeGeometry::ConstPointer sourceGeometry, unsigned int startTimestep, unsigned int endTimestep) const
91  {
92  auto newTimeGeometry = mitk::ArbitraryTimeGeometry::New();
93  newTimeGeometry->ClearAllGeometries();
94  for (unsigned int timestep = startTimestep; timestep < endTimestep; timestep++) {
95  auto geometryForTimePoint = sourceGeometry->GetGeometryForTimeStep(timestep);
96  newTimeGeometry->AppendNewTimeStep(geometryForTimePoint,
97  sourceGeometry->GetMinimumTimePoint(timestep),
98  sourceGeometry->GetMaximumTimePoint(timestep));
99  }
100  return newTimeGeometry.GetPointer();
101  }
102 
103 void mitk::CropTimestepsImageFilter::GenerateData()
104 {
105  const auto* inputImage = this->GetInput();
106  mitk::Image::Pointer output = this->GetOutput();
107 
108  if ((output->IsInitialized() == false))
109  return;
110 
111  auto timeSelector = mitk::ImageTimeSelector::New();
112 
113  timeSelector->SetInput(inputImage);
114 
115  unsigned int timeStart = m_DesiredRegion.GetIndex(3);
116  unsigned int timeEnd = timeStart + m_DesiredRegion.GetSize(3);
117  for (unsigned int timestep = timeStart; timestep < timeEnd; ++timestep)
118  {
119  timeSelector->SetTimeNr(timestep);
120  timeSelector->UpdateLargestPossibleRegion();
121  mitk::ImageReadAccessor imageAccessorWithOneTimestep(timeSelector->GetOutput());
122  output->SetVolume(imageAccessorWithOneTimestep.GetData(), timestep-timeStart);
123  }
124 }
125 
127 {
128  if (this->GetInput() == image)
129  return;
130 
131  Superclass::SetInput(image);
132 }
133 
135 {
136  if (0 != index)
137  mitkThrow() << "Input index " << index << " is invalid.";
138 
139  this->SetInput(image);
140 }
141 
142 void mitk::CropTimestepsImageFilter::VerifyInputInformation()
143 {
144  Superclass::VerifyInputInformation();
145 
146  VerifyInputImage(this->GetInput());
147 }
bool IsVolumeSet(int t=0, int n=0) const override
Check whether volume at time t in channel n is set.
Definition: mitkImage.cpp:602
itk::SmartPointer< Self > Pointer
Definition: mitkImage.h:84
#define timeStart(part)
#define MITK_WARN
Definition: mitkLogMacros.h:19
unsigned int GetDimension() const
Get dimension of the image.
Definition: mitkImage.cpp:106
itk::ImageRegion< RegionDimension > RegionType
#define mitkThrow()
Image class for storing images.
Definition: mitkImage.h:72
static T max(T x, T y)
Definition: svm.cpp:56
mitk::Image::Pointer image
void itk2vtk(const Tin &in, Tout &out)
InputImageType * GetInput(void)
virtual bool IsInitialized() const
Check whether the data has been initialized, i.e., at least the Geometry and other header data has be...
const RegionType & GetLargestPossibleRegion() const
unsigned int GetTimeSteps() const
Get the number of time steps from the TimeGeometry As the base data has not a data vector given by it...
Definition: mitkBaseData.h:355
OutputType * GetOutput()
Get the output data of this image source object.
ImageReadAccessor class to get locked read access for a particular image part.
mitk::BaseGeometry * GetGeometry(int t=0) const
Return the geometry, which is a TimeGeometry, of the data as non-const pointer.
Definition: mitkBaseData.h:138
itk::SmartPointer< const Self > ConstPointer
Definition: mitkImage.h:84
void SetInput(const InputImageType *image) override
Sets the input image.
static Pointer New()
Class for defining the data type of pixels.
Definition: mitkPixelType.h:51