Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkDiffusionPropertyHelper.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 
18 #include <mitkITKImageImport.h>
19 #include <mitkImageCast.h>
20 #include <itkImageRegionIterator.h>
21 #include <mitkProperties.h>
22 
23 const std::string mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME = "DWMRI.GradientDirections";
24 const std::string mitk::DiffusionPropertyHelper::ORIGINALGRADIENTCONTAINERPROPERTYNAME = "DWMRI.OriginalGradientDirections";
25 const std::string mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME = "DWMRI.MeasurementFrame";
26 const std::string mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME = "DWMRI.ReferenceBValue";
27 const std::string mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME = "DWMRI.BValueMap";
28 const std::string mitk::DiffusionPropertyHelper::MODALITY = "DWMRI.Modality";
29 
31 {
32 }
33 
35  : m_Image( inputImage )
36 {
37  // Update props
38 }
39 
41 {
42 }
43 
44 
46 {
47  ImageType::Pointer vectorImage = ImageType::New();
48  mitk::CastToItkImage(image, vectorImage);
49  return vectorImage;
50 }
51 
54 {
55  // save old and construct new direction container
57 
58  // fill new direction container
59  for(GradientDirectionsContainerType::ConstIterator gdcitOld = directions->Begin();
60  gdcitOld != directions->End(); ++gdcitOld)
61  {
62  // already exists?
63  bool found = false;
64  for(GradientDirectionsContainerType::ConstIterator gdcitNew = newDirections->Begin();
65  gdcitNew != newDirections->End(); ++gdcitNew)
66  {
67  if(AreAlike(gdcitNew.Value(), gdcitOld.Value(), precision))
68  {
69  found = true;
70  break;
71  }
72  }
73 
74  // if not found, add it to new container
75  if(!found)
76  {
77  newDirections->push_back(gdcitOld.Value());
78  }
79  }
80 
81  return newDirections;
82 }
83 
85 {
86 
87  mitk::GradientDirectionsProperty* DirectionsProperty = static_cast<mitk::GradientDirectionsProperty*>( m_Image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() );
89 
91  CalcAveragedDirectionSet(precision, oldDirs);
92 
93  // if sizes equal, we do not need to do anything in this function
94  if(oldDirs->size() == newDirs->size())
95  return;
96 
97  // new image
99  mitk::CastToItkImage( m_Image, oldImage);
100  ImageType::Pointer newITKImage = ImageType::New();
101  newITKImage->SetSpacing( oldImage->GetSpacing() ); // Set the image spacing
102  newITKImage->SetOrigin( oldImage->GetOrigin() ); // Set the image origin
103  newITKImage->SetDirection( oldImage->GetDirection() ); // Set the image direction
104  newITKImage->SetLargestPossibleRegion( oldImage->GetLargestPossibleRegion() );
105  newITKImage->SetVectorLength( newDirs->size() );
106  newITKImage->SetBufferedRegion( oldImage->GetLargestPossibleRegion() );
107  newITKImage->Allocate();
108 
109  // average image data that corresponds to identical directions
110  itk::ImageRegionIterator< ImageType > newIt(newITKImage, newITKImage->GetLargestPossibleRegion());
111  newIt.GoToBegin();
112  itk::ImageRegionIterator< ImageType > oldIt(oldImage, oldImage->GetLargestPossibleRegion());
113  oldIt.GoToBegin();
114 
115  // initial new value of voxel
116  ImageType::PixelType newVec;
117  newVec.SetSize(newDirs->size());
118  newVec.AllocateElements(newDirs->size());
119 
120  // find which gradients should be averaged
121  GradientDirectionsContainerType::Pointer oldDirections = oldDirs;
122  std::vector<std::vector<int> > dirIndices;
123  for(GradientDirectionsContainerType::ConstIterator gdcitNew = newDirs->Begin();
124  gdcitNew != newDirs->End(); ++gdcitNew)
125  {
126  dirIndices.push_back(std::vector<int>(0));
127  for(GradientDirectionsContainerType::ConstIterator gdcitOld = oldDirs->Begin();
128  gdcitOld != oldDirections->End(); ++gdcitOld)
129  {
130  if(AreAlike(gdcitNew.Value(), gdcitOld.Value(), precision))
131  {
132  //MITK_INFO << gdcitNew.Value() << " " << gdcitOld.Value();
133  dirIndices[gdcitNew.Index()].push_back(gdcitOld.Index());
134  }
135  }
136  }
137 
138  //int ind1 = -1;
139  while(!newIt.IsAtEnd())
140  {
141 
142  // progress
143  //typename ImageType::IndexType ind = newIt.GetIndex();
144  //ind1 = ind.m_Index[2];
145 
146  // init new vector with zeros
147  newVec.Fill(0.0);
148 
149  // the old voxel value with duplicates
150  ImageType::PixelType oldVec = oldIt.Get();
151 
152  for(unsigned int i=0; i<dirIndices.size(); i++)
153  {
154  // do the averaging
155  const unsigned int numavg = dirIndices[i].size();
156  unsigned int sum = 0;
157  for(unsigned int j=0; j<numavg; j++)
158  {
159  //MITK_INFO << newVec[i] << " << " << oldVec[dirIndices[i].at(j)];
160  sum += oldVec[dirIndices[i].at(j)];
161  }
162  if(numavg == 0)
163  {
164  MITK_ERROR << "VectorImage: Error on averaging. Possibly due to corrupted data";
165  return;
166  }
167  newVec[i] = sum / numavg;
168  }
169 
170  newIt.Set(newVec);
171 
172  ++newIt;
173  ++oldIt;
174  }
175 
176  mitk::GrabItkImageMemory( newITKImage, m_Image );
177 
180  ApplyMeasurementFrame();
181  UpdateBValueMap();
182  std::cout << std::endl;
183 }
184 
186 {
187 
188  if( m_Image->GetProperty(mitk::DiffusionPropertyHelper::ORIGINALGRADIENTCONTAINERPROPERTYNAME.c_str()).IsNull() )
189  {
190  return;
191  }
192 
193  GradientDirectionsContainerType::Pointer originalDirections = static_cast<mitk::GradientDirectionsProperty*>( m_Image->GetProperty(mitk::DiffusionPropertyHelper::ORIGINALGRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer())->GetGradientDirectionsContainer();
194 
195  MeasurementFrameType measurementFrame = GetMeasurementFrame(m_Image);
196 
198 
199  if( originalDirections.IsNull() || ( originalDirections->size() == 0 ) )
200  {
201  // original direction container was not set
202  return;
203  }
204 
205  int c = 0;
206  for(GradientDirectionsContainerType::ConstIterator gdcit = originalDirections->Begin();
207  gdcit != originalDirections->End(); ++gdcit)
208  {
209  vnl_vector<double> vec = gdcit.Value();
210  vec = vec.pre_multiply(measurementFrame);
211  directions->InsertElement(c, vec);
212  c++;
213  }
214 
216 }
217 
219 {
220  BValueMapType b_ValueMap;
221 
222  if(m_Image->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).IsNull())
223  {
224  }
225  else
226  {
227  b_ValueMap = static_cast<mitk::BValueMapProperty*>(m_Image->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap();
228  }
229 
230  if(!b_ValueMap.empty())
231  {
232  b_ValueMap.clear();
233  }
234 
235  if( m_Image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).IsNotNull() )
236  {
237  GradientDirectionsContainerType::Pointer directions = static_cast<mitk::GradientDirectionsProperty*>( m_Image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer();
238 
239  GradientDirectionsContainerType::ConstIterator gdcit;
240  for( gdcit = directions->Begin(); gdcit != directions->End(); ++gdcit)
241  {
242  b_ValueMap[GetB_Value(gdcit.Index())].push_back(gdcit.Index());
243  }
244  }
245 
246  m_Image->SetProperty( mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str(), mitk::BValueMapProperty::New( b_ValueMap ) );
247 }
248 
251  double precision)
252 {
253  GradientDirectionType diff = g1 - g2;
254  GradientDirectionType diff2 = g1 + g2;
255  return diff.two_norm() < precision || diff2.two_norm() < precision;
256 }
257 
259 {
260  GradientDirectionsContainerType::Pointer directions = static_cast<mitk::GradientDirectionsProperty*>( m_Image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer();
261 
262  float b_value = static_cast<mitk::FloatProperty*>(m_Image->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue();
263 
264  if(i > directions->Size()-1)
265  return -1;
266 
267  if(directions->ElementAt(i).one_norm() <= 0.0)
268  {
269  return 0;
270  }
271  else
272  {
273  double twonorm = directions->ElementAt(i).two_norm();
274  double bval = b_value*twonorm*twonorm;
275 
276  if (bval<0)
277  bval = ceil(bval - 0.5);
278  else
279  bval = floor(bval + 0.5);
280 
281  return bval;
282  }
283 }
284 
286 {
287  this->ApplyMeasurementFrame();
288  this->UpdateBValueMap();
289 
290  // initialize missing properties
291  mitk::MeasurementFrameProperty::Pointer mf = dynamic_cast<mitk::MeasurementFrameProperty *>( m_Image->GetProperty(MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer());
292  if( mf.IsNull() )
293  {
294  //no measurement frame present, identity is assumed
295  MeasurementFrameType identity;
296  identity.set_identity();
298  }
299 }
300 
302 {
303  if ( node==nullptr )
304  return false;
305  if ( node->GetData()==nullptr )
306  return false;
307  return IsDiffusionWeightedImage(dynamic_cast<mitk::Image *>(node->GetData()));
308 }
309 
310 
312 {
313  bool isDiffusionWeightedImage( true );
314 
315  if( image == nullptr )
316  {
317  isDiffusionWeightedImage = false;
318  }
319 
320  if( isDiffusionWeightedImage )
321  {
322  mitk::FloatProperty::Pointer referenceBValue = dynamic_cast<mitk::FloatProperty *>(image->GetProperty(REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer());
323 
324  if( referenceBValue.IsNull() )
325  {
326  isDiffusionWeightedImage = false;
327  }
328 
329  }
330 
331  unsigned int gradientDirections( 0 );
332  if( isDiffusionWeightedImage )
333  {
334  mitk::GradientDirectionsProperty::Pointer gradientDirectionsProperty = dynamic_cast<mitk::GradientDirectionsProperty *>(image->GetProperty(GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer());
335 
336  if( gradientDirectionsProperty.IsNull() )
337  {
338  isDiffusionWeightedImage = false;
339  }
340  else
341  {
342  gradientDirections = gradientDirectionsProperty->GetGradientDirectionsContainer()->size();
343  }
344  }
345 
346  if( isDiffusionWeightedImage )
347  {
348  unsigned int components = image->GetPixelType().GetNumberOfComponents();
349 
350  if( components != gradientDirections )
351  {
352  isDiffusionWeightedImage = false;
353  }
354  }
355 
356  return isDiffusionWeightedImage;
357 }
358 
360 {
361  return dynamic_cast<mitk::BValueMapProperty *>(image->GetProperty(BVALUEMAPPROPERTYNAME.c_str()).GetPointer())->GetBValueMap();
362 }
363 
365 {
366  return dynamic_cast<mitk::FloatProperty *>(image->GetProperty(REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer())->GetValue();
367 }
368 
370 {
371  mitk::MeasurementFrameProperty::Pointer mf = dynamic_cast<mitk::MeasurementFrameProperty *>( image->GetProperty(MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer());
372  if( mf.IsNull() )
373  {
374  //no measurement frame present, identity is assumed
375  MeasurementFrameType identity;
376  identity.set_identity();
377  mf = mitk::MeasurementFrameProperty::New( identity );
378  }
379 
380  return mf->GetMeasurementFrame();
381 }
382 
384 {
385  return dynamic_cast<mitk::GradientDirectionsProperty *>(image->GetProperty(ORIGINALGRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer())->GetGradientDirectionsContainer();
386 }
387 
389 {
390  return dynamic_cast<mitk::GradientDirectionsProperty *>(image->GetProperty(GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer())->GetGradientDirectionsContainer();
391 }
392 
394 {
395  return IsDiffusionWeightedImage(m_Image);
396 }
397 
399 {
400  return GetBValueMap(m_Image);
401 }
402 
404 {
405  return GetReferenceBValue(m_Image);
406 }
407 
409 {
410  return GetMeasurementFrame(m_Image);
411 }
412 
414 {
415  return GetOriginalGradientContainer(m_Image);
416 }
417 
419 {
420  return GetGradientContainer(m_Image);
421 }
const MeasurementFrameType & GetMeasurementFrame() const
void AverageRedundantGradients(double precision)
static const std::string REFERENCEBVALUEPROPERTYNAME
itk::SmartPointer< Self > Pointer
#define MITK_ERROR
Definition: mitkLogMacros.h:24
mitk::BValueMapProperty::BValueMap BValueMapType
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
Image::Pointer GrabItkImageMemory(itk::SmartPointer< ItkOutputImageType > &itkimage, mitk::Image *mitkImage=nullptr, const BaseGeometry *geometry=nullptr, bool update=true)
Grabs the memory of an itk::Image (with a specific type) and puts it into an mitk::Image.The memory is managed by the mitk::Image after calling this function. The itk::Image remains valid until the mitk::Image decides to free the memory.
static const std::string MEASUREMENTFRAMEPROPERTYNAME
const BValueMapType & GetBValueMap() const
void InitializeImage()
Make certain the owned image is up to date with all necessary properties.
static ImageType::Pointer GetItkVectorImage(Image *image)
Image class for storing images.
Definition: mitkImage.h:76
void ApplyMeasurementFrame()
Apply the previouse set MeasurementFrame to all gradients in the GradientsDirectionContainer (m_Direc...
const mitk::PixelType GetPixelType(int n=0) const
Returns the PixelType of channel n.
Definition: mitkImage.cpp:105
const GradientDirectionsContainerType::Pointer GetGradientDirectionsContainer() const
GradientDirectionsProperty::GradientDirectionType GradientDirectionType
GradientDirectionsContainerType::Pointer CalcAveragedDirectionSet(double precision, GradientDirectionsContainerType::Pointer directions)
void UpdateBValueMap()
Update the BValueMap (m_B_ValueMap) using the current gradient directions (m_Directions) ...
bool AreAlike(GradientDirectionType g1, GradientDirectionType g2, double precision)
Determines whether gradients can be considered to be equal.
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
float GetB_Value(unsigned int i)
Get the b value belonging to an index.
vcl_size_t GetNumberOfComponents() const
Get the number of components of which each element consists.
GradientDirectionsContainerType::Pointer GetGradientContainer() const
unsigned short PixelType
GradientDirectionsContainerType::Pointer GetOriginalGradientContainer() const
mitk::MeasurementFrameProperty::MeasurementFrameType MeasurementFrameType
mitk::BaseProperty::Pointer GetProperty(const char *propertyKey) const
Get the property (instance of BaseProperty) with key propertyKey from the PropertyList, and set it to this, respectively;.
static const std::string GRADIENTCONTAINERPROPERTYNAME
static const std::string BVALUEMAPPROPERTYNAME
Class for nodes of the DataTree.
Definition: mitkDataNode.h:66
static const std::string ORIGINALGRADIENTCONTAINERPROPERTYNAME
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.