diff --git a/Modules/PhotoacousticsLib/include/mitkPASpectralUnmixingFilterBase.h b/Modules/PhotoacousticsLib/include/mitkPASpectralUnmixingFilterBase.h index 7e012dbaa9..9801ff814b 100644 --- a/Modules/PhotoacousticsLib/include/mitkPASpectralUnmixingFilterBase.h +++ b/Modules/PhotoacousticsLib/include/mitkPASpectralUnmixingFilterBase.h @@ -1,176 +1,177 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKPHOTOACOUSTICSPECTRALUNMIXINGFILTERBASE_H #define MITKPHOTOACOUSTICSPECTRALUNMIXINGFILTERBASE_H #include "mitkImageToImageFilter.h" #include //Includes for smart pointer usage #include "mitkCommon.h" #include "itkLightObject.h" // Includes for AddEnmemberMatrix #include "mitkPAPropertyCalculator.h" #include namespace mitk { namespace pa { /** * \brief The spectral unmixing filter base is designed as superclass for several spectral unmixing filter eg. Eigen- or Vigrabased ones. * One can add wavelengths and chromophores and get a unmixed output images out of one MITK input image using algorithms from the subclasses. * * Input: * The unmixing input has to be a 3D MITK image where the XY-plane is a image and the Z-direction represents recordings for different * wavelengths. Herein a XY-plane for a specific Z-direction will be called "image". Every image has to be assigned to a certain wavelength. * The "AddWavelength" uses "push_back" to write float values into a vector. The first wavelength will correspond to the first image!!! * If there a more input images 'I' then added wavelengths 'w' the filter base interprets the next x images as repetition sequence of the same * wavelengths. If I % w !=0 the surplus image(s) will be dropped. * Addtionaly one has to add chromophores from the property calculator class enum "ChromophoreType" with the "AddChromophore" method. * This method as well uses "push_back" but the chosen (arbitary) order will be the order of the outputs. * * Output: * The output will be one MITK image per chosen chromophore. Where the XY-plane is a image and the Z-direction represents recordings for different - * sequences. + * sequences. Furthermore it is possible to creat an output image that contains the information about the relative error between unmixing result + * and the input image. * * Subclasses: * - mitkPASpectralUnmixingFilterVigra * - mitkPALinearSpectralUnmixingFilter (uses Eigen algorithms) * - mitkPASpectralUnmixingFilterSimplex * * Possible exceptions: * - "PIXELTYPE ERROR! FLOAT 32 REQUIRED": The MITK input image has to consist out of floats. * - "ERROR! REMOVE WAVELENGTHS!": One needs at least the same amount of images (z-dimension) then added wavelengths. * - "ADD MORE WAVELENGTHS!": One needs at least the same amount of wavelengths then added chromophores. * - "WAVELENGTH XXX nm NOT SUPPORTED!": The wavelength is not part of the proptery calculater data base. The data base can be found @ * [...]\mitk\Modules\PhotoacousticsLib\Resources\spectralLIB.dat */ class MITKPHOTOACOUSTICSLIB_EXPORT SpectralUnmixingFilterBase : public mitk::ImageToImageFilter { public: mitkClassMacro(SpectralUnmixingFilterBase, mitk::ImageToImageFilter); /** * \brief AddChromophore takes mitk::pa::PropertyCalculator::ChromophoreType and writes them at the end of the m_Chromophore vector. * The call of the method sets the order of the GetOutput method! * * @param chromophore has to be element of porperty calculater enum chromophore type * @return for wavelength smaller then 300nm and larger then 1000nm the return will be 0, because not at the data base (2018/06/19) */ void AddChromophore(mitk::pa::PropertyCalculator::ChromophoreType chromophore); /** * \brief 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. * @param wavelength database supports integers between 300 and 1000 nm */ void AddWavelength(int wavelength); /* * \brief Verbose gives more information to the console. Default value is false. * @param verbose is the boolian to activate the MITK_INFO logged to the console */ virtual void Verbose(bool verbose); /** * \brief AddOutputs takes an integer and sets indexed outputs * @param outputs integer correponds to the number of output images */ virtual void AddOutputs(unsigned int outputs); /* * \brief RelativeError returns a image which compare the L2 norm of the input vector with the unmixing result * @param relativeError is the boolian to activate this tool */ virtual void RelativeError(bool relativeError); ofstream myfile; // just for testing purposes; has to be removeed protected: /** * \brief Constructor creats proptery calculater smart pointer new() */ SpectralUnmixingFilterBase(); virtual ~SpectralUnmixingFilterBase(); /** * \brief The subclasses will override the mehtod to calculate the spectral unmixing result vector. * @param endmemberMatrix Matrix with number of chromophores colums and number of wavelengths rows so matrix element (i,j) contains * the absorbtion of chromophore j @ wavelength i taken from the database by PropertyElement method. * @param inputVector Vector containing values of one pixel of XY-plane image with number of wavelength rows (z-dimension of a sequenece) * so the pixelvalue of the first wavelength is stored in inputVector[0] and so on. */ virtual Eigen::VectorXf SpectralUnmixingAlgorithm(Eigen::Matrix endmemberMatrix, Eigen::VectorXf inputVector) = 0; bool m_Verbose = false; bool m_RelativeError = false; std::vector m_Chromophore; std::vector m_Wavelength; private: /* * \brief Initialized output images with the same XY-plane size like the input image and total size in z-direction equals number of sequences. * The pixel type is set to float. * @param totalNumberOfSequences = (unsigned int) (numberOfInputImages / numberOfWavelength) >= 1 */ virtual void InitializeOutputs(unsigned int totalNumberOfSequences); /* * \brief Checks if there are a suitable amount of wavelengths and if the input image consists of floats. * @param numberOfInputImages corresponds to the z-dimension of the MITK input image * @param inputDataArray contains every pixel of the MITK input image. Accessable like pseudo multidimensional array, that means * pixel(x,y,z) = (xdim * yDim * z) + x * yDim + y where eg. "xdim" means the total size of the MITK input image in x direction. * @throws if there are more wavelength then images * @throws if there are more chromophores then wavelengths * @throws if the pixel type is not float 32 */ virtual void CheckPreConditions(unsigned int numberOfInputImages, const float* inputDataArray); /* * \brief Inherit from the "ImageToImageFilter" Superclass. Herain it calls InitializeOutputs, CalculateEndmemberMatrix and * CheckPreConditions methods and enables pixelwise access to do spectral unmixing with the "SpectralUnmixingAlgorithm" * method. In the end the method writes the results into the new MITK output images. */ virtual void GenerateData() override; /* * \brief Creats a Matrix with number of chromophores colums and number of wavelengths rows so matrix element (i,j) contains * the absorbtion of chromophore j @ wavelength i. The absorbtion values are taken from the "PropertyElement" method. * @param m_Chromophore is a vector of "PropertyCalculator::ChromophoreType" containing all selected chromophores for the unmixing * @param m_Wavelength is a vector of integers containing all wavelengths of one sequence */ virtual Eigen::Matrix CalculateEndmemberMatrix( std::vector m_Chromophore, std::vector m_Wavelength); /* * \brief "PropertyElement" is the tool to access the absorbtion values out of the database using mitk::pa::PropertyCalculator::GetAbsorptionForWavelengt * and checks if the requested wavelength is part of the database (not zero values). The "ONEENDMEMBER" is a pseudo absorber with static absorbtion 1 * at every wavelength and is therefor not part of the database. If this one is the selected chromophore the return value is 1 for every wavelength. * @param wavelength has to be integer between 300 and 1000 nm * @param chromophore has to be a mitk::pa::PropertyCalculator::ChromophoreType * @throws if mitk::pa::PropertyCalculator::GetAbsorptionForWavelengt returns 0, because this means that the delivered wavelength is not in the database. */ virtual float PropertyElement(mitk::pa::PropertyCalculator::ChromophoreType, int wavelength); PropertyCalculator::Pointer m_PropertyCalculatorEigen; }; } } #endif // MITKPHOTOACOUSTICSPECTRALUNMIXINGFILTERBASE_ diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/GUI.PNG b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/GUI.PNG new file mode 100644 index 0000000000..23c2c5cdd0 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/GUI.PNG differ diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/Manual.dox index 6a4d6266a3..177ecacda1 100644 --- a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/Manual.dox +++ b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/Manual.dox @@ -1,17 +1,37 @@ /** -\page org_mitk_gui_qt_photoacoustics_spectralunmixing The Spectralunmixing +\page org_mitk_gui_qt_photoacoustics_spectralunmixing The spectral unmixing (SU) plugin \imageMacro{icon.png,"Icon of Spectralunmixing",2.00} -\tableofcontents +\table of contents +
    +
  • Introduction +
  • Overview +
  • How to add an additional algorithm +
-\section org_mitk_gui_qt_photoacoustics_spectralunmixingOverview Overview -Describe the features of your awesome plugin here +\section org_mitk_gui_qt_photoacoustics_spectralunmixingIntroduction +The spectral unmixing plugin provides a GUI tool to perform spectral unmixing of multispectral MITK images. It was designed to unmix beamformed photoacoustic images. The outputs are MITK images for every chosen absorber (endmember). Furthermore it is possible to calculate the oxygen saturation of the multispectral input if the endmembers oxy- and deoxyhemoglobin are selected in the GUI as well as an output image that contains the information about the relative error between unmixing result and the input image. +Detailed information about the Plugin, the baseclass and its subclasses can be found in their header files. If you want to call the SU filter from your own class have a look at the “mitkSpectralUnmixingTest.cpp”. There you find information about which functions are callable or have to be called from your class to guarantee the promised functionality of the SU filter. + +\section org_mitk_gui_qt_photoacoustics_spectralunmixingOverview
    -
  • Increases productivity -
  • Creates beautiful images -
  • Generates PhD thesis -
  • Brings world peace +
  • supports several linear Eigen solvers collected in the “mitkPALinearSpectralUnmixingFilter” +
  • supports several linear Vigra solvers collected in the “mitkPASpectralUnmixingVigraFilter” +
  • calculates oxygen saturation with the “mitkPASpectralUnmixingSO2”
+\section How to add an additional algorithm: +If the algorithm fits in one of the existing classes you can ignore steps 0. – 3. +0. Have a look at the commit rMITK36cfd1731089: implement three empty classes for Simplex, Lagrange and Vigra SU algorithms. Which actually are exactly the first (not all!) steps to implement a new algorithm. +1. Add your future header and cpp file to files.cmake +2. Create a header file which needs at least the methods shown in header.png +\imageMacro{header.png,"empty header for a new SU algorithm",2.00} +3. Create a cpp file which takes an Eigen endmember matrix and an Eigen input vector as inputs and returns an Eigen vector as result. A structure like in the cpp.png is recommended. If your class will consist of more than one algorithm you should have an if/else decision between them with an enum like in the cpp.png otherwise you can directly return your result. +\imageMacro{cpp.png,"example cpp file for a new SU algorithm",2.00} +4. In the Plugin you just have to add another “else if” like in the plugin.png. The string in the else if has to be the same then selectable in the GUI(step 5). +\imageMacro{plugin.png,"changes of Plugin for a new SU algorithm",2.00} +5. To make you algorithm selectable you have to add to the GUI Combobox. Klick at 1. (GUI.png), then at 2. and then name your algorithm 3. like in step 4. +\imageMacro{GUI.png,"changes of GUI for a new SU algorithm",2.00} + */ diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/cpp.PNG b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/cpp.PNG new file mode 100644 index 0000000000..b47993b6cc Binary files /dev/null and b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/cpp.PNG differ diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/header.PNG b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/header.PNG new file mode 100644 index 0000000000..1f02be12c8 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/header.PNG differ diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/icon.png b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/icon.png new file mode 100644 index 0000000000..3384467830 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/icon.png differ diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/icon.xpm b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/icon.xpm deleted file mode 100644 index 9057c20bc6..0000000000 --- a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/icon.xpm +++ /dev/null @@ -1,21 +0,0 @@ -/* XPM */ -static const char * icon_xpm[] = { -"16 16 2 1", -" c #FF0000", -". c #000000", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" "}; diff --git a/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/plugin.PNG b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/plugin.PNG new file mode 100644 index 0000000000..89d7559d66 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.photoacoustics.spectralunmixing/documentation/UserManual/plugin.PNG differ