Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
mitkAlgorithmHelper.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 "mitkAlgorithmHelper.h"
18 
19 //itk
20 #include <itkImageDuplicator.h>
21 
22 // Mitk
23 #include <mitkImageAccessByItk.h>
25 
26 // MatchPoint
27 #include <mapImageRegistrationAlgorithmInterface.h>
28 #include <mapRegistrationAlgorithmInterface.h>
29 #include <mapPointSetRegistrationAlgorithmInterface.h>
30 #include <mapDummyImageRegistrationAlgorithm.h>
31 #include <mapAlgorithmIdentificationInterface.h>
32 
33 namespace mitk
34 {
35 
36  MITKAlgorithmHelper::MITKAlgorithmHelper(map::algorithm::RegistrationAlgorithmBase* algorithm) :
37  m_AlgorithmBase(algorithm)
38  {
39  m_AllowImageCasting = true;
40  }
41 
45  {
47 
48  unsigned int movingDim = m_AlgorithmBase->getMovingDimensions();
49  unsigned int targetDim = m_AlgorithmBase->getTargetDimensions();
50 
51  if (movingDim != targetDim)
52  {
53  mapDefaultExceptionStaticMacro( <<
54  "Error, algorithm instance has unequal dimensionality and is therefore not supported in the current version of MITKAlgorithmHelper.");
55  }
56 
57  if (movingDim > 3)
58  {
59  mapDefaultExceptionStaticMacro( <<
60  "Error, algorithm instance has a dimensionality larger than 3 and is therefore not supported in the current version of MITKAlgorithmHelper.");
61  }
62 
63  typedef ::map::algorithm::facet::RegistrationAlgorithmInterface<2, 2> RegistrationAlg2D2DInterface;
64  typedef ::map::algorithm::facet::RegistrationAlgorithmInterface<3, 3> RegistrationAlg3D3DInterface;
65 
66  RegistrationAlg2D2DInterface* pRegAlgorithm2D2D = dynamic_cast<RegistrationAlg2D2DInterface*>
67  (m_AlgorithmBase.GetPointer());
68  RegistrationAlg3D3DInterface* pRegAlgorithm3D3D = dynamic_cast<RegistrationAlg3D3DInterface*>
69  (m_AlgorithmBase.GetPointer());
70 
71  if (pRegAlgorithm2D2D)
72  {
73  spResult = pRegAlgorithm2D2D->getRegistration();
74  }
75 
76  if (pRegAlgorithm3D3D)
77  {
78  spResult = pRegAlgorithm3D3D->getRegistration();
79  }
80 
81  return spResult;
82  }
83 
87  {
90  spResult->SetRegistration(spInternalResult);
91  return spResult;
92  };
93 
94 
95  static const mitk::Image* GetDataAsImage(const mitk::BaseData* data)
96  {
97  return dynamic_cast<const mitk::Image*>(data);
98  };
99 
101  {
102  return dynamic_cast<const mitk::PointSet*>(data);
103  };
104 
105  bool
107  CheckData(const mitk::BaseData* moving, const mitk::BaseData* target, CheckError::Type& error) const
108  {
109  if (! m_AlgorithmBase)
110  {
111  mapDefaultExceptionStaticMacro( << "Error, cannot check data. Helper has no algorithm defined.");
112  }
113 
114  if (! moving)
115  {
116  mapDefaultExceptionStaticMacro( << "Error, cannot check data. Moving data pointer is NULL.");
117  }
118 
119  if (! target)
120  {
121  mapDefaultExceptionStaticMacro( << "Error, cannot check data. Target data pointer is NULL.");
122  }
123 
124  bool result = false;
126 
127  unsigned int movingDim = m_AlgorithmBase->getMovingDimensions();
128  unsigned int targetDim = m_AlgorithmBase->getTargetDimensions();
129 
130  if (movingDim != targetDim)
131  {
132  m_Error = CheckError::wrongDimension;
133  }
134  else
135  {
136  //First check if data are point sets or images
137  if (GetDataAsPointSet(target) && GetDataAsPointSet(moving))
138  {
139  typedef ::map::core::continuous::Elements<3>::InternalPointSetType InternalDefaultPointSetType;
140  typedef ::map::algorithm::facet::PointSetRegistrationAlgorithmInterface<InternalDefaultPointSetType, InternalDefaultPointSetType>
141  PointSetRegInterface;
142 
143  PointSetRegInterface* pPointSetInterface = dynamic_cast<PointSetRegInterface*>
144  (m_AlgorithmBase.GetPointer());
145 
146  if (!pPointSetInterface)
147  {
148  result = false;
150  }
151  }
152  else if (GetDataAsImage(moving) && GetDataAsImage(target))
153  {
154  if (movingDim == 2)
155  {
156  AccessTwoImagesFixedDimensionByItk(GetDataAsImage(moving), GetDataAsImage(target), DoCheckImages,
157  2);
158  }
159  else if (movingDim == 3)
160  {
161  AccessTwoImagesFixedDimensionByItk(GetDataAsImage(moving), GetDataAsImage(target), DoCheckImages,
162  3);
163  }
164  else
165  {
166  m_Error = CheckError::wrongDimension;
167  }
168 
169  if (m_Error == CheckError::none || (m_AllowImageCasting && m_Error == CheckError::onlyByCasting))
170  {
171  result = true;
172  }
173  }
174 
175  }
176 
177  error = m_Error;
178  return result;
179 
180  };
181 
183  {
184  this->m_AllowImageCasting = allowCasting;
185  };
186 
188  {
189  return this->m_AllowImageCasting;
190  };
191 
192  void MITKAlgorithmHelper::SetData(const mitk::BaseData* moving, const mitk::BaseData* target)
193  {
194  if (! m_AlgorithmBase)
195  {
196  mapDefaultExceptionStaticMacro( << "Error, cannot check data. Helper has no algorithm defined.");
197  }
198 
199  if (! moving)
200  {
201  mapDefaultExceptionStaticMacro( << "Error, cannot check data. Moving data pointer is NULL.");
202  }
203 
204  if (! target)
205  {
206  mapDefaultExceptionStaticMacro( << "Error, cannot check data. Target data pointer is NULL.");
207  }
208 
209  unsigned int movingDim = m_AlgorithmBase->getMovingDimensions();
210  unsigned int targetDim = m_AlgorithmBase->getTargetDimensions();
211 
212  if (movingDim != targetDim)
213  {
214  mapDefaultExceptionStaticMacro( <<
215  "Error, cannot set data. Current version of MITKAlgorithmHelper only supports images/point sets with same dimensionality.");
216  }
217 
218  if (GetDataAsPointSet(target) && GetDataAsPointSet(moving))
219  {
220  typedef ::map::core::continuous::Elements<3>::InternalPointSetType InternalDefaultPointSetType;
221  typedef ::map::algorithm::facet::PointSetRegistrationAlgorithmInterface<InternalDefaultPointSetType, InternalDefaultPointSetType>
222  PointSetRegInterface;
223 
224  PointSetRegInterface* pPointSetInterface = dynamic_cast<PointSetRegInterface*>
225  (m_AlgorithmBase.GetPointer());
226 
227  pPointSetInterface->setMovingPointSet(mitk::PointSetMappingHelper::ConvertPointSetMITKtoMAP(
228  GetDataAsPointSet(moving)->GetPointSet()));
229  pPointSetInterface->setTargetPointSet(mitk::PointSetMappingHelper::ConvertPointSetMITKtoMAP(
230  GetDataAsPointSet(target)->GetPointSet()));
231  }
232  else if (GetDataAsImage(moving) && GetDataAsImage(target))
233  {
234  if (movingDim == 2)
235  {
236  AccessTwoImagesFixedDimensionByItk(GetDataAsImage(moving), GetDataAsImage(target), DoSetImages, 2);
237  }
238  else if (movingDim == 3)
239  {
240  AccessTwoImagesFixedDimensionByItk(GetDataAsImage(moving), GetDataAsImage(target), DoSetImages, 3);
241  }
242  }
243  };
244 
245  template<typename TInImageType, typename TOutImageType>
246  typename TOutImageType::Pointer MITKAlgorithmHelper::CastImage(const TInImageType* input) const
247  {
248  typedef itk::CastImageFilter< TInImageType, TOutImageType > CastFilterType;
249  typename CastFilterType::Pointer spImageCaster = CastFilterType::New();
250 
251  spImageCaster->SetInput(input);
252 
253  typename TOutImageType::Pointer spImage = spImageCaster->GetOutput();
254  spImageCaster->Update();
255 
256  return spImage;
257  }
258 
259  template<typename TPixelType1, unsigned int VImageDimension1,
260  typename TPixelType2, unsigned int VImageDimension2>
261  void MITKAlgorithmHelper::DoSetImages(const itk::Image<TPixelType1, VImageDimension1>* moving,
262  const itk::Image<TPixelType2, VImageDimension2>* target)
263  {
264  typedef itk::Image<TPixelType1, VImageDimension1> MovingImageType;
265  typedef itk::Image<TPixelType2, VImageDimension2> TargetImageType;
266  typedef itk::Image<map::core::discrete::InternalPixelType, VImageDimension1>
267  InternalDefaultMovingImageType;
268  typedef itk::Image<map::core::discrete::InternalPixelType, VImageDimension2>
269  InternalDefaultTargetImageType;
270 
271  typedef ::map::algorithm::facet::ImageRegistrationAlgorithmInterface<MovingImageType, TargetImageType>
272  ImageRegInterface;
273  typedef ::map::algorithm::facet::ImageRegistrationAlgorithmInterface<InternalDefaultMovingImageType, InternalDefaultTargetImageType>
274  DefaultImageRegInterface;
275 
276 
277  ImageRegInterface* pImageInterface = dynamic_cast<ImageRegInterface*>(m_AlgorithmBase.GetPointer());
278  DefaultImageRegInterface* pDefaultImageInterface = dynamic_cast<DefaultImageRegInterface*>
279  (m_AlgorithmBase.GetPointer());
280 
281  if (pImageInterface)
282  {
283  //just set directly and you are done
284 
291  typedef itk::ImageDuplicator< MovingImageType > MovingDuplicatorType;
292  typedef itk::ImageDuplicator< TargetImageType > TargetDuplicatorType;
294  mDuplicator->SetInputImage(moving);
295  mDuplicator->Update();
296 
298  tDuplicator->SetInputImage(target);
299  tDuplicator->Update();
300 
301  typename MovingImageType::Pointer clonedMoving = mDuplicator->GetOutput();
302  typename TargetImageType::Pointer clonedTarget = tDuplicator->GetOutput();
303 
304  pImageInterface->setTargetImage(clonedTarget);
305  pImageInterface->setMovingImage(clonedMoving);
306  }
307  else if (pDefaultImageInterface)
308  {
309  //you may convert it to the default image type and use it then
310  if (! m_AllowImageCasting)
311  {
312  mapDefaultExceptionStaticMacro( <<
313  "Error, cannot set images. MITKAlgorithmHelper has to convert them into MatchPoint default images, but is not allowed. Please reconfigure helper.");
314  }
315 
316  typename InternalDefaultTargetImageType::Pointer spCastedTarget =
317  CastImage<TargetImageType, InternalDefaultTargetImageType>(target);
318  typename InternalDefaultMovingImageType::Pointer spCastedMoving =
319  CastImage<MovingImageType, InternalDefaultMovingImageType>(moving);
320  pDefaultImageInterface->setTargetImage(spCastedTarget);
321  pDefaultImageInterface->setMovingImage(spCastedMoving);
322  }
323  else
324  {
325  mapDefaultExceptionStaticMacro( << "Error, algorithm is not able to use the based images.");
326  }
327  }
328 
329  template<typename TPixelType1, unsigned int VImageDimension1,
330  typename TPixelType2, unsigned int VImageDimension2>
331  void MITKAlgorithmHelper::DoCheckImages(const itk::Image<TPixelType1, VImageDimension1>* moving,
332  const itk::Image<TPixelType2, VImageDimension2>* target) const
333  {
334  typedef itk::Image<TPixelType1, VImageDimension1> MovingImageType;
335  typedef itk::Image<TPixelType2, VImageDimension2> TargetImageType;
336  typedef itk::Image<map::core::discrete::InternalPixelType, VImageDimension1>
337  InternalDefaultMovingImageType;
338  typedef itk::Image<map::core::discrete::InternalPixelType, VImageDimension2>
339  InternalDefaultTargetImageType;
340 
341  typedef ::map::algorithm::facet::ImageRegistrationAlgorithmInterface<MovingImageType, TargetImageType>
342  ImageRegInterface;
343  typedef ::map::algorithm::facet::ImageRegistrationAlgorithmInterface<InternalDefaultMovingImageType, InternalDefaultTargetImageType>
344  DefaultImageRegInterface;
345 
346  ImageRegInterface* pImageInterface = dynamic_cast<ImageRegInterface*>(m_AlgorithmBase.GetPointer());
347  DefaultImageRegInterface* pDefaultImageInterface = dynamic_cast<DefaultImageRegInterface*>
348  (m_AlgorithmBase.GetPointer());
349 
350  if (pImageInterface)
351  {
352  //just set directly and you are done
353  m_Error = CheckError::none;
354  }
355  else if (pDefaultImageInterface)
356  {
357  //you may convert it to the default image type and use it then
358  m_Error = CheckError::onlyByCasting;
359  }
360  else
361  {
363  }
364  }
365 
366 
367  mapGenerateAlgorithmUIDPolicyMacro(DummyRegIDPolicy, "de.dkfz.dipp", "Identity", "1.0.0", "");
368 
370  {
371  typedef map::algorithm::DummyImageRegistrationAlgorithm<map::core::discrete::Elements<3>::InternalImageType, map::core::discrete::Elements<3>::InternalImageType, DummyRegIDPolicy>
372  DummyRegType;
374  mitk::MITKAlgorithmHelper helper(regAlg);
375 
378  dummyImg->Allocate();
379  regAlg->setTargetImage(dummyImg);
380  regAlg->setMovingImage(dummyImg);
381 
383  dummyReg->SetRegistration(regAlg->getRegistration());
384 
385  return dummyReg;
386  }
387 
388 }
void SetAllowImageCasting(bool allowCasting)
map::core::RegistrationBase::Pointer GetRegistration() const
MITKAlgorithmHelper.
itk::SmartPointer< Self > Pointer
Base of all data objects.
Definition: mitkBaseData.h:39
DataCollection - Class to facilitate loading/accessing structured data.
bool CheckData(const mitk::BaseData *moving, const mitk::BaseData *target, CheckError::Type &error) const
MITKMATCHPOINTREGISTRATION_EXPORT::map::core::continuous::Elements< 3 >::InternalPointSetType::Pointer ConvertPointSetMITKtoMAP(const mitk::PointSet::DataType *mitkSet)
Data structure which stores a set of points. Superclass of mitk::Mesh.
Definition: mitkPointSet.h:79
void SetData(const mitk::BaseData *moving, const mitk::BaseData *target)
mitk::MAPRegistrationWrapper::Pointer GetMITKRegistrationWrapper() const
Image class for storing images.
Definition: mitkImage.h:76
static const mitk::Image * GetDataAsImage(const mitk::BaseData *data)
static const mitk::PointSet * GetDataAsPointSet(const mitk::BaseData *data)
#define AccessTwoImagesFixedDimensionByItk(mitkImage1, mitkImage2, itkImageTypeFunction, dimension)
Access two mitk-images with known dimension by itk-images.
mitk::MAPRegistrationWrapper::Pointer GenerateIdentityRegistration3D()
MITKAlgorithmHelper(map::algorithm::RegistrationAlgorithmBase *algorithm=NULL)
mapGenerateAlgorithmUIDPolicyMacro(DummyRegIDPolicy,"de.dkfz.dipp","Identity","1.0.0","")
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.