17 #include <eigen3/Eigen/Dense> 36 mitkThrow() <<
"ADD OUTPUTS HAS TO BE LARGER THEN ZERO!";
37 this->SetNumberOfIndexedOutputs(outputs);
38 for (
unsigned int i = 0; i<GetNumberOfIndexedOutputs(); i++)
67 void mitk::pa::SpectralUnmixingFilterBase::GenerateData()
72 CheckPreConditions(input);
74 unsigned int xDim = input->GetDimensions()[0];
75 unsigned int yDim = input->GetDimensions()[1];
76 unsigned int numberOfInputImages = input->GetDimensions()[2];
84 const float* inputDataArray = ((
const float*)readAccess.
GetData());
87 unsigned int totalNumberOfSequences = numberOfInputImages / sequenceSize;
90 InitializeOutputs(totalNumberOfSequences);
95 myfile.open(
"SimplexNormalisation.txt");
97 unsigned int outputCounter = GetNumberOfIndexedOutputs();
98 std::vector<float*> writteBufferVector;
99 for (
unsigned int i = 0; i < outputCounter; ++i)
103 float* writeBuffer = (
float *)writeOutput.
GetData();
104 writteBufferVector.push_back(writeBuffer);
113 for (
unsigned int sequenceCounter = 0; sequenceCounter < totalNumberOfSequences; ++sequenceCounter)
117 for (
unsigned int x = 0; x < xDim; x++)
119 for (
unsigned int y = 0; y < yDim; y++)
121 Eigen::VectorXf inputVector(sequenceSize);
122 for (
unsigned int z = 0; z < sequenceSize; z++)
129 unsigned int pixelNumber = (xDim*yDim*(z+sequenceCounter*sequenceSize)) + x * yDim + y;
130 auto pixel = inputDataArray[pixelNumber];
132 inputVector[z] = pixel;
138 float relativeError = CalculateRelativeError(endmemberMatrix, inputVector, resultVector);
139 writteBufferVector[outputCounter][(xDim*yDim * sequenceCounter) + x * yDim + y] = relativeError;
142 for (
unsigned int outputIdx = 0; outputIdx < outputCounter; ++outputIdx)
144 writteBufferVector[outputIdx][(xDim*yDim * sequenceCounter) + x * yDim + y] = resultVector[outputIdx];
158 mitkThrow() <<
"NO WAVELENGHTS/CHROMOPHORES SELECTED!";
164 mitkThrow() <<
"ADD MORE WAVELENGTHS OR REMOVE ENDMEMBERS!";
166 if (input->GetPixelType() != mitk::MakeScalarPixelType<float>())
167 mitkThrow() <<
"PIXELTYPE ERROR! FLOAT REQUIRED";
170 mitkThrow() <<
"INDEX ERROR! NUMBER OF OUTPUTS DOESN'T FIT TO OTHER SETTIGNS!";
175 void mitk::pa::SpectralUnmixingFilterBase::InitializeOutputs(
unsigned int totalNumberOfSequences)
179 unsigned int numberOfInputs = GetNumberOfIndexedInputs();
180 unsigned int numberOfOutputs = GetNumberOfIndexedOutputs();
181 MITK_INFO(
m_Verbose) <<
"Inputs: " << numberOfInputs <<
" Outputs: " << numberOfOutputs;
184 const int NUMBER_OF_SPATIAL_DIMENSIONS = 3;
185 auto* dimensions =
new unsigned int[NUMBER_OF_SPATIAL_DIMENSIONS];
186 for (
unsigned int dimIdx = 0; dimIdx < 2; dimIdx++)
188 dimensions[2] = totalNumberOfSequences;
190 for (
unsigned int outputIdx = 0; outputIdx < numberOfOutputs; outputIdx++)
191 GetOutput(outputIdx)->Initialize(pixelType, NUMBER_OF_SPATIAL_DIMENSIONS, dimensions);
195 Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> mitk::pa::SpectralUnmixingFilterBase::CalculateEndmemberMatrix(
198 unsigned int numberOfChromophores = m_Chromophore.size();
199 unsigned int numberOfWavelengths = m_Wavelength.size();
200 Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> endmemberMatrixEigen(numberOfWavelengths, numberOfChromophores);
202 for (
unsigned int j = 0; j < numberOfChromophores; ++j)
204 for (
unsigned int i = 0; i < numberOfWavelengths; ++i)
205 endmemberMatrixEigen(i, j) = PropertyElement(m_Chromophore[j], m_Wavelength[i]);
208 return endmemberMatrixEigen;
213 if (chromophore == mitk::pa::PropertyCalculator::ChromophoreType::ONEENDMEMBER)
217 float value = m_PropertyCalculatorEigen->GetAbsorptionForWavelength(chromophore, wavelength);
219 mitkThrow() <<
"WAVELENGTH " << wavelength <<
"nm NOT SUPPORTED!";
225 float mitk::pa::SpectralUnmixingFilterBase::CalculateRelativeError(Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> endmemberMatrix,
226 Eigen::VectorXf inputVector, Eigen::VectorXf resultVector)
228 float relativeError = (endmemberMatrix*resultVector - inputVector).norm() / inputVector.norm();
229 for (
int i = 0; i < 2; ++i)
234 return relativeError;
void AddWavelength(int wavelength)
AddWavelength takes integers and writes them at the end of the m_Wavelength vector. The first call of the method then corresponds to the first input image and so on.
unsigned int * GetDimensions() const
Get the sizes of all dimensions as an integer-array.
void * GetData()
Gives full data access.
virtual void Verbose(bool verbose)
virtual void AddOutputs(unsigned int outputs)
AddOutputs takes an integer and sets indexed outputs.
virtual void AddRelativeErrorSettings(int value)
AddRelativeErrorSettings takes integers and writes them at the end of the m_RelativeErrorSettings vec...
std::vector< mitk::pa::PropertyCalculator::ChromophoreType > m_Chromophore
std::vector< int > m_Wavelength
void AddChromophore(mitk::pa::PropertyCalculator::ChromophoreType chromophore)
AddChromophore takes mitk::pa::PropertyCalculator::ChromophoreType and writes them at the end of the ...
InputImageType * GetInput(void)
SpectralUnmixingFilterBase()
Constructor creats proptery calculater smart pointer new()
OutputType * GetOutput()
Get the output data of this image source object.
ImageWriteAccessor class to get locked write-access for a particular image part.
virtual void RelativeError(bool relativeError)
virtual Eigen::VectorXf SpectralUnmixingAlgorithm(Eigen::Matrix< float, Eigen::Dynamic, Eigen::Dynamic > endmemberMatrix, Eigen::VectorXf inputVector)=0
The subclasses will override the mehtod to calculate the spectral unmixing result vector...
ImageReadAccessor class to get locked read access for a particular image part.
~SpectralUnmixingFilterBase() override
const void * GetData() const
Gives const access to the data.
Class for defining the data type of pixels.
std::vector< int > m_RelativeErrorSettings