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
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.