Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkPASpectralUnmixingFilterSimplex.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 
15 // Includes for AddEnmemberMatrix
16 #include <eigen3/Eigen/Dense>
17 
18 #include <cmath>
19 
21 {
22 
23 }
24 
26 {
27 
28 }
29 
30 Eigen::VectorXf mitk::pa::SpectralUnmixingFilterSimplex::SpectralUnmixingAlgorithm(
31  Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> EndmemberMatrix, Eigen::VectorXf inputVector)
32 {
33  int numberOfChromophores = EndmemberMatrix.cols();
34 
35  Eigen::VectorXf resultVector(numberOfChromophores);
36  Eigen::VectorXf normalizedInputVector(EndmemberMatrix.rows());
37  normalizedInputVector = Normalization(EndmemberMatrix, inputVector);
38  //normalizedInputVector = inputVector;
39 
40 
41  float VolumeMax = simplexVolume(EndmemberMatrix);
42  for (int i = 0; i < numberOfChromophores; ++i)
43  {
44  Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> A = GenerateA(EndmemberMatrix, normalizedInputVector, i);
45  float Volume = simplexVolume(A);
46 
47 
48  resultVector[i] = Volume / VolumeMax;
49 
50  myfile << "resultVector["<<i<<"]: " << resultVector[i] << "\n";
51  myfile << "Volume: " << Volume << "\n";
52  myfile << "VolumeMax: " << VolumeMax << "\n";
53 
54  }
55  //
56 
57  return resultVector;
58  // see code @ linearSUFilter
59 }
60 
61 
62 Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> mitk::pa::SpectralUnmixingFilterSimplex::GenerateA
63 (Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> EndmemberMatrix, Eigen::VectorXf inputVector, int i)
64 {
65  Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> A = EndmemberMatrix;
66  int numberOfChromophores = EndmemberMatrix.cols();
67 
68  for (int j = 0; j < numberOfChromophores; ++j)
69  {
70  A(i, j) = inputVector(j);
71  }
72 
73  return A;
74 }
75 
76 Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> mitk::pa::SpectralUnmixingFilterSimplex::GenerateD2
77 (Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> A)
78 {
79  int numberOfChromophores = A.cols();
80 
81  Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> D2(numberOfChromophores, numberOfChromophores);
82 
83  for (int i = 0; i < numberOfChromophores; ++i)
84  {
85  for (int j = 0; j < numberOfChromophores; ++j)
86  {
87  Eigen::VectorXf x = A.col(i) - A.col(j);
88  //MITK_INFO << "a_col_i: " <<A.col(i);
89  //MITK_INFO << "a_col_j: " <<A.col(j);
90  //MITK_INFO << "x: " <<x;
91  Eigen::VectorXf y = x;
92  float foo = x.dot(y);
93  //MITK_INFO << "x*y: " << foo;
94 
95  D2(i, j) = foo;
96  }
97  }
98 
99  return D2;
100 }
101 
102 float mitk::pa::SpectralUnmixingFilterSimplex::simplexVolume(Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> Matrix)
103 {
104  float Volume;
105  int numberOfChromophores = Matrix.cols();
106  Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> C(numberOfChromophores + 1, numberOfChromophores + 1);
107  Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> D2 = GenerateD2(Matrix);
108 
109  for (int i = 0; i < numberOfChromophores; ++i)
110  {
111  for (int j = 0; j < numberOfChromophores; ++j)
112  {
113  C(i, j) = D2(i, j);
114  }
115  C(i, numberOfChromophores) = 1;
116  for (int k = 0; k < numberOfChromophores; ++k)
117  {
118  C(numberOfChromophores, k) = 1;
119  }
120  C(numberOfChromophores, numberOfChromophores) = 0;
121  }
122 
123  float detC = -C.determinant();// determinate von C
124  float denominator = (factorial(numberOfChromophores - 1)) ^ 2 * 2 ^ (numberOfChromophores - 1)*(-1) ^ numberOfChromophores;
125  Volume = std::sqrt(detC / denominator);
126  //MITK_INFO << "detC: " << detC;
127 
128  //MITK_INFO << "denominator: " << denominator;
129 
130  //MITK_INFO << "Volume: " << Volume;
131 
132  return Volume;
133 }
134 
135 int mitk::pa::SpectralUnmixingFilterSimplex::factorial(int n)
136 {
137  if (n == 1)
138  return 1;
139  else
140  return n * factorial(n - 1);
141 }
142 
143 Eigen::VectorXf mitk::pa::SpectralUnmixingFilterSimplex::Normalization(
144  Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> EndmemberMatrix, Eigen::VectorXf inputVector)
145 {
146  int numberOfWavelengths = inputVector.rows();
147  Eigen::VectorXf result(numberOfWavelengths);
148  float NormalizationFactor = 1;
149  float foo;
150  float norm = 0;
151 
152  for (int i = 0; i < numberOfWavelengths; ++i)
153  {
154  foo = EndmemberMatrix(i, 0) - EndmemberMatrix(i, 1);
155  if (std::abs(foo) > norm)
156  norm = std::abs(foo);
157  }
158 
159 //ofstream myfile;
160 //myfile.open("SimplexNormalisation.txt");
161  //NormalizationFactor = inputVector[0] * 2 / norm;
162  myfile << "Normalizationfactor " << NormalizationFactor << "\n";
163 
164  for (int i = 0; i < numberOfWavelengths; ++i)
165  {
166 
167  result[i]=(inputVector[i]/NormalizationFactor);
168  }
169 //myfile.close();
170 
171  return result;
172 }
float k(1.0)
The Volume class is designed to encapsulate volumetric information and to provide convenience methods...
Definition: mitkPAVolume.h:30