diff --git a/Modules/PhotoacousticArtifacts/src/Algorithms/mitkPhotoacousticArtifact.cpp b/Modules/PhotoacousticArtifacts/src/Algorithms/mitkPhotoacousticArtifact.cpp index e088f047bc..65b7e8d07c 100644 --- a/Modules/PhotoacousticArtifacts/src/Algorithms/mitkPhotoacousticArtifact.cpp +++ b/Modules/PhotoacousticArtifacts/src/Algorithms/mitkPhotoacousticArtifact.cpp @@ -1,104 +1,84 @@ /*=================================================================== 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. ===================================================================*/ #include #include #include #include +#include #include -//Step 1: inputImage in matrix m überführen -//Step 2: eigenvectoren der matrix berechnen -//Step 3: eigenvectors in outputImage überführen - +template static void ComputeSVD(mitk::Image::Pointer inputImage, int svdNumber, mitk::Image::Pointer outputImage) { - //MatrixXd m = - Eigen::MatrixXd m(2, 2); - m(0, 0) = 2; - m(1, 0) = -1; - m(0, 1) = 2; - m(1, 1) = 1; + //Step 1: inputImage in matrix m überführen + unsigned int* dimension = inputImage->GetDimensions(); //0=x, 1=y, 2=z + unsigned int numberOfSlices = dimension[2]; + unsigned int vectorLength = dimension[0] * dimension[1]; + + Eigen::MatrixXd m(vectorLength, numberOfSlices); + for (unsigned int i = 0; i < numberOfSlices; ++i) + { + mitk::ImageReadAccessor readAccessor(inputImage, inputImage->GetSliceData(i)); + const TPixel* data = (const TPixel*)readAccessor.GetData(); + for (unsigned int j = 0; j < vectorLength; ++j) + { + m(j, i) = (double)data[j]; + } + } + + //Step 2: eigenvectoren der matrix berechnen Eigen::JacobiSVD svdSolver(m, Eigen::ComputeFullV); Eigen::MatrixXd matrixV = svdSolver.matrixV(); auto eigenVec1 = matrixV.col(0); auto eigenVec2 = matrixV.col(1); MITK_INFO << "Matrix V: " << endl << matrixV << endl; MITK_INFO << "Eigenvector 1: " << endl << eigenVec1 << endl; MITK_INFO << "Eigenvector 2: " << endl << eigenVec2 << endl; - //This is the tricky part that is done wrong very often.As the image data - // of ITK images and MITK images are binary compatible, we don't need to - // cast or copy the ITK output image.Instead, we just want to reference - // the image data and tell ITK that we took the ownership. - //mitk::GrabItkImageMemory(svd->GetOutput(), outputImage); + //Step 3: eigenvectors in outputImage überführen + mitk::PixelType pixelType = mitk::MakeScalarPixelType(); + outputImage->Initialize(pixelType, 3, dimension); + for (unsigned int i = 0; i < numberOfSlices; ++i) + { + outputImage->SetImportSlice(matrixV.col(i).data(), i); + } } mitk::PhotoacousticArtifact::PhotoacousticArtifact() : m_SVD(1) { this->SetPrimaryOutput(mitk::Image::New()); MITK_INFO << "Hello."; this->SetNumberOfRequiredInputs(1); this->SetNumberOfRequiredOutputs(1); } mitk::PhotoacousticArtifact::~PhotoacousticArtifact() { } void mitk::PhotoacousticArtifact::GenerateData() { mitk::Image::Pointer inputImage = this->GetInput(0); mitk::Image::Pointer outputImage = this->GetOutput(); - ComputeSVD(nullptr, 1, nullptr); - - //try - //{ - // // We want to apply an ITK filter to the MITK input image. While MITK - // // images are not templated, ITK images are templated by both pixel type - // // and image dimension. The actual image data is binary compatible, though. - // // MITK provides ITK access macros that enable you to directly operate - // // on MITK images without any superfluous copying. - // // To allow ITK filters to work with different image types at runtime you - // // would be required to instantiate your function templates for each and - // // every expected combination of pixel type and image dimension. Luckily, - // // MITK provides a whole bunch of multiplexer macros to save you doing this - // // manually (see mitkImageAccessByItk.h). - // // These macros range from being completely generic to partly constrained - // // variants. For example, you may want to constrain the image dimension or - // // the pixel type. As your function template is compiled for each allowed - // // combination, compile time and code size may increase dramatically. - // // As a rule of thumb, use a suitable multiplexer macro that is as - // // constrained as possible and yet as generic as necessary. - // // To prevent a combinatorial explosion, image dimension is restricted to - // // 2 and 3 even for the dimension-variable multiplexer macros. - // // Thus, the following multiplexer macro allows for 2-dimensional and - // // 3-dimensional images with an integer pixel type, for example, - // // (un)signed char, short, and int, resulting in a total of 12 distinct - // // combinations. - // AccessIntegralPixelTypeByItk_n(inputImage, ComputeSVD, (outputImage)); - //} - //catch (const mitk::AccessByItkException& e) - //{ - // MITK_ERROR << "Unsupported pixel type or image dimension: " << e.what(); - //} + ComputeSVD(inputImage, 1, outputImage); }