Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
RectifyImage.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,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include <mitkCommandLineParser.h>
20 #include <mitkIOUtil.h>
21 
22 template <typename TPixelType>
24 {
25  mitk::ImagePixelReadAccessor<TPixelType, 3> pixelReadAccess(inputImage);
26  mitk::ImagePixelWriteAccessor<TPixelType, 3> pixelWriteAccess(outputImage);
27 
28  const auto DEPTH = static_cast<itk::IndexValueType>(outputImage->GetDimension(2));
29  const auto HEIGHT = static_cast<itk::IndexValueType>(outputImage->GetDimension(1));
30  const auto WIDTH = static_cast<itk::IndexValueType>(outputImage->GetDimension(0));
31 
32  auto geometry = outputImage->GetGeometry();
33  itk::Index<3> index;
34  mitk::Point3D worldCoords;
35 
36  for (index[2] = 0; index[2] < DEPTH; ++index[2])
37  {
38  for (index[1] = 0; index[1] < HEIGHT; ++index[1])
39  {
40  for (index[0] = 0; index[0] < WIDTH; ++index[0])
41  {
42  geometry->IndexToWorld(index, worldCoords);
43  pixelWriteAccess.SetPixelByIndex(index, pixelReadAccess.GetPixelByWorldCoordinates(worldCoords));
44  }
45  }
46  }
47 }
48 
49 int main(int argc, char* argv[])
50 {
51  mitkCommandLineParser parser;
52 
53  parser.setTitle("Rectify Image");
54  parser.setCategory("Basic Image Processing");
55  parser.setDescription("Resample image based on standard world to index transform");
56  parser.setContributor("German Cancer Research Center (DKFZ)");
57 
58  parser.setArgumentPrefix("--", "-");
59  parser.addArgument("input", "i", mitkCommandLineParser::Image, "Input Image", "Path to input image", us::Any(), false);
60  parser.addArgument("output", "o", mitkCommandLineParser::Image, "Output Image", "Path to output image", us::Any(), false);
61 
62  auto parsedArgs = parser.parseArguments(argc, argv);
63 
64  if (2 != parsedArgs.size() || 0 == parsedArgs.count("input") || 0 == parsedArgs.count("output"))
65  return EXIT_FAILURE;
66 
67  auto inputImagePath = us::any_value_to_string(parsedArgs["input"]);
68  mitk::Image::Pointer inputImage;
69 
70  try
71  {
72  inputImage = dynamic_cast<mitk::Image*>(mitk::IOUtil::Load(inputImagePath)[0].GetPointer());
73  }
74  catch (const mitk::Exception&)
75  {
76  return EXIT_FAILURE;
77  }
78 
79  if (3 != inputImage->GetDimension())
80  {
81  MITK_ERROR << "Only 3-d images are supported.";
82  return EXIT_FAILURE;
83  }
84 
85  auto inputGeometry = inputImage->GetGeometry();
86 
87  mitk::Point3D minInputIndex;
88  mitk::FillVector3D(minInputIndex, 0.0, 0.0, 0.0);
89 
90  mitk::Point3D minInputIndexInWorld;
91  inputGeometry->IndexToWorld(minInputIndex, minInputIndexInWorld);
92 
93  mitk::Point3D maxInputIndex;
94  for (int i = 0; i < 3; ++i)
95  maxInputIndex[i] = inputGeometry->GetExtent(i) - 1;
96 
97  mitk::Point3D maxInputIndexInWorld;
98  inputGeometry->IndexToWorld(maxInputIndex, maxInputIndexInWorld);
99 
100  mitk::Point3D minOutputIndexInWorld;
101  for (int i = 0; i < 3; ++i)
102  minOutputIndexInWorld[i] = std::min(minInputIndexInWorld[i], maxInputIndexInWorld[i]);
103 
104  mitk::Point3D maxOutputIndexInWorld;
105  for (int i = 0; i < 3; ++i)
106  maxOutputIndexInWorld[i] = std::max(minInputIndexInWorld[i], maxInputIndexInWorld[i]);
107 
108  mitk::Vector3D spacing = inputGeometry->GetSpacing();
109  auto transform = inputGeometry->GetIndexToWorldTransform()->Clone();
110  auto matrix = transform->GetMatrix();
111 
112  for (int i = 0; i < 3; ++i)
113  {
114  for (int j = 0; j < 3; ++j)
115  {
116  matrix[i][j] = std::abs(matrix[i][j]) / spacing[j];
117  }
118  }
119 
120  transform->SetMatrix(matrix);
121  spacing = transform->TransformVector(spacing);
122 
123  mitk::Vector3D outputExtent = (maxOutputIndexInWorld - minOutputIndexInWorld + spacing);
124  for (int i = 0; i < 3; ++i)
125  outputExtent[i] /= spacing[i];
126 
127  mitk::Point3D origin = minOutputIndexInWorld;
128 
129  mitk::Vector3D right;
130  mitk::FillVector3D(right, outputExtent[0], 0.0, 0.0);
131 
132  mitk::Vector3D down;
133  mitk::FillVector3D(down, 0.0, outputExtent[1], 0.0);
134 
135  auto planeGeometry = mitk::PlaneGeometry::New();
136  planeGeometry->InitializeStandardPlane(right, down, &spacing);
137  planeGeometry->SetOrigin(origin);
138  planeGeometry->SetImageGeometry(true);
139 
140  auto slicedGeometry = mitk::SlicedGeometry3D::New();
141  slicedGeometry->InitializeEvenlySpaced(planeGeometry, static_cast<unsigned int>(outputExtent[2]));
142 
143  auto outputGeometry = mitk::ProportionalTimeGeometry::New();
144  outputGeometry->SetTimeStepGeometry(slicedGeometry, 0);
145 
146  auto pixelType = inputImage->GetPixelType();
147 
148  auto outputImage = mitk::Image::New();
149  outputImage->Initialize(pixelType, *outputGeometry);
150 
151  try
152  {
153  switch (pixelType.GetComponentType())
154  {
155  case itk::ImageIOBase::CHAR:
156  RectifyImage<char>(inputImage, outputImage);
157  break;
158 
159  case itk::ImageIOBase::UCHAR:
160  RectifyImage<unsigned char>(inputImage, outputImage);
161  break;
162 
163  case itk::ImageIOBase::SHORT:
164  RectifyImage<short>(inputImage, outputImage);
165  break;
166 
167  case itk::ImageIOBase::USHORT:
168  RectifyImage<unsigned short>(inputImage, outputImage);
169  break;
170 
171  default:
172  MITK_ERROR << "Pixel type is not supported.";
173  return EXIT_FAILURE;
174  }
175  }
176  catch (const mitk::Exception &e)
177  {
178  MITK_ERROR << e.GetDescription();
179  return EXIT_FAILURE;
180  }
181 
182  auto outputImagePath = us::any_value_to_string(parsedArgs["output"]);
183 
184  try
185  {
186  mitk::IOUtil::Save(outputImage, outputImagePath);
187  }
188  catch (const mitk::Exception &)
189  {
190  return EXIT_FAILURE;
191  }
192 
193  return EXIT_SUCCESS;
194 }
US_Core_EXPORT std::string any_value_to_string(const Any &any)
Definition: usAny.cpp:26
Gives locked and index-based write access for a particular image part. The class provides several set...
Gives locked and index-based read access for a particular image part. The class provides several set-...
static Pointer New()
#define MITK_ERROR
Definition: mitkLogMacros.h:20
void setContributor(std::string contributor)
void addArgument(const std::string &longarg, const std::string &shortarg, Type type, const std::string &argLabel, const std::string &argHelp=std::string(), const us::Any &defaultValue=us::Any(), bool optional=true, bool ignoreRest=false, bool deprecated=false, mitkCommandLineParser::Channel channel=mitkCommandLineParser::Channel::None)
std::map< std::string, us::Any > parseArguments(const StringContainerType &arguments, bool *ok=nullptr)
void FillVector3D(Tout &out, mitk::ScalarType x, mitk::ScalarType y, mitk::ScalarType z)
Definition: mitkArray.h:106
int main(int argc, char *argv[])
An object of this class represents an exception of MITK. Please don&#39;t instantiate exceptions manually...
Definition: mitkException.h:45
Image class for storing images.
Definition: mitkImage.h:72
Definition: usAny.h:163
void RectifyImage(mitk::Image::Pointer inputImage, mitk::Image::Pointer outputImage)
static T max(T x, T y)
Definition: svm.cpp:56
void setCategory(std::string category)
static Pointer New()
void SetPixelByIndex(const itk::Index< VDimension > &idx, const TPixel &value)
Sets a pixel value at given index.
void setArgumentPrefix(const std::string &longPrefix, const std::string &shortPrefix)
static T min(T x, T y)
Definition: svm.cpp:53
static void Save(const mitk::BaseData *data, const std::string &path, bool setPathProperty=false)
Save a mitk::BaseData instance.
Definition: mitkIOUtil.cpp:774
static Pointer New()
void setTitle(std::string title)
void setDescription(std::string description)
static DataStorage::SetOfObjects::Pointer Load(const std::string &path, DataStorage &storage, const ReaderOptionsFunctorBase *optionsCallback=nullptr)
Load a file into the given DataStorage.
Definition: mitkIOUtil.cpp:489
const TPixel & GetPixelByWorldCoordinates(mitk::Point3D position)