Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkPAPhantomTissueGenerator.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 #include "mitkPAVector.h"
16 
17 mitk::pa::InSilicoTissueVolume::Pointer mitk::pa::PhantomTissueGenerator::GeneratePhantomData(
18  TissueGeneratorParameters::Pointer parameters)
19 {
20  MITK_DEBUG << "Initializing Empty Volume";
21 
22  const double RESAMPLING_FACTOR = 2;
23 
24  if (parameters->GetDoPartialVolume())
25  {
26  parameters->SetXDim(parameters->GetXDim() * RESAMPLING_FACTOR);
27  parameters->SetYDim(parameters->GetYDim() * RESAMPLING_FACTOR);
28  parameters->SetZDim(parameters->GetZDim() * RESAMPLING_FACTOR);
29  parameters->SetVesselBifurcationFrequency(parameters->GetVesselBifurcationFrequency() * RESAMPLING_FACTOR);
30  parameters->SetVoxelSpacingInCentimeters(parameters->GetVoxelSpacingInCentimeters() / RESAMPLING_FACTOR);
31  }
32 
33  parameters->SetVesselBifurcationFrequency(10000);
34 
35  std::mt19937 randomNumberGenerator;
36  std::random_device randomDevice;
37  if (parameters->GetUseRngSeed())
38  {
39  randomNumberGenerator.seed(parameters->GetRngSeed());
40  }
41  else
42  {
43  if (randomDevice.entropy() > 0.1)
44  {
45  randomNumberGenerator.seed(randomDevice());
46  }
47  else
48  {
49  randomNumberGenerator.seed(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count());
50  }
51  }
52 
53  auto generatedVolume = mitk::pa::InSilicoTissueVolume::New(parameters, &randomNumberGenerator);
54 
55  const unsigned int NUMER_OF_VESSELS = 5;
56  const double START_DEPTH_IN_CM = 2.10;
57  const double START_X_IN_CM = 0.76;
58  const double RADIUS_IN_MM = 0.5;
59  const double INCREMENT_XZ_IN_CM = 0.50;
60  double ABSORPTION_PER_CM = parameters->GetMinVesselAbsorption();
61 
62  generatedVolume->AddIntProperty("numberOfVessels", NUMER_OF_VESSELS);
63  generatedVolume->AddIntProperty("bifurcationFrequency", parameters->GetVesselBifurcationFrequency());
64 
65  for (unsigned int vesselNumber = 0; vesselNumber < NUMER_OF_VESSELS; vesselNumber++)
66  {
67  Vector::Pointer initialPosition = Vector::New();
68  Vector::Pointer initialDirection = Vector::New();
69 
70  double initialRadius = RADIUS_IN_MM / parameters->GetVoxelSpacingInCentimeters() / 10;
71  std::stringstream radiusString;
72  radiusString << "vessel_" << vesselNumber + 1 << "_radius";
73  generatedVolume->AddDoubleProperty(radiusString.str(), initialRadius);
74 
75  double absorptionCoefficient = ABSORPTION_PER_CM;
76  std::stringstream absorptionString;
77  absorptionString << "vessel_" << vesselNumber + 1 << "_absorption";
78  generatedVolume->AddDoubleProperty(absorptionString.str(), absorptionCoefficient);
79 
80  double bendingFactor = 0;
81  std::stringstream bendingString;
82  bendingString << "vessel_" << vesselNumber + 1 << "_bendingFactor";
83  generatedVolume->AddDoubleProperty(bendingString.str(), bendingFactor);
84 
85  double vesselScattering = 15;
86  std::stringstream scatteringString;
87  scatteringString << "vessel_" << vesselNumber + 1 << "_scattering";
88  generatedVolume->AddDoubleProperty(scatteringString.str(), vesselScattering);
89 
90  double vesselAnisotropy = 0.9;
91  std::stringstream anisotropyString;
92  anisotropyString << "vessel_" << vesselNumber + 1 << "_anisotropy";
93  generatedVolume->AddDoubleProperty(anisotropyString.str(), vesselAnisotropy);
94 
95  /*The vessel tree shall start at one of the 4 sides of the volume.
96  * The vessels will always be completely contained in the volume
97  * when starting to meander.
98  * They will meander in a direction perpendicular to the
99  * plane they started from (within the limits of the
100  * DIRECTION_VECTOR_INITIAL_VARIANCE)
101  */
102 
103  double zposition = (START_DEPTH_IN_CM + (vesselNumber*INCREMENT_XZ_IN_CM)) / parameters->GetVoxelSpacingInCentimeters();
104 
105  double xposition = (START_X_IN_CM + (vesselNumber*INCREMENT_XZ_IN_CM)) / parameters->GetVoxelSpacingInCentimeters();
106 
107  initialPosition->Randomize(xposition, xposition, 0, 0, zposition, zposition, &randomNumberGenerator);
108  initialDirection->Randomize(0, 0, 1, 1, 0, 0, &randomNumberGenerator);
109 
110  initialDirection->Normalize();
111  MITK_INFO << initialPosition->GetElement(0) << " | " << initialPosition->GetElement(1) << " | " << initialPosition->GetElement(2);
112  MITK_INFO << initialDirection->GetElement(0) << " | " << initialDirection->GetElement(1) << " | " << initialDirection->GetElement(2);
113 
114  VesselProperties::Pointer vesselParams = VesselProperties::New();
115  vesselParams->SetDirectionVector(initialDirection);
116  vesselParams->SetPositionVector(initialPosition);
117  vesselParams->SetRadiusInVoxel(initialRadius);
118  vesselParams->SetAbsorptionCoefficient(absorptionCoefficient);
119  vesselParams->SetScatteringCoefficient(vesselScattering);
120  vesselParams->SetAnisotopyCoefficient(vesselAnisotropy);
121  vesselParams->SetBifurcationFrequency(parameters->GetVesselBifurcationFrequency());
122  vesselParams->SetDoPartialVolume(parameters->GetDoPartialVolume());
123 
124  VesselTree::Pointer vesselTree = VesselTree::New(vesselParams);
125 
126  while (!vesselTree->IsFinished())
127  {
128  vesselTree->Step(generatedVolume, parameters->GetCalculateNewVesselPositionCallback(), bendingFactor, &randomNumberGenerator);
129  }
130  }
131 
132  if (parameters->GetDoPartialVolume())
133  {
134  VolumeManipulator::RescaleImage(generatedVolume, (1.0 / RESAMPLING_FACTOR));
135  parameters->SetXDim(parameters->GetXDim() / RESAMPLING_FACTOR);
136  parameters->SetYDim(parameters->GetYDim() / RESAMPLING_FACTOR);
137  parameters->SetZDim(parameters->GetZDim() / RESAMPLING_FACTOR);
138  parameters->SetVesselBifurcationFrequency(parameters->GetVesselBifurcationFrequency() / RESAMPLING_FACTOR);
139  parameters->SetVoxelSpacingInCentimeters(parameters->GetVoxelSpacingInCentimeters() * RESAMPLING_FACTOR);
140  }
141 
142  generatedVolume->FinalizeVolume();
143 
144  return generatedVolume;
145 }
146 
147 mitk::pa::PhantomTissueGenerator::PhantomTissueGenerator()
148 {
149 }
150 
151 mitk::pa::PhantomTissueGenerator::~PhantomTissueGenerator()
152 {
153 }
#define MITK_INFO
Definition: mitkLogMacros.h:18
static InSilicoTissueVolume::Pointer GeneratePhantomData(TissueGeneratorParameters::Pointer parameters)
GenerateInSilicoData This method will return a InSilicoTissueVolume created in terms of the given par...
#define MITK_DEBUG
Definition: mitkLogMacros.h:22
static InSilicoTissueVolume::Pointer New(mitk::pa::Volume::Pointer absorptionVolume, Volume::Pointer scatteringVolume, Volume::Pointer anisotropyVolume, Volume::Pointer segmentationVolume, TissueGeneratorParameters::Pointer tissueParameters, mitk::PropertyList::Pointer propertyList)
static void RescaleImage(InSilicoTissueVolume::Pointer image, double ratio)
static Pointer New()