diff --git a/Modules/BasicImageProcessing/src/mitkTransformationOperation.cpp b/Modules/BasicImageProcessing/src/mitkTransformationOperation.cpp index 323c74bc00..87269991c4 100644 --- a/Modules/BasicImageProcessing/src/mitkTransformationOperation.cpp +++ b/Modules/BasicImageProcessing/src/mitkTransformationOperation.cpp @@ -1,500 +1,500 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkTransformationOperation.h" #include #include #include #include #include #include // Wavelet #include #include #include #include #include #include #include #include #include #include "itkZeroFluxNeumannBoundaryCondition.h" #include "itkPeriodicBoundaryCondition.h" #include "itkConstantBoundaryCondition.h" //#include #include "itkCastImageFilter.h" #include "itkUnaryFunctorImageFilter.h" #include -#include +#include #include namespace mitk { namespace Functor { template< class TInput> class ThresholdValue { public: ThresholdValue() {}; ~ThresholdValue() {}; bool operator!=(const ThresholdValue &) const { return false; } bool operator==(const ThresholdValue & other) const { return !(*this != other); } inline unsigned short operator()(const TInput & A) const { if (A < value) return 0; else return 1; } double value = 0.0; }; template< class TInput, class TOutput> class RoundValue { public: RoundValue() {}; ~RoundValue() {}; bool operator!=(const RoundValue &) const { return false; } bool operator==(const RoundValue & other) const { return !(*this != other); } inline TOutput operator()(const TInput & A) const { return std::round(A); } }; } } template static void ExecuteMultiResolution(itk::Image* image, unsigned int numberOfLevels, bool outputAsDouble, std::vector &resultImages) { typedef itk::Image ImageType; typedef itk::Image DoubleOutputType; typedef itk::RecursiveMultiResolutionPyramidImageFilter ImageTypeFilterType; typedef itk::RecursiveMultiResolutionPyramidImageFilter DoubleTypeFilterType; if (outputAsDouble) { typename DoubleTypeFilterType::Pointer recursiveMultiResolutionPyramidImageFilter = DoubleTypeFilterType::New(); recursiveMultiResolutionPyramidImageFilter->SetInput(image); recursiveMultiResolutionPyramidImageFilter->SetNumberOfLevels(numberOfLevels); recursiveMultiResolutionPyramidImageFilter->Update(); // This outputs the levels (0 is the lowest resolution) for (unsigned int i = 0; i < numberOfLevels; ++i) { mitk::Image::Pointer outputImage = mitk::Image::New(); CastToMitkImage(recursiveMultiResolutionPyramidImageFilter->GetOutput(i), outputImage); resultImages.push_back(outputImage); } } else { typename ImageTypeFilterType::Pointer recursiveMultiResolutionPyramidImageFilter = ImageTypeFilterType::New(); recursiveMultiResolutionPyramidImageFilter->SetInput(image); recursiveMultiResolutionPyramidImageFilter->SetNumberOfLevels(numberOfLevels); recursiveMultiResolutionPyramidImageFilter->Update(); // This outputs the levels (0 is the lowest resolution) for (unsigned int i = 0; i < numberOfLevels; ++i) { mitk::Image::Pointer outputImage = mitk::Image::New(); CastToMitkImage(recursiveMultiResolutionPyramidImageFilter->GetOutput(i), outputImage); resultImages.push_back(outputImage); } } } std::vector mitk::TransformationOperation::MultiResolution(Image::Pointer & image, unsigned int numberOfLevels, bool outputAsDouble) { std::vector resultImages; AccessByItk_n(image, ExecuteMultiResolution, (numberOfLevels, outputAsDouble, resultImages)); return resultImages; } template static void ExecuteLaplacianOfGaussian(itk::Image* image, double sigma, bool outputAsDouble, mitk::Image::Pointer &resultImage) { typedef itk::Image ImageType; typedef itk::Image DoubleOutputType; typedef itk::LaplacianRecursiveGaussianImageFilter ImageTypeFilterType; typedef itk::LaplacianRecursiveGaussianImageFilter DoubleTypeFilterType; if (outputAsDouble) { typename DoubleTypeFilterType::Pointer filter = DoubleTypeFilterType::New(); filter->SetInput(image); filter->SetSigma(sigma); filter->Update(); CastToMitkImage(filter->GetOutput(), resultImage); } else { typename ImageTypeFilterType::Pointer filter = ImageTypeFilterType::New(); filter->SetInput(image); filter->SetSigma(sigma); filter->Update(); CastToMitkImage(filter->GetOutput(), resultImage); } } mitk::Image::Pointer mitk::TransformationOperation::LaplacianOfGaussian(Image::Pointer & image, double sigma, bool outputAsDouble) { Image::Pointer resultImage; AccessByItk_n(image, ExecuteLaplacianOfGaussian, (sigma, outputAsDouble, resultImage)); return resultImage; } template static void ExecuteSpecificWaveletTransformation(itk::Image* image, unsigned int numberOfLevels, unsigned int numberOfBands, mitk::BorderCondition condition, std::vector &resultImages) { const unsigned int Dimension = VImageDimension; typedef TInputPixel PixelType; typedef TOutputPixel OutputPixelType; typedef itk::Image< PixelType, Dimension > ImageType; typedef itk::Image< double, Dimension > DoubleImageType; typedef itk::Image< OutputPixelType, Dimension > OutputImageType; typedef itk::CastImageFilter< ImageType, DoubleImageType > CastFilterType; typedef itk::FFTPadPositiveIndexImageFilter< DoubleImageType > FFTPadType; typedef itk::ForwardFFTImageFilter< DoubleImageType, itk::Image< std::complex, Dimension> > FFTFilterType; typedef typename FFTFilterType::OutputImageType ComplexImageType; typedef TWaveletFunction WaveletFunctionType; typedef itk::WaveletFrequencyFilterBankGenerator< ComplexImageType, WaveletFunctionType > WaveletFilterBankType; typedef itk::WaveletFrequencyForward< ComplexImageType, ComplexImageType, WaveletFilterBankType > ForwardWaveletType; typedef itk::InverseFFTImageFilter< ComplexImageType, OutputImageType > InverseFFTFilterType; // Convert input parameter unsigned int highSubBands = numberOfBands; //inputBands; unsigned int levels = numberOfLevels; // Perform FFT on input image typename CastFilterType::Pointer castFilter = CastFilterType::New(); castFilter->SetInput(image); // Pad Image so it fits the expect typename FFTPadType::Pointer fftpad = FFTPadType::New(); fftpad->SetSizeGreatestPrimeFactor(4); itk::ConstantBoundaryCondition< DoubleImageType > constantBoundaryCondition; itk::PeriodicBoundaryCondition< DoubleImageType > periodicBoundaryCondition; itk::ZeroFluxNeumannBoundaryCondition< DoubleImageType > zeroFluxNeumannBoundaryCondition; switch (condition) { case mitk::BorderCondition::Constant: fftpad->SetBoundaryCondition(&constantBoundaryCondition); break; case mitk::BorderCondition::Periodic: fftpad->SetBoundaryCondition(&periodicBoundaryCondition); break; case mitk::BorderCondition::ZeroFluxNeumann: fftpad->SetBoundaryCondition(&zeroFluxNeumannBoundaryCondition); break; default: break; } fftpad->SetInput(castFilter->GetOutput()); typename FFTFilterType::Pointer fftFilter = FFTFilterType::New(); fftFilter->SetInput(fftpad->GetOutput()); // Calculate forward transformation typename ForwardWaveletType::Pointer forwardWavelet = ForwardWaveletType::New(); forwardWavelet->SetHighPassSubBands(highSubBands); forwardWavelet->SetLevels(levels); forwardWavelet->SetInput(fftFilter->GetOutput()); forwardWavelet->Update(); // Obtain target spacing, size and origin typename ComplexImageType::SpacingType inputSpacing; for (unsigned int i = 0; i < Dimension; ++i) { inputSpacing[i] = image->GetLargestPossibleRegion().GetSize()[i]; } typename ComplexImageType::SpacingType expectedSpacing = inputSpacing; typename ComplexImageType::PointType inputOrigin = image->GetOrigin(); typename ComplexImageType::PointType expectedOrigin = inputOrigin; typename ComplexImageType::SizeType inputSize = fftFilter->GetOutput()->GetLargestPossibleRegion().GetSize(); typename ComplexImageType::SizeType expectedSize = inputSize; // Inverse FFT to obtain filtered images typename InverseFFTFilterType::Pointer inverseFFT = InverseFFTFilterType::New(); for (unsigned int level = 0; level < numberOfLevels + 1; ++level) { double scaleFactorPerLevel = std::pow(static_cast< double >(forwardWavelet->GetScaleFactor()),static_cast< double >(level)); for (unsigned int i = 0; i < Dimension; ++i) { expectedSize[i] = inputSize[i] / scaleFactorPerLevel; expectedOrigin[i] = inputOrigin[i]; expectedSpacing[i] = inputSpacing[i] * scaleFactorPerLevel; } for (unsigned int band = 0; band < highSubBands; ++band) { unsigned int nOutput = level * forwardWavelet->GetHighPassSubBands() + band; // Do not compute bands in low-pass level. if (level == numberOfLevels && band == 0) { nOutput = forwardWavelet->GetTotalOutputs() - 1; } else if (level == numberOfLevels && band != 0) { break; } inverseFFT->SetInput(forwardWavelet->GetOutput(nOutput)); inverseFFT->Update(); auto itkOutputImage = inverseFFT->GetOutput(); itkOutputImage->SetSpacing(expectedSpacing); mitk::Image::Pointer outputImage = mitk::Image::New(); CastToMitkImage(itkOutputImage, outputImage); resultImages.push_back(outputImage); } } } template static void ExecuteWaveletTransformation(itk::Image* image, unsigned int numberOfLevels, unsigned int numberOfBands, mitk::BorderCondition condition, mitk::WaveletType waveletType, std::vector &resultImages) { typedef itk::Point< double, VImageDimension > PointType; typedef itk::HeldIsotropicWavelet< double, VImageDimension, PointType > HeldIsotropicWaveletType; typedef itk::VowIsotropicWavelet< double, VImageDimension, PointType > VowIsotropicWaveletType; typedef itk::SimoncelliIsotropicWavelet< double, VImageDimension, PointType > SimoncelliIsotropicWaveletType; typedef itk::ShannonIsotropicWavelet< double, VImageDimension, PointType > ShannonIsotropicWaveletType; switch (waveletType) { case mitk::WaveletType::Held: ExecuteSpecificWaveletTransformation(image, numberOfLevels, numberOfBands, condition, resultImages); break; case mitk::WaveletType::Shannon: ExecuteSpecificWaveletTransformation(image, numberOfLevels, numberOfBands, condition, resultImages); break; case mitk::WaveletType::Simoncelli: ExecuteSpecificWaveletTransformation(image, numberOfLevels, numberOfBands, condition, resultImages); break; case mitk::WaveletType::Vow: ExecuteSpecificWaveletTransformation(image, numberOfLevels, numberOfBands, condition, resultImages); break; default: ExecuteSpecificWaveletTransformation(image, numberOfLevels, numberOfBands, condition, resultImages); break; } } std::vector mitk::TransformationOperation::WaveletForward(Image::Pointer & image, unsigned int numberOfLevels, unsigned int numberOfBands, mitk::BorderCondition condition, mitk::WaveletType waveletType) { std::vector resultImages; AccessByItk_n(image, ExecuteWaveletTransformation, (numberOfLevels, numberOfBands, condition, waveletType, resultImages)); return resultImages; } template static void ExecuteImageTypeToDouble(itk::Image* image, mitk::Image::Pointer &outputImage) { typedef itk::Image< TPixel, VImageDimension > ImageType; typedef itk::Image< double, VImageDimension > DoubleImageType; typedef itk::CastImageFilter< ImageType, DoubleImageType > CastFilterType; typedef itk::ImageDuplicator< DoubleImageType > DuplicatorType; // Perform FFT on input image typename CastFilterType::Pointer castFilter = CastFilterType::New(); castFilter->SetInput(image); castFilter->Update(); typename DuplicatorType::Pointer duplicator = DuplicatorType::New(); duplicator->SetInputImage(castFilter->GetOutput()); duplicator->Update(); CastToMitkImage(duplicator->GetOutput(), outputImage); } template static void ExecuteRoundImage(itk::Image* /*image*/, mitk::Image::Pointer resampledImage, mitk::Image::Pointer &outputImage) { typedef itk::Image< TPixel, VImageDimension > ImageType; typedef itk::Image< double, VImageDimension > DoubleImageType; typedef itk::UnaryFunctorImageFilter< DoubleImageType, ImageType, mitk::Functor::RoundValue > DefaultFilterType; typename DoubleImageType::Pointer itkImage = DoubleImageType::New(); mitk::CastToItkImage(resampledImage, itkImage); typename DefaultFilterType::Pointer filter = DefaultFilterType::New(); filter->SetInput(itkImage); filter->Update(); CastToMitkImage(filter->GetOutput(), outputImage); } mitk::Image::Pointer mitk::TransformationOperation::ResampleImage(Image::Pointer &image, mitk::Vector3D spacingVector, mitk::ImageMappingInterpolator::Type interpolator, GridInterpolationPositionType position, bool returnAsDouble, bool roundOutput) { // Convert image to double if required mitk::Image::Pointer tmpImage = image; if (returnAsDouble) { AccessByItk_n(image, ExecuteImageTypeToDouble, (tmpImage)); } auto newGeometry = image->GetGeometry()->Clone(); mitk::Vector3D spacing; mitk::BaseGeometry::BoundsArrayType bounds = newGeometry->GetBounds(); for (int i = 0; i < 3; ++i) { spacing[i] = newGeometry->GetSpacing()[i]; //bounds[i*2+1] = newGeometry->GetBounds()[i * 2 + 1]; if (spacingVector[i] > 0) { spacing[i] = spacingVector[i]; if (position == mitk::GridInterpolationPositionType::SameSize) { unsigned int samples = image->GetDimensions()[i]; double currentSpacing = newGeometry->GetSpacing()[i]; double newFactor = std::floor(samples*currentSpacing / spacingVector[i]); spacing[i] = samples * currentSpacing / newFactor; } } bounds[i * 2] = 0; bounds[i*2+1] = std::ceil(bounds[i*2+1] * newGeometry->GetSpacing()[i] *1.0 / spacing[i]); } mitk::Point3D origin = newGeometry->GetOrigin(); if (position == mitk::GridInterpolationPositionType::CenterAligned) { for (int i = 0; i < 3; ++i) { double oldLength = newGeometry->GetSpacing()[i] * newGeometry->GetBounds()[i*2+1]; double newLength = spacing[i] * bounds[i*2+1]; origin[i] = origin[i] - (newLength - oldLength) / 2; } } newGeometry->SetSpacing(spacing); newGeometry->SetOrigin(origin); newGeometry->SetBounds(bounds); mitk::Image::Pointer tmpResult = ImageMappingHelper::map( tmpImage, mitk::GenerateIdentityRegistration3D().GetPointer(), false, 0.0, //Padding Value newGeometry.GetPointer(), false, 0, //Error Value interpolator ); mitk::Image::Pointer result = mitk::Image::New(); if (roundOutput) { AccessByItk_n(tmpImage, ExecuteRoundImage, (tmpResult, result)); } else { result = tmpResult; } return result; } template static void ExecuteImageThresholding(itk::Image* image, mitk::Image::Pointer &resultImage) { typedef itk::Image ImageType; typedef itk::Image MaskType; typedef itk::UnaryFunctorImageFilter< ImageType, MaskType, mitk::Functor::ThresholdValue > DefaultFilterType; typename DefaultFilterType::Pointer filter = DefaultFilterType::New(); filter->SetInput(image); filter->GetFunctor().value = 0.5; filter->Update(); CastToMitkImage(filter->GetOutput(), resultImage); } mitk::Image::Pointer mitk::TransformationOperation::ResampleMask(Image::Pointer &image, mitk::Vector3D spacingVector, mitk::ImageMappingInterpolator::Type interpolator, GridInterpolationPositionType position) { mitk::Image::Pointer result; if (interpolator == mitk::ImageMappingInterpolator::NearestNeighbor) { result = TransformationOperation::ResampleImage(image, spacingVector, interpolator, position, false, false); } else { auto tmpResult = TransformationOperation::ResampleImage(image, spacingVector, interpolator, position, true, false); AccessByItk_n(tmpResult, ExecuteImageThresholding, (result)); } return result; } namespace itk { namespace utils { IndexPairType IndexToLevelBandSteerablePyramid(unsigned int linearIndex, unsigned int levels, unsigned int bands) { unsigned int totalOutputs = 1 + levels * bands; if (linearIndex > totalOutputs - 1) { itkGenericExceptionMacro(<< "Failed converting linearIndex " << linearIndex << " with levels: " << levels << " bands: " << bands << " to Level,Band pair : out of bounds"); } // Low pass (band = 0). if (linearIndex == totalOutputs - 1) { return std::make_pair(levels - 1, 0); } unsigned int band = (linearIndex) % bands + 1; // note integer division ahead. unsigned int level = (linearIndex) / bands; itkAssertInDebugAndIgnoreInReleaseMacro(level < levels); return std::make_pair(level, band); } // Instantiation template unsigned int ComputeMaxNumberOfLevels<3>(const Size< 3 >& inputSize, const unsigned int & scaleFactor); template unsigned int ComputeMaxNumberOfLevels<2>(const Size< 2 >& inputSize, const unsigned int & scaleFactor); } // end namespace utils } // end namespace itk diff --git a/Modules/Classification/CLMiniApps/CLMatchPointReg.cpp b/Modules/Classification/CLMiniApps/CLMatchPointReg.cpp index 2cab1b9183..2e29e11d93 100644 --- a/Modules/Classification/CLMiniApps/CLMatchPointReg.cpp +++ b/Modules/Classification/CLMiniApps/CLMatchPointReg.cpp @@ -1,164 +1,164 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkProperties.h" #include "mitkCommandLineParser.h" #include "mitkIOUtil.h" #include "mitkPreferenceListReaderOptionsFunctor.h" // MatchPoint #include #include #include #include #include #include #include #include #include #include #include -#include +#include // Qt #include #include #include //#include #include #include #include #include int main(int argc, char* argv[]) { mitkCommandLineParser parser; parser.setTitle("Dicom Loader"); parser.setCategory("Preprocessing Tools"); parser.setDescription(""); parser.setContributor("German Cancer Research Center (DKFZ)"); parser.setArgumentPrefix("--","-"); // Add command line argument names parser.addArgument("help", "h",mitkCommandLineParser::Bool, "Help:", "Show this help text"); parser.addArgument("moving", "m", mitkCommandLineParser::Directory, "Input folder:", "Input folder", us::Any(), false, false, false, mitkCommandLineParser::Input); parser.addArgument("fixed", "f", mitkCommandLineParser::Directory, "Input folder:", "Input folder", us::Any(), false, false, false, mitkCommandLineParser::Input); parser.addArgument("output", "o", mitkCommandLineParser::File, "Output file:", "Output file", us::Any(), false, false, false, mitkCommandLineParser::Output); parser.addArgument("reader", "r", mitkCommandLineParser::Int, "Reader ID", "Reader Name", us::Any(), false); parser.addArgument("interpolation", "interp", mitkCommandLineParser::Int, "Reader ID", "Reader Name", us::Any(), false); std::map parsedArgs = parser.parseArguments(argc, argv); QFileInfo fi(argv[0]); map::deployment::DLLDirectoryBrowser::Pointer browser = map::deployment::DLLDirectoryBrowser::New(); browser->addDLLSearchLocation(QDir::homePath().toStdString()); browser->addDLLSearchLocation(QDir::currentPath().toStdString()); browser->addDLLSearchLocation(fi.canonicalPath().toStdString()); browser->update(); auto dllList = browser->getLibraryInfos(); int id = 0; std::cout << std::endl << " --- Algorithm List --- " << std::endl; for (auto info : dllList) { std::cout << "Algorithm ID " << id << ": " << info->getAlgorithmUID().getName() << std::endl; ++id; } std::cout << std::endl << " --- Interpolation List --- " << std::endl; std::cout << "Interpolation ID 0: Linear Interpolation " << std::endl; std::cout << "Interpolation ID 1: Nearest Neighbour" << std::endl; std::cout << "Interpolation ID 2: BSpline 3D" << std::endl << std::endl; mitk::ImageMappingInterpolator::Type interpolationMode = mitk::ImageMappingInterpolator::Linear; if (parsedArgs.size()==0) return EXIT_FAILURE; // Show a help message if ( parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } std::string movingFile = us::any_cast(parsedArgs["moving"]); std::string fixedFile = us::any_cast(parsedArgs["fixed"]); int selectedAlgorithm = us::any_cast(parsedArgs["reader"]); std::string outputPath = us::any_cast(parsedArgs["output"]); if (parsedArgs.count("interpolation")) { switch (us::any_cast(parsedArgs["interpolation"])) { case 0: interpolationMode = mitk::ImageMappingInterpolator::Linear; break; case 1: interpolationMode = mitk::ImageMappingInterpolator::NearestNeighbor; break; case 2: interpolationMode = mitk::ImageMappingInterpolator::BSpline_3; break; default: interpolationMode = mitk::ImageMappingInterpolator::Linear; } } mitk::Image::Pointer movingImage = mitk::IOUtil::Load(movingFile); mitk::Image::Pointer fixedImage = mitk::IOUtil::Load(fixedFile); auto dllInfo = dllList[selectedAlgorithm]; if (!dllInfo) { MITK_ERROR << "No valid algorithm is selected. Cannot load algorithm. ABORTING."; return -1; } ::map::deployment::DLLHandle::Pointer tempDLLHandle = ::map::deployment::openDeploymentDLL( dllInfo->getLibraryFilePath()); ::map::algorithm::RegistrationAlgorithmBase::Pointer tempAlgorithm = ::map::deployment::getRegistrationAlgorithm(tempDLLHandle); MITK_INFO << "Well...."; if (tempAlgorithm.IsNull()) { MITK_ERROR << "Error. Cannot load selected algorithm."; return -2; } - mitk::MITKAlgorithmHelper helper(tempAlgorithm); + mitk::MAPAlgorithmHelper helper(tempAlgorithm); helper.SetData(movingImage, fixedImage); auto registration = helper.GetRegistration(); MITK_INFO << "Well...."; mitk::Image::Pointer spResultData= mitk::ImageMappingHelper::map(movingImage, registration, false, // Use all Pixels 0.0, // Padding Value fixedImage->GetGeometry()->Clone().GetPointer(), // Ref. Geometry false, //!(this->m_allowUnregPixels), 0, // Error Value interpolationMode // Interpolator Type ); MITK_INFO << "Well...."; mitk::IOUtil::Save(spResultData, outputPath); return EXIT_SUCCESS; } diff --git a/Modules/Core/include/mitkIdentifiable.h b/Modules/Core/include/mitkIdentifiable.h index cdaa18d2ff..9c2cef821f 100644 --- a/Modules/Core/include/mitkIdentifiable.h +++ b/Modules/Core/include/mitkIdentifiable.h @@ -1,77 +1,77 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkIdentifiable_h #define mitkIdentifiable_h #include #include namespace mitk { /** * \brief Base class of identifiable objects. * * Offers an interface to query a UID for the instance. Can be inherited * by other classes to provide this capability.\n\n * What does the UID stand for/what is its scope?\n * - It is unique in its creation, but it is not a content specific unique ID. Therfore: * - A class instance, associated with a UID, may change its values over its lifetime, but still have the same UID. - - If a class instance gets persistet and loaded multiple times, then theire could + - If a class instance gets persisted and loaded multiple times, then their could be several instances with the same UID. - UIDs are therefore more simelar to git paths than to git hashes. They identify something, but the state of something can change (stream of commits). The difference of the UID compared to using e.g. plain instance pointers to identify an object is that UIDs allow the feature of serialization as they abstract from the memory location of the current runtime environment. - It is up to the application that builds upon that feature to ensure appropriate usage within the application scope. * @remark It is not a feature of mitk::Identifiable per se to be persistable. It depends on classes that derive - * from mitk::Identifiable, if and how they implement a persistancy mechanism for their MITK UID. + * from mitk::Identifiable, if and how they implement a persistence mechanism for their MITK UID. * @remark If you want to change the unique ID after creation time, you can use * the mitk::UIDManipulator class. The reationale behind this pattern is * to ensure that you think twice before doing this. It is intended to be * used by data readers if necessary at all. */ class MITKCORE_EXPORT Identifiable { public: using UIDType = std::string; Identifiable(); explicit Identifiable(const UIDType &uid); Identifiable(const Identifiable &) = delete; Identifiable(Identifiable &&) noexcept; virtual ~Identifiable(); Identifiable & operator =(const Identifiable &) = delete; Identifiable & operator =(Identifiable &&other) noexcept; /** * \brief Get unique ID of an object. * * \return Empty string if an object has no unique ID. */ virtual UIDType GetUID() const; protected: virtual void SetUID(const UIDType& uid); private: friend class UIDManipulator; struct Impl; Impl *m_Impl; }; } #endif diff --git a/Modules/MatchPointRegistration/Helper/mitkAlgorithmHelper.cpp b/Modules/MatchPointRegistration/Helper/mitkMAPAlgorithmHelper.cpp similarity index 90% rename from Modules/MatchPointRegistration/Helper/mitkAlgorithmHelper.cpp rename to Modules/MatchPointRegistration/Helper/mitkMAPAlgorithmHelper.cpp index 8ccf235cc6..0b11df2dad 100644 --- a/Modules/MatchPointRegistration/Helper/mitkAlgorithmHelper.cpp +++ b/Modules/MatchPointRegistration/Helper/mitkMAPAlgorithmHelper.cpp @@ -1,408 +1,407 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ -#include "mitkAlgorithmHelper.h" +#include "mitkMAPAlgorithmHelper.h" //itk #include // Mitk #include #include // MatchPoint #include #include #include #include #include namespace mitk { - MITKAlgorithmHelper::MITKAlgorithmHelper(map::algorithm::RegistrationAlgorithmBase *algorithm) + MAPAlgorithmHelper::MAPAlgorithmHelper(map::algorithm::RegistrationAlgorithmBase *algorithm) : m_AlgorithmBase(algorithm), m_Error(CheckError::none) { m_AllowImageCasting = true; } - bool MITKAlgorithmHelper::HasImageAlgorithmInterface(const map::algorithm::RegistrationAlgorithmBase* algorithm) + bool MAPAlgorithmHelper::HasImageAlgorithmInterface(const map::algorithm::RegistrationAlgorithmBase* algorithm) { using InternalDefault2DImageType = itk::Image; using InternalDefault3DImageType = itk::Image; using Alg2DType = const ::map::algorithm::facet::ImageRegistrationAlgorithmInterface; if (dynamic_cast(algorithm) != nullptr) return true; using Alg3DType = const ::map::algorithm::facet::ImageRegistrationAlgorithmInterface; if (dynamic_cast(algorithm) != nullptr) return true; using Alg2D3DType = const ::map::algorithm::facet::ImageRegistrationAlgorithmInterface; if (dynamic_cast(algorithm) != nullptr) return true; using Alg3D2DType = const ::map::algorithm::facet::ImageRegistrationAlgorithmInterface; if (dynamic_cast(algorithm) != nullptr) return true; return false; - }; + } - bool MITKAlgorithmHelper::HasPointSetAlgorithmInterface(const map::algorithm::RegistrationAlgorithmBase* algorithm) + bool MAPAlgorithmHelper::HasPointSetAlgorithmInterface(const map::algorithm::RegistrationAlgorithmBase* algorithm) { typedef ::map::core::continuous::Elements<3>::InternalPointSetType InternalDefaultPointSetType; typedef const ::map::algorithm::facet::PointSetRegistrationAlgorithmInterface PointSetRegInterface; return dynamic_cast(algorithm) != nullptr; - }; + } map::core::RegistrationBase::Pointer - MITKAlgorithmHelper:: + MAPAlgorithmHelper:: GetRegistration() const { map::core::RegistrationBase::Pointer spResult; unsigned int movingDim = m_AlgorithmBase->getMovingDimensions(); unsigned int targetDim = m_AlgorithmBase->getTargetDimensions(); if (movingDim != targetDim) { mapDefaultExceptionStaticMacro( << - "Error, algorithm instance has unequal dimensionality and is therefore not supported in the current version of MITKAlgorithmHelper."); + "Error, algorithm instance has unequal dimensionality and is therefore not supported in the current version of MAPAlgorithmHelper."); } if (movingDim > 3) { mapDefaultExceptionStaticMacro( << - "Error, algorithm instance has a dimensionality larger than 3 and is therefore not supported in the current version of MITKAlgorithmHelper."); + "Error, algorithm instance has a dimensionality larger than 3 and is therefore not supported in the current version of MAPAlgorithmHelper."); } typedef ::map::algorithm::facet::RegistrationAlgorithmInterface<2, 2> RegistrationAlg2D2DInterface; typedef ::map::algorithm::facet::RegistrationAlgorithmInterface<3, 3> RegistrationAlg3D3DInterface; RegistrationAlg2D2DInterface* pRegAlgorithm2D2D = dynamic_cast (m_AlgorithmBase.GetPointer()); RegistrationAlg3D3DInterface* pRegAlgorithm3D3D = dynamic_cast (m_AlgorithmBase.GetPointer()); if (pRegAlgorithm2D2D) { spResult = pRegAlgorithm2D2D->getRegistration(); } if (pRegAlgorithm3D3D) { spResult = pRegAlgorithm3D3D->getRegistration(); } return spResult; } mitk::MAPRegistrationWrapper::Pointer - MITKAlgorithmHelper:: + MAPAlgorithmHelper:: GetMITKRegistrationWrapper() const { map::core::RegistrationBase::Pointer spInternalResult = GetRegistration(); mitk::MAPRegistrationWrapper::Pointer spResult = mitk::MAPRegistrationWrapper::New(spInternalResult); return spResult; - }; + } static const mitk::Image* GetDataAsImage(const mitk::BaseData* data) { return dynamic_cast(data); - }; + } static const mitk::PointSet* GetDataAsPointSet(const mitk::BaseData* data) { return dynamic_cast(data); - }; + } bool - MITKAlgorithmHelper:: + MAPAlgorithmHelper:: CheckData(const mitk::BaseData* moving, const mitk::BaseData* target, CheckError::Type& error) const { if (! m_AlgorithmBase) { mapDefaultExceptionStaticMacro( << "Error, cannot check data. Helper has no algorithm defined."); } if (! moving) { mapDefaultExceptionStaticMacro( << "Error, cannot check data. Moving data pointer is nullptr."); } if (! target) { mapDefaultExceptionStaticMacro( << "Error, cannot check data. Target data pointer is nullptr."); } bool result = false; m_Error = CheckError::unsupportedDataType; unsigned int movingDim = m_AlgorithmBase->getMovingDimensions(); unsigned int targetDim = m_AlgorithmBase->getTargetDimensions(); if (movingDim != targetDim) { m_Error = CheckError::wrongDimension; } else { //First check if data are point sets or images if (GetDataAsPointSet(target) && GetDataAsPointSet(moving)) { typedef ::map::core::continuous::Elements<3>::InternalPointSetType InternalDefaultPointSetType; typedef ::map::algorithm::facet::PointSetRegistrationAlgorithmInterface PointSetRegInterface; PointSetRegInterface* pPointSetInterface = dynamic_cast (m_AlgorithmBase.GetPointer()); if (!pPointSetInterface) { result = false; m_Error = CheckError::unsupportedDataType; } } else if (GetDataAsImage(moving) && GetDataAsImage(target)) { if (movingDim == 2) { AccessTwoImagesFixedDimensionByItk(GetDataAsImage(moving), GetDataAsImage(target), DoCheckImages, 2); } else if (movingDim == 3) { AccessTwoImagesFixedDimensionByItk(GetDataAsImage(moving), GetDataAsImage(target), DoCheckImages, 3); } else { m_Error = CheckError::wrongDimension; } if (m_Error == CheckError::none || (m_AllowImageCasting && m_Error == CheckError::onlyByCasting)) { result = true; } } } error = m_Error; return result; + } - }; - - void MITKAlgorithmHelper::SetAllowImageCasting(bool allowCasting) + void MAPAlgorithmHelper::SetAllowImageCasting(bool allowCasting) { this->m_AllowImageCasting = allowCasting; - }; + } - bool MITKAlgorithmHelper::GetAllowImageCasting() const + bool MAPAlgorithmHelper::GetAllowImageCasting() const { return this->m_AllowImageCasting; - }; + } - void MITKAlgorithmHelper::SetData(const mitk::BaseData* moving, const mitk::BaseData* target) + void MAPAlgorithmHelper::SetData(const mitk::BaseData* moving, const mitk::BaseData* target) { if (! m_AlgorithmBase) { mapDefaultExceptionStaticMacro( << "Error, cannot check data. Helper has no algorithm defined."); } if (! moving) { mapDefaultExceptionStaticMacro( << "Error, cannot check data. Moving data pointer is nullptr."); } if (! target) { mapDefaultExceptionStaticMacro( << "Error, cannot check data. Target data pointer is nullptr."); } unsigned int movingDim = m_AlgorithmBase->getMovingDimensions(); unsigned int targetDim = m_AlgorithmBase->getTargetDimensions(); if (movingDim != targetDim) { mapDefaultExceptionStaticMacro( << - "Error, cannot set data. Current version of MITKAlgorithmHelper only supports images/point sets with same dimensionality."); + "Error, cannot set data. Current version of MAPAlgorithmHelper only supports images/point sets with same dimensionality."); } if (GetDataAsPointSet(target) && GetDataAsPointSet(moving)) { typedef ::map::core::continuous::Elements<3>::InternalPointSetType InternalDefaultPointSetType; typedef ::map::algorithm::facet::PointSetRegistrationAlgorithmInterface PointSetRegInterface; PointSetRegInterface* pPointSetInterface = dynamic_cast (m_AlgorithmBase.GetPointer()); pPointSetInterface->setMovingPointSet(mitk::PointSetMappingHelper::ConvertPointSetMITKtoMAP( GetDataAsPointSet(moving)->GetPointSet())); pPointSetInterface->setTargetPointSet(mitk::PointSetMappingHelper::ConvertPointSetMITKtoMAP( GetDataAsPointSet(target)->GetPointSet())); } else if (GetDataAsImage(moving) && GetDataAsImage(target)) { if (movingDim == 2) { AccessTwoImagesFixedDimensionByItk(GetDataAsImage(moving), GetDataAsImage(target), DoSetImages, 2); } else if (movingDim == 3) { AccessTwoImagesFixedDimensionByItk(GetDataAsImage(moving), GetDataAsImage(target), DoSetImages, 3); } } - }; + } template - typename TOutImageType::Pointer MITKAlgorithmHelper::CastImage(const TInImageType* input) const + typename TOutImageType::Pointer MAPAlgorithmHelper::CastImage(const TInImageType* input) const { typedef itk::CastImageFilter< TInImageType, TOutImageType > CastFilterType; typename CastFilterType::Pointer spImageCaster = CastFilterType::New(); spImageCaster->SetInput(input); typename TOutImageType::Pointer spImage = spImageCaster->GetOutput(); spImageCaster->Update(); return spImage; } template - void MITKAlgorithmHelper::DoSetImages(const itk::Image* moving, + void MAPAlgorithmHelper::DoSetImages(const itk::Image* moving, const itk::Image* target) { typedef itk::Image MovingImageType; typedef itk::Image TargetImageType; typedef itk::Image InternalDefaultMovingImageType; typedef itk::Image InternalDefaultTargetImageType; typedef ::map::algorithm::facet::ImageRegistrationAlgorithmInterface ImageRegInterface; typedef ::map::algorithm::facet::ImageRegistrationAlgorithmInterface DefaultImageRegInterface; ImageRegInterface* pImageInterface = dynamic_cast(m_AlgorithmBase.GetPointer()); DefaultImageRegInterface* pDefaultImageInterface = dynamic_cast (m_AlgorithmBase.GetPointer()); if (pImageInterface) { //just set directly and you are done /**@todo the duplication work arround is needed due to a insufficuence in the AccessTwoImagesFixedDimensionByItk macro. The macro always cast the passed image into non const (even if tha image was passed as const). This behavior enforces the unnecessary use of an writeaccessor, which as a consequence will lead to redundant access exceptions as long as the algorithm exists; e.g. in the typical scenario with the MatchPoint Plugins*/ typedef itk::ImageDuplicator< MovingImageType > MovingDuplicatorType; typedef itk::ImageDuplicator< TargetImageType > TargetDuplicatorType; typename MovingDuplicatorType::Pointer mDuplicator = MovingDuplicatorType::New(); mDuplicator->SetInputImage(moving); mDuplicator->Update(); typename TargetDuplicatorType::Pointer tDuplicator = TargetDuplicatorType::New(); tDuplicator->SetInputImage(target); tDuplicator->Update(); typename MovingImageType::Pointer clonedMoving = mDuplicator->GetOutput(); typename TargetImageType::Pointer clonedTarget = tDuplicator->GetOutput(); pImageInterface->setTargetImage(clonedTarget); pImageInterface->setMovingImage(clonedMoving); } else if (pDefaultImageInterface) { //you may convert it to the default image type and use it then if (! m_AllowImageCasting) { mapDefaultExceptionStaticMacro( << - "Error, cannot set images. MITKAlgorithmHelper has to convert them into MatchPoint default images, but is not allowed. Please reconfigure helper."); + "Error, cannot set images. MAPAlgorithmHelper has to convert them into MatchPoint default images, but is not allowed. Please reconfigure helper."); } typename InternalDefaultTargetImageType::Pointer spCastedTarget = CastImage(target); typename InternalDefaultMovingImageType::Pointer spCastedMoving = CastImage(moving); pDefaultImageInterface->setTargetImage(spCastedTarget); pDefaultImageInterface->setMovingImage(spCastedMoving); } else { mapDefaultExceptionStaticMacro( << "Error, algorithm is not able to use the based images."); } } template - void MITKAlgorithmHelper::DoCheckImages(const itk::Image* /*moving*/, + void MAPAlgorithmHelper::DoCheckImages(const itk::Image* /*moving*/, const itk::Image* /*target*/) const { typedef itk::Image MovingImageType; typedef itk::Image TargetImageType; typedef itk::Image InternalDefaultMovingImageType; typedef itk::Image InternalDefaultTargetImageType; typedef ::map::algorithm::facet::ImageRegistrationAlgorithmInterface ImageRegInterface; typedef ::map::algorithm::facet::ImageRegistrationAlgorithmInterface DefaultImageRegInterface; ImageRegInterface* pImageInterface = dynamic_cast(m_AlgorithmBase.GetPointer()); DefaultImageRegInterface* pDefaultImageInterface = dynamic_cast (m_AlgorithmBase.GetPointer()); if (pImageInterface) { //just set directly and you are done m_Error = CheckError::none; } else if (pDefaultImageInterface) { //you may convert it to the default image type and use it then m_Error = CheckError::onlyByCasting; } else { m_Error = CheckError::unsupportedDataType; } } mapGenerateAlgorithmUIDPolicyMacro(DummyRegIDPolicy, "de.dkfz.dipp", "Identity", "1.0.0", ""); mitk::MAPRegistrationWrapper::Pointer GenerateIdentityRegistration3D() { typedef map::algorithm::DummyImageRegistrationAlgorithm::InternalImageType, map::core::discrete::Elements<3>::InternalImageType, DummyRegIDPolicy> DummyRegType; DummyRegType::Pointer regAlg = DummyRegType::New(); - mitk::MITKAlgorithmHelper helper(regAlg); + mitk::MAPAlgorithmHelper helper(regAlg); map::core::discrete::Elements<3>::InternalImageType::Pointer dummyImg = map::core::discrete::Elements<3>::InternalImageType::New(); dummyImg->Allocate(); regAlg->setTargetImage(dummyImg); regAlg->setMovingImage(dummyImg); - mitk::MAPRegistrationWrapper::Pointer dummyReg = mitk::MAPRegistrationWrapper::New(regAlg->getRegistration()); + auto dummyReg = mitk::MAPRegistrationWrapper::New(regAlg->getRegistration()); return dummyReg; } } diff --git a/Modules/MatchPointRegistration/Helper/mitkAlgorithmHelper.h b/Modules/MatchPointRegistration/Helper/mitkMAPAlgorithmHelper.h similarity index 89% rename from Modules/MatchPointRegistration/Helper/mitkAlgorithmHelper.h rename to Modules/MatchPointRegistration/Helper/mitkMAPAlgorithmHelper.h index 087c0b2425..70c42632f3 100644 --- a/Modules/MatchPointRegistration/Helper/mitkAlgorithmHelper.h +++ b/Modules/MatchPointRegistration/Helper/mitkMAPAlgorithmHelper.h @@ -1,107 +1,107 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ -#ifndef mitkAlgorithmHelper_h -#define mitkAlgorithmHelper_h +#ifndef mitkMAPAlgorithmHelper_h +#define mitkMAPAlgorithmHelper_h //MatchPoint #include "mapRegistrationAlgorithmBase.h" #include "mapRegistrationBase.h" //MITK #include #include //MITK #include "MitkMatchPointRegistrationExports.h" #include "mitkMAPRegistrationWrapper.h" namespace mitk { /*! - \brief MITKAlgorithmHelper + \brief MAPAlgorithmHelper \remark Current implementation is not thread-save. Just use one Helper class per registration task. \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. */ - class MITKMATCHPOINTREGISTRATION_EXPORT MITKAlgorithmHelper + class MITKMATCHPOINTREGISTRATION_EXPORT MAPAlgorithmHelper { public: - MITKAlgorithmHelper(map::algorithm::RegistrationAlgorithmBase* algorithm); + MAPAlgorithmHelper(map::algorithm::RegistrationAlgorithmBase* algorithm); void SetData(const mitk::BaseData* moving, const mitk::BaseData* target); void SetAllowImageCasting(bool allowCasting); bool GetAllowImageCasting() const; static bool HasImageAlgorithmInterface(const map::algorithm::RegistrationAlgorithmBase* algorithm); static bool HasPointSetAlgorithmInterface(const map::algorithm::RegistrationAlgorithmBase* algorithm); struct CheckError { enum Type { none = 0, onlyByCasting = 1, wrongDimension = 2, unsupportedDataType = 3 }; }; bool CheckData(const mitk::BaseData* moving, const mitk::BaseData* target, CheckError::Type& error) const; map::core::RegistrationBase::Pointer GetRegistration() const; mitk::MAPRegistrationWrapper::Pointer GetMITKRegistrationWrapper() const; - ~MITKAlgorithmHelper() {} + ~MAPAlgorithmHelper() {} private: - MITKAlgorithmHelper& operator = (const MITKAlgorithmHelper&); - MITKAlgorithmHelper(const MITKAlgorithmHelper&); + MAPAlgorithmHelper& operator = (const MAPAlgorithmHelper&); + MAPAlgorithmHelper(const MAPAlgorithmHelper&); /**Internal helper that casts itk images from one pixel type into an other (used by DoSetImages if the images have the right dimension but wrong type and AllowImageCasting is activated)*/ template typename TOutImageType::Pointer CastImage(const TInImageType* input) const; /**Internal helper that is used by SetData if the data are images to set them properly.*/ template void DoSetImages(const itk::Image* moving, const itk::Image* target); /**Internal helper that is used by SetData if the data are images to check if the image types are supported by the algorithm.*/ template void DoCheckImages(const itk::Image* moving, const itk::Image* target) const; map::algorithm::RegistrationAlgorithmBase::Pointer m_AlgorithmBase; bool m_AllowImageCasting; mutable CheckError::Type m_Error; }; /**Small helper function that generates Identity transforms in 3D.*/ mitk::MAPRegistrationWrapper::Pointer MITKMATCHPOINTREGISTRATION_EXPORT GenerateIdentityRegistration3D(); } #endif diff --git a/Modules/MatchPointRegistration/Helper/mitkTimeFramesRegistrationHelper.cpp b/Modules/MatchPointRegistration/Helper/mitkTimeFramesRegistrationHelper.cpp index 6c18fa1dc2..5950e7ba52 100644 --- a/Modules/MatchPointRegistration/Helper/mitkTimeFramesRegistrationHelper.cpp +++ b/Modules/MatchPointRegistration/Helper/mitkTimeFramesRegistrationHelper.cpp @@ -1,234 +1,234 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "itkCommand.h" #include "mitkTimeFramesRegistrationHelper.h" #include #include #include -#include +#include mitk::Image::Pointer mitk::TimeFramesRegistrationHelper::GetFrameImage(const mitk::Image* image, mitk::TimePointType timePoint) const { mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); imageTimeSelector->SetInput(image); imageTimeSelector->SetTimeNr(timePoint); imageTimeSelector->UpdateLargestPossibleRegion(); mitk::Image::Pointer frameImage = imageTimeSelector->GetOutput(); return frameImage; }; void mitk::TimeFramesRegistrationHelper::Generate() { CheckValidInputs(); //prepare processing mitk::Image::Pointer targetFrame = GetFrameImage(this->m_4DImage, 0); this->m_Registered4DImage = this->m_4DImage->Clone(); Image::ConstPointer mask; if (m_TargetMask.IsNotNull()) { if (m_TargetMask->GetTimeSteps() > 1) { mask = GetFrameImage(m_TargetMask, 0); } else { mask = m_TargetMask; } } double progressDelta = 1.0 / ((this->m_4DImage->GetTimeSteps() - 1) * 3.0); m_Progress = 0.0; //process the frames for (unsigned int i = 1; i < this->m_4DImage->GetTimeSteps(); ++i) { Image::Pointer movingFrame = GetFrameImage(this->m_4DImage, i); Image::Pointer mappedFrame; IgnoreListType::iterator finding = std::find(m_IgnoreList.begin(), m_IgnoreList.end(), i); if (finding == m_IgnoreList.end()) { //frame should be processed RegistrationPointer reg = DoFrameRegistration(movingFrame, targetFrame, mask); m_Progress += progressDelta; this->InvokeEvent(::mitk::FrameRegistrationEvent(nullptr, "Registred frame #" +::map::core::convert::toStr(i))); mappedFrame = DoFrameMapping(movingFrame, reg, targetFrame); m_Progress += progressDelta; this->InvokeEvent(::mitk::FrameMappingEvent(nullptr, "Mapped frame #" + ::map::core::convert::toStr(i))); mitk::ImageReadAccessor accessor(mappedFrame, mappedFrame->GetVolumeData(0, 0, nullptr, mitk::Image::ReferenceMemory)); this->m_Registered4DImage->SetVolume(accessor.GetData(), i); this->m_Registered4DImage->GetTimeGeometry()->SetTimeStepGeometry(mappedFrame->GetGeometry(), i); m_Progress += progressDelta; } else { m_Progress += 3 * progressDelta; } this->InvokeEvent(::itk::ProgressEvent()); } }; mitk::Image::Pointer mitk::TimeFramesRegistrationHelper::GetRegisteredImage() { if (this->HasOutdatedResult()) { Generate(); } return m_Registered4DImage; }; void mitk::TimeFramesRegistrationHelper:: SetIgnoreList(const IgnoreListType& il) { m_IgnoreList = il; this->Modified(); } void mitk::TimeFramesRegistrationHelper::ClearIgnoreList() { m_IgnoreList.clear(); this->Modified(); }; mitk::TimeFramesRegistrationHelper::RegistrationPointer mitk::TimeFramesRegistrationHelper::DoFrameRegistration(const mitk::Image* movingFrame, const mitk::Image* targetFrame, const mitk::Image* targetMask) const { - mitk::MITKAlgorithmHelper algHelper(m_Algorithm); + mitk::MAPAlgorithmHelper algHelper(m_Algorithm); algHelper.SetAllowImageCasting(true); algHelper.SetData(movingFrame, targetFrame); if (targetMask) { mitk::MaskedAlgorithmHelper maskHelper(m_Algorithm); maskHelper.SetMasks(nullptr, targetMask); } return algHelper.GetRegistration(); }; mitk::Image::Pointer mitk::TimeFramesRegistrationHelper::DoFrameMapping( const mitk::Image* movingFrame, const RegistrationType* reg, const mitk::Image* targetFrame) const { return mitk::ImageMappingHelper::map(movingFrame, reg, !m_AllowUndefPixels, m_PaddingValue, targetFrame->GetGeometry(), !m_AllowUnregPixels, m_ErrorValue, m_InterpolatorType); }; bool mitk::TimeFramesRegistrationHelper::HasOutdatedResult() const { if (m_Registered4DImage.IsNull()) { return true; } bool result = false; if (m_Registered4DImage->GetMTime() > this->GetMTime()) { result = true; } if (m_Algorithm.IsNotNull()) { if (m_Algorithm->GetMTime() > this->GetMTime()) { result = true; } } if (m_4DImage.IsNotNull()) { if (m_4DImage->GetMTime() > this->GetMTime()) { result = true; } } if (m_TargetMask.IsNotNull()) { if (m_TargetMask->GetMTime() > this->GetMTime()) { result = true; } } return result; }; void mitk::TimeFramesRegistrationHelper::CheckValidInputs() const { if (m_4DImage.IsNull()) { mitkThrow() << "Cannot register image. Input 4D image is not set."; } if (m_Algorithm.IsNull()) { mitkThrow() << "Cannot register image. Algorithm is not set."; } if (m_4DImage->GetTimeSteps() <= 1) { mitkThrow() << "Cannot register image. Input 4D image must have 2 or more time steps."; } for (IgnoreListType::const_iterator pos = this->m_IgnoreList.begin(); pos != this->m_IgnoreList.end(); ++pos) { if (*pos >= m_4DImage->GetTimeSteps()) { mitkThrow() << "Cannot register image. Ignore list containes at least one inexistant frame. Invalid frame index: " << *pos; } } }; double mitk::TimeFramesRegistrationHelper::GetProgress() const { return m_Progress; }; diff --git a/Modules/MatchPointRegistration/autoload/IO/mitkMAPRegistrationWrapperIO.cpp b/Modules/MatchPointRegistration/autoload/IO/mitkMAPRegistrationWrapperIO.cpp index db738b7a52..c5cf757609 100644 --- a/Modules/MatchPointRegistration/autoload/IO/mitkMAPRegistrationWrapperIO.cpp +++ b/Modules/MatchPointRegistration/autoload/IO/mitkMAPRegistrationWrapperIO.cpp @@ -1,279 +1,279 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include #include #include #include "mapRegistration.h" #include "mapRegistrationFileWriter.h" #include "mapRegistrationFileReader.h" #include "mapLazyFileFieldKernelLoader.h" #include #include #include #include "mitkMAPRegistrationWrapperIO.h" #include "mitkMAPRegistrationWrapper.h" namespace mitk { /** Helper class that allows to use an functor in multiple combinations of * moving and target dimensions on a passed MAPRegistrationWrapper instance.\n * DimHelperSub is used DimHelper to iterate in a row of the dimension * combination matrix. */ template< unsigned int i, unsigned int j, template < unsigned int, unsigned int> class TFunctor> class DimHelperSub { public: static bool Execute(const mitk::MAPRegistrationWrapper* obj, const map::core::String& data) { if (TFunctor::Execute(obj, data)) { return true; } return DimHelperSub::Execute(obj, data); } }; /** Specialized template version of DimSubHelper that indicates the end * of the row in the dimension combination matrix, thus does nothing. */ template< unsigned int i, template < unsigned int, unsigned int> class TFunctor> class DimHelperSub { public: static bool Execute(const mitk::MAPRegistrationWrapper*, const map::core::String&) { //just unwind. Go to the next "row" with DimHelper return false; } }; /** Helper class that allows to use an functor in multiple combinations of * moving and target dimensions on a passed MAPRegistrationWrapper instance.\n * It is helpful if you want to ensure that all combinations are checked/touched * (e.g. 3D 3D, 3D 2D, 2D 3D, 2D 2D) without generating a large switch yard. * Think of n*m matrix (indicating the posible combinations). DimHelper walks from * one row to the next and uses DimHelperSub to iterate in a row.\n * For every element of the matrix the functor is executed on the passed object. */ template< unsigned int i, unsigned int j, template < unsigned int, unsigned int> class TFunctor> class DimHelper{ public: static bool Execute(const mitk::MAPRegistrationWrapper* obj, const map::core::String& data = "") { if (DimHelperSub::Execute(obj, data)) { return true; } return DimHelper::Execute(obj, data); } }; /** Specialized template version of DimHelper that indicates the end * of the dimension combination matrix, thus does nothing. */ template< unsigned int j, template < unsigned int, unsigned int> class TFunctor> class DimHelper<1,j, TFunctor > { public: static bool Execute(const mitk::MAPRegistrationWrapper*, const map::core::String&) { //just unwind. We are done. return false; } }; /** Functor that checks of the dimension of the registration is supported and can * be written. */ template class CanWrite { public: static bool Execute(const mitk::MAPRegistrationWrapper* obj, const map::core::String& = "") { bool result = false; result = dynamic_cast *>(obj->GetRegistration()) != nullptr; return result; } }; /** Functor that writes the registration to a file if it has the right dimensionality. */ template class WriteReg { public: static bool Execute(const mitk::MAPRegistrationWrapper* obj, const map::core::String& data) { const map::core::Registration* pReg = dynamic_cast*>(obj->GetRegistration()); if (pReg == nullptr) { return false; } typedef map::io::RegistrationFileWriter WriterType; typename WriterType::Pointer writer = WriterType::New(); writer->setExpandLazyKernels(false); try { writer->write(pReg,data); } catch (const itk::ExceptionObject& e) { std::cout << e.what() << std::endl; throw; } return true; } }; MAPRegistrationWrapperIO::MAPRegistrationWrapperIO(const MAPRegistrationWrapperIO& other) : AbstractFileIO(other) { } MAPRegistrationWrapperIO::MAPRegistrationWrapperIO() : AbstractFileIO(mitk::MAPRegistrationWrapper::GetStaticNameOfClass()) { std::string category = "MatchPoint Registration File"; CustomMimeType customMimeType; customMimeType.SetCategory(category); customMimeType.AddExtension("mapr"); this->AbstractFileIOWriter::SetMimeType(customMimeType); this->AbstractFileIOWriter::SetDescription(category); customMimeType.AddExtension("mapr.xml"); customMimeType.AddExtension("MAPR"); customMimeType.AddExtension("MAPR.XML"); this->AbstractFileIOReader::SetMimeType(customMimeType); this->AbstractFileIOReader::SetDescription(category); this->RegisterService(); } void MAPRegistrationWrapperIO::Write() { bool success = false; const BaseData* input = this->GetInput(); if (input == nullptr) { mitkThrow() << "Cannot write data. Data pointer is nullptr."; } const mitk::MAPRegistrationWrapper* wrapper = dynamic_cast(input); if (wrapper == nullptr) { mitkThrow() << "Cannot write data. Data pointer is not a Registration wrapper."; } std::ostream* writeStream = this->GetOutputStream(); std::string fileName = this->GetOutputLocation(); if (writeStream) { fileName = this->GetLocalFileName(); } // Switch the current locale to "C" LocaleSwitch localeSwitch("C"); try { success = DimHelper<3,3,WriteReg>::Execute(wrapper, fileName); } catch (const std::exception& e) { mitkThrow() << e.what(); } if (!success) { mitkThrow() << "Cannot write registration. Currently only registrations up to 4D are supported."; } } AbstractFileIO::ConfidenceLevel MAPRegistrationWrapperIO::GetWriterConfidenceLevel() const { const mitk::MAPRegistrationWrapper* regWrapper = dynamic_cast(this->GetInput()); if (regWrapper == nullptr) { return IFileWriter::Unsupported; } // Check if the registration dimension is supported if (! DimHelper<3,3,CanWrite>::Execute(regWrapper)) { return IFileWriter::Unsupported; }; return IFileWriter::Supported; } std::vector MAPRegistrationWrapperIO::DoRead() { std::vector result; LocaleSwitch("C"); std::string fileName = this->GetLocalFileName(); if ( fileName.empty() ) { mitkThrow() << "Cannot read file. Filename has not been set!"; } /* Remove the following kernel loader provider because in MITK no lazy file loading should be used due to conflicts with session loading (end there usage of temporary directories)*/ map::io::RegistrationFileReader::LoaderStackType::unregisterProvider(map::io::LazyFileFieldKernelLoader<2,2>::getStaticProviderName()); map::io::RegistrationFileReader::LoaderStackType::unregisterProvider(map::io::LazyFileFieldKernelLoader<3,3>::getStaticProviderName()); map::io::RegistrationFileReader::Pointer spReader = map::io::RegistrationFileReader::New(); spReader->setPreferLazyLoading(true); map::core::RegistrationBase::Pointer spReg = spReader->read(fileName); - mitk::MAPRegistrationWrapper::Pointer spRegWrapper = mitk::MAPRegistrationWrapper::New(spReg); + auto spRegWrapper = mitk::MAPRegistrationWrapper::New(spReg); result.push_back(spRegWrapper.GetPointer()); return result; } AbstractFileIO::ConfidenceLevel MAPRegistrationWrapperIO::GetReaderConfidenceLevel() const { AbstractFileIO::ConfidenceLevel result = IFileReader::Unsupported; std::string fileName = this->GetLocalFileName(); std::ifstream in( fileName.c_str() ); if ( in.good() ) { result = IFileReader::Supported; } in.close(); return result; } MAPRegistrationWrapperIO* MAPRegistrationWrapperIO::IOClone() const { return new MAPRegistrationWrapperIO(*this); } } diff --git a/Modules/MatchPointRegistration/files.cmake b/Modules/MatchPointRegistration/files.cmake index 8546d7de97..1b9c8ff7e1 100644 --- a/Modules/MatchPointRegistration/files.cmake +++ b/Modules/MatchPointRegistration/files.cmake @@ -1,65 +1,65 @@ set(CPP_FILES mitkMAPRegistrationWrapper.cpp mitkMAPRegistrationWrapperObjectFactory.cpp mitkRegEvaluationObjectFactory.cpp mitkRegEvaluationObject.cpp Helper/mitkUIDHelper.cpp - Helper/mitkAlgorithmHelper.cpp + Helper/mitkMAPAlgorithmHelper.cpp Helper/mitkMaskedAlgorithmHelper.cpp Helper/mitkRegistrationHelper.cpp Helper/mitkImageMappingHelper.cpp Helper/mitkPointSetMappingHelper.cpp Helper/mitkResultNodeGenerationHelper.cpp Helper/mitkTimeFramesRegistrationHelper.cpp Rendering/mitkRegistrationWrapperMapper2D.cpp Rendering/mitkRegistrationWrapperMapper3D.cpp Rendering/mitkRegistrationWrapperMapperBase.cpp Rendering/mitkRegEvaluationMapper2D.cpp Rendering/mitkRegVisStyleProperty.cpp Rendering/mitkRegVisDirectionProperty.cpp Rendering/mitkRegVisColorStyleProperty.cpp Rendering/mitkRegVisPropertyTags.cpp Rendering/mitkRegVisHelper.cpp Rendering/mitkRegEvalStyleProperty.cpp Rendering/mitkRegEvalWipeStyleProperty.cpp ) set(H_FILES mitkMatchPointPropertyTags.h mitkMAPRegistrationWrapper.h mitkMAPRegistrationWrapperObjectFactory.h mitkRegEvaluationObjectFactory.h mitkRegEvaluationObject.h algorithms/mitkMultiModalAffineDefaultRegistrationAlgorithm.h algorithms/mitkMultiModalRigidDefaultRegistrationAlgorithm.h algorithms/mitkMultiModalTransDefaultRegistrationAlgorithm.h algorithms/mitkFastSymmetricForcesDemonsMultiResDefaultRegistrationAlgorithm.h algorithms/mitkLevelSetMotionMultiResDefaultRegistrationAlgorithm.h algorithms/mitkRigidClosedFormPointsDefaultRegistrationAlgorithm.h algorithms/mitkRigidICPDefaultRegistrationAlgorithm.h Helper/mitkUIDHelper.h - Helper/mitkAlgorithmHelper.h + Helper/mitkMAPAlgorithmHelper.h Helper/mitkMaskedAlgorithmHelper.h Helper/mitkRegistrationHelper.h Helper/mitkImageMappingHelper.h Helper/mitkPointSetMappingHelper.h Helper/mitkResultNodeGenerationHelper.h Helper/mitkTimeFramesRegistrationHelper.h Rendering/mitkRegistrationWrapperMapper2D.h Rendering/mitkRegistrationWrapperMapper3D.h Rendering/mitkRegistrationWrapperMapperBase.h Rendering/mitkRegVisStyleProperty.h Rendering/mitkRegVisDirectionProperty.h Rendering/mitkRegVisColorStyleProperty.h Rendering/mitkRegVisPropertyTags.h Rendering/mitkRegVisHelper.h Rendering/mitkRegEvaluationMapper2D.h Rendering/mitkRegEvalStyleProperty.h Rendering/mitkRegEvalWipeStyleProperty.h ) set(TPP_FILES ) set(MOC_H_FILES ) diff --git a/Modules/MatchPointRegistrationUI/Qmitk/QmitkRegistrationJob.cpp b/Modules/MatchPointRegistrationUI/Qmitk/QmitkRegistrationJob.cpp index 359c07802e..76197de9b9 100644 --- a/Modules/MatchPointRegistrationUI/Qmitk/QmitkRegistrationJob.cpp +++ b/Modules/MatchPointRegistrationUI/Qmitk/QmitkRegistrationJob.cpp @@ -1,200 +1,200 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkRegistrationJob.h" // Mitk -#include +#include #include #include #include #include #include #include // Qt #include // MatchPoint #include #include #include #include #include const mitk::Image *QmitkRegistrationJob::GetTargetDataAsImage() const { return dynamic_cast(m_spTargetData.GetPointer()); -}; +} const mitk::Image *QmitkRegistrationJob::GetMovingDataAsImage() const { return dynamic_cast(m_spMovingData.GetPointer()); -}; +} const map::algorithm::RegistrationAlgorithmBase *QmitkRegistrationJob::GetLoadedAlgorithm() const { return m_spLoadedAlgorithm; -}; +} void QmitkRegistrationJob::OnMapAlgorithmEvent(::itk::Object *, const itk::EventObject &event) { const map::events::AlgorithmEvent *pAlgEvent = dynamic_cast(&event); const map::events::AlgorithmIterationEvent *pIterationEvent = dynamic_cast(&event); const map::events::AlgorithmWrapperEvent *pWrapEvent = dynamic_cast(&event); const map::events::AlgorithmResolutionLevelEvent *pLevelEvent = dynamic_cast(&event); const map::events::InitializingAlgorithmEvent *pInitEvent = dynamic_cast(&event); const map::events::StartingAlgorithmEvent *pStartEvent = dynamic_cast(&event); const map::events::StoppingAlgorithmEvent *pStoppingEvent = dynamic_cast(&event); const map::events::StoppedAlgorithmEvent *pStoppedEvent = dynamic_cast(&event); const map::events::FinalizingAlgorithmEvent *pFinalizingEvent = dynamic_cast(&event); const map::events::FinalizedAlgorithmEvent *pFinalizedEvent = dynamic_cast(&event); if (pInitEvent) { emit AlgorithmStatusChanged(QString("Initializing algorithm ...")); } else if (pStartEvent) { emit AlgorithmStatusChanged(QString("Starting algorithm ...")); } else if (pStoppingEvent) { emit AlgorithmStatusChanged(QString("Stopping algorithm ...")); } else if (pStoppedEvent) { emit AlgorithmStatusChanged(QString("Stopped algorithm ...")); if (!pStoppedEvent->getComment().empty()) { emit AlgorithmInfo(QString("Stopping condition: ") + QString::fromStdString(pStoppedEvent->getComment())); } } else if (pFinalizingEvent) { emit AlgorithmStatusChanged(QString("Finalizing algorithm and results ...")); } else if (pFinalizedEvent) { emit AlgorithmStatusChanged(QString("Finalized algorithm ...")); } else if (pIterationEvent) { const IIterativeAlgorithm *pIterative = dynamic_cast(this->m_spLoadedAlgorithm.GetPointer()); map::algorithm::facet::IterativeAlgorithmInterface::IterationCountType count = 0; bool hasCount = false; if (pIterative && pIterative->hasIterationCount()) { hasCount = true; count = pIterative->getCurrentIteration(); } emit AlgorithmIterated(QString::fromStdString(pIterationEvent->getComment()), hasCount, count); } else if (pLevelEvent) { const IMultiResAlgorithm *pResAlg = dynamic_cast(this->m_spLoadedAlgorithm.GetPointer()); map::algorithm::facet::MultiResRegistrationAlgorithmInterface::ResolutionLevelCountType count = 0; bool hasCount = false; QString info = QString::fromStdString(pLevelEvent->getComment()); if (pResAlg && pResAlg->hasLevelCount()) { count = pResAlg->getCurrentLevel() + 1; hasCount = true; info = QString("Level #") + QString::number(pResAlg->getCurrentLevel() + 1) + QString(" ") + info; } emit LevelChanged(info, hasCount, count); } else if (pAlgEvent && !pWrapEvent) { emit AlgorithmInfo(QString::fromStdString(pAlgEvent->getComment())); } } QmitkRegistrationJob::QmitkRegistrationJob(map::algorithm::RegistrationAlgorithmBase *pAlgorithm) { m_MapEntity = false; m_StoreReg = false; m_ErrorOccured = false; m_spLoadedAlgorithm = pAlgorithm; m_JobName = "Unnamed RegJob"; m_MovingDataUID = "Missing moving UID"; m_TargetDataUID = "Missing target UID"; m_spTargetMask = nullptr; m_spMovingMask = nullptr; m_spCommand = ::itk::MemberCommand::New(); m_spCommand->SetCallbackFunction(this, &QmitkRegistrationJob::OnMapAlgorithmEvent); m_ObserverID = m_spLoadedAlgorithm->AddObserver(::map::events::AlgorithmEvent(), m_spCommand); -}; +} QmitkRegistrationJob::~QmitkRegistrationJob() { m_spLoadedAlgorithm->RemoveObserver(m_ObserverID); -}; +} void QmitkRegistrationJob::run() { try { - mitk::MITKAlgorithmHelper helper(m_spLoadedAlgorithm); + mitk::MAPAlgorithmHelper helper(m_spLoadedAlgorithm); mitk::MaskedAlgorithmHelper maskedHelper(m_spLoadedAlgorithm); //*@TODO Data Check and failure handle helper.SetData(this->m_spMovingData, this->m_spTargetData); maskedHelper.SetMasks(this->m_spMovingMask, this->m_spTargetMask); // perform registration m_spResultRegistration = helper.GetRegistration(); // wrap the registration in a data node if (m_spResultRegistration.IsNull()) { emit Error(QString("Error. No registration was determined. No results to store.")); } else { - mitk::MAPRegistrationWrapper::Pointer spRegWrapper = mitk::MAPRegistrationWrapper::New(m_spResultRegistration); + auto spRegWrapper = mitk::MAPRegistrationWrapper::New(m_spResultRegistration); emit RegResultIsAvailable(spRegWrapper, this); } } catch (::std::exception &e) { emit Error(QString("Error while registering data. Details: ") + QString::fromLatin1(e.what())); } catch (...) { emit Error(QString("Unkown error when registering data.")); } emit Finished(); -}; +} diff --git a/Modules/SceneSerialization/src/mitkSceneReaderV1.cpp b/Modules/SceneSerialization/src/mitkSceneReaderV1.cpp index 5e805685ff..5f349a4d22 100644 --- a/Modules/SceneSerialization/src/mitkSceneReaderV1.cpp +++ b/Modules/SceneSerialization/src/mitkSceneReaderV1.cpp @@ -1,429 +1,429 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkSceneReaderV1.h" #include "Poco/Path.h" #include "mitkBaseRenderer.h" #include "mitkIOUtil.h" #include "mitkProgressBar.h" #include "mitkPropertyListDeserializer.h" #include "mitkSerializerMacros.h" -#include "mitkUIDManipulator.h" +#include #include MITK_REGISTER_SERIALIZER(SceneReaderV1) namespace { typedef std::pair> NodesAndParentsPair; bool NodeSortByLayerIsLessThan(const NodesAndParentsPair &left, const NodesAndParentsPair &right) { if (left.first.IsNotNull() && right.first.IsNotNull()) { int leftLayer; int rightLayer; if (left.first->GetIntProperty("layer", leftLayer) && right.first->GetIntProperty("layer", rightLayer)) { return leftLayer < rightLayer; } else { // fall back to name sort return left.first->GetName() < right.first->GetName(); } } // in all other cases, fall back to stupid pointer comparison // this is not reasonable but at least answers the sorting // question clearly return left.first.GetPointer() < right.first.GetPointer(); } } bool mitk::SceneReaderV1::LoadScene(TiXmlDocument &document, const std::string &workingDirectory, DataStorage *storage) { assert(storage); bool error(false); // TODO prepare to detect errors (such as cycles) from wrongly written or edited xml files // Get number of elements to initialze progress bar // 1. if there is a element, // - construct a name for the appropriate serializer // - try to instantiate this serializer via itk object factory // - if serializer could be created, use it to read the file into a BaseData object // - if successful, call the new node's SetData(..) // create a node for the tag "data" and test if node was created typedef std::vector DataNodeVector; DataNodeVector DataNodes; unsigned int listSize = 0; for (TiXmlElement *element = document.FirstChildElement("node"); element != nullptr; element = element->NextSiblingElement("node")) { ++listSize; } ProgressBar::GetInstance()->AddStepsToDo(listSize * 2); for (TiXmlElement *element = document.FirstChildElement("node"); element != nullptr; element = element->NextSiblingElement("node")) { DataNodes.push_back(LoadBaseDataFromDataTag(element->FirstChildElement("data"), workingDirectory, error)); ProgressBar::GetInstance()->Progress(); } // iterate all nodes // first level nodes should be elements auto nit = DataNodes.begin(); for (TiXmlElement *element = document.FirstChildElement("node"); element != nullptr || nit != DataNodes.end(); element = element->NextSiblingElement("node"), ++nit) { mitk::DataNode::Pointer node = *nit; // in case dataXmlElement is valid test whether it containts the "properties" child tag // and process further if and only if yes TiXmlElement *dataXmlElement = element->FirstChildElement("data"); if (dataXmlElement && dataXmlElement->FirstChildElement("properties")) { TiXmlElement *baseDataElement = dataXmlElement->FirstChildElement("properties"); if (node->GetData()) { DecorateBaseDataWithProperties(node->GetData(), baseDataElement, workingDirectory); } else { MITK_WARN << "BaseData properties stored in scene file, but BaseData could not be read" << std::endl; } } // 2. check child nodes const char *uida = element->Attribute("UID"); std::string uid(""); if (uida) { uid = uida; m_NodeForID[uid] = node.GetPointer(); m_IDForNode[node.GetPointer()] = uid; } else { MITK_ERROR << "No UID found for current node. Node will have no parents."; error = true; } // 3. if there are nodes, // - instantiate the appropriate PropertyListDeSerializer // - use them to construct PropertyList objects // - add these properties to the node (if necessary, use renderwindow name) bool success = DecorateNodeWithProperties(node, element, workingDirectory); if (!success) { MITK_ERROR << "Could not load properties for node."; error = true; } // remember node for later adding to DataStorage m_OrderedNodePairs.push_back(std::make_pair(node, std::list())); // 4. if there are elements, remember parent objects for (TiXmlElement *source = element->FirstChildElement("source"); source != nullptr; source = source->NextSiblingElement("source")) { const char *sourceUID = source->Attribute("UID"); if (sourceUID) { m_OrderedNodePairs.back().second.push_back(std::string(sourceUID)); } } ProgressBar::GetInstance()->Progress(); } // end for all // sort our nodes by their "layer" property // (to be inserted in that order) m_OrderedNodePairs.sort(&NodeSortByLayerIsLessThan); // remove all unknown parent UIDs for (auto nodesIter = m_OrderedNodePairs.begin(); nodesIter != m_OrderedNodePairs.end(); ++nodesIter) { for (auto parentsIter = nodesIter->second.begin(); parentsIter != nodesIter->second.end();) { if (m_NodeForID.find(*parentsIter) == m_NodeForID.end()) { parentsIter = nodesIter->second.erase(parentsIter); MITK_WARN << "Found a DataNode with unknown parents. Will add it to DataStorage without any parent objects."; error = true; } else { ++parentsIter; } } } // repeat the following loop ... // ... for all created nodes unsigned int lastMapSize(0); while (lastMapSize != m_OrderedNodePairs .size()) // this is to prevent infinite loops; each iteration must at least add one node to DataStorage { lastMapSize = m_OrderedNodePairs.size(); // iterate (layer) ordered nodes backwards // we insert the highest layers first for (auto nodesIter = m_OrderedNodePairs.begin(); nodesIter != m_OrderedNodePairs.end(); ++nodesIter) { bool addThisNode(true); // if any parent node is not yet in DataStorage, skip node for now and check later for (auto parentsIter = nodesIter->second.begin(); parentsIter != nodesIter->second.end(); ++parentsIter) { if (!storage->Exists(m_NodeForID[*parentsIter])) { addThisNode = false; break; } } if (addThisNode) { DataStorage::SetOfObjects::Pointer parents = DataStorage::SetOfObjects::New(); for (auto parentsIter = nodesIter->second.begin(); parentsIter != nodesIter->second.end(); ++parentsIter) { parents->push_back(m_NodeForID[*parentsIter]); } // if all parents are found in datastorage (or are unknown), add node to DataStorage storage->Add(nodesIter->first, parents); // remove this node from m_OrderedNodePairs m_OrderedNodePairs.erase(nodesIter); // break this for loop because iterators are probably invalid break; } } } // All nodes that are still in m_OrderedNodePairs at this point are not part of a proper directed graph structure. // We'll add such nodes without any parent information. for (auto nodesIter = m_OrderedNodePairs.begin(); nodesIter != m_OrderedNodePairs.end(); ++nodesIter) { storage->Add(nodesIter->first); MITK_WARN << "Encountered node that is not part of a directed graph structure. Will be added to DataStorage " "without parents."; error = true; } return !error; } mitk::DataNode::Pointer mitk::SceneReaderV1::LoadBaseDataFromDataTag(TiXmlElement *dataElement, const std::string &workingDirectory, bool &error) { DataNode::Pointer node; if (dataElement) { const char *filename = dataElement->Attribute("file"); if (filename && strlen(filename) != 0) { try { std::vector baseData = IOUtil::Load(workingDirectory + Poco::Path::separator() + filename); if (baseData.size() > 1) { MITK_WARN << "Discarding multiple base data results from " << filename << " except the first one."; } node = DataNode::New(); node->SetData(baseData.front()); } catch (std::exception &e) { MITK_ERROR << "Error during attempt to read '" << filename << "'. Exception says: " << e.what(); error = true; } if (node.IsNull()) { MITK_ERROR << "Error during attempt to read '" << filename << "'. Factory returned nullptr object."; error = true; } } const char* dataUID = dataElement->Attribute("UID"); - if (!error && dataUID && strlen(dataUID) != 0) + if (!error && nullptr != dataUID && 0 != strlen(dataUID)) { UIDManipulator manip(node->GetData()); manip.SetUID(dataUID); } } // in case there was no element we create a new empty node (for appending a propertylist later) if (node.IsNull()) { node = DataNode::New(); } return node; } void mitk::SceneReaderV1::ClearNodePropertyListWithExceptions(DataNode &node, PropertyList &propertyList) { // Basically call propertyList.Clear(), but implement exceptions (see bug 19354) BaseData *data = node.GetData(); PropertyList::Pointer propertiesToKeep = PropertyList::New(); if (dynamic_cast(data)) { /* Older scene files (before changes of bug 17547) could contain a RenderingMode property with value "LevelWindow_Color". Since bug 17547 this value has been removed and replaced by the default value LookupTable_LevelWindow_Color. This new default value does only result in "black-to-white" CT images (or others) if there is a corresponding lookup table. Such a lookup table is provided as a default value by the Image mapper. Since that value was never present in older scene files, we do well in not removing the new default value here. Otherwise the mapper would fall back to another default which is all the colors of the rainbow :-( */ BaseProperty::Pointer lutProperty = propertyList.GetProperty("LookupTable"); propertiesToKeep->SetProperty("LookupTable", lutProperty); /* Older scene files (before changes of T14807) may contain multi-component images without the "Image.Displayed Component" property. As the treatment as multi-component image and the corresponding visualization options hinges on that property we should not delete it, if it was added by the mapper. This is a fix for the issue reported in T19919. */ BaseProperty::Pointer compProperty = propertyList.GetProperty("Image.Displayed Component"); if (compProperty.IsNotNull()) { propertiesToKeep->SetProperty("Image.Displayed Component", compProperty); } } propertyList.Clear(); propertyList.ConcatenatePropertyList(propertiesToKeep); } bool mitk::SceneReaderV1::DecorateNodeWithProperties(DataNode *node, TiXmlElement *nodeElement, const std::string &workingDirectory) { assert(node); assert(nodeElement); bool error(false); for (TiXmlElement *properties = nodeElement->FirstChildElement("properties"); properties != nullptr; properties = properties->NextSiblingElement("properties")) { const char *propertiesfilea(properties->Attribute("file")); std::string propertiesfile(propertiesfilea ? propertiesfilea : ""); const char *renderwindowa(properties->Attribute("renderwindow")); std::string renderwindow(renderwindowa ? renderwindowa : ""); PropertyList::Pointer propertyList = node->GetPropertyList(renderwindow); // DataNode implementation always returns a propertylist ClearNodePropertyListWithExceptions(*node, *propertyList); // use deserializer to construct new properties PropertyListDeserializer::Pointer deserializer = PropertyListDeserializer::New(); deserializer->SetFilename(workingDirectory + Poco::Path::separator() + propertiesfile); bool success = deserializer->Deserialize(); error |= !success; PropertyList::Pointer readProperties = deserializer->GetOutput(); if (readProperties.IsNotNull()) { propertyList->ConcatenatePropertyList(readProperties, true); // true = replace } else { MITK_ERROR << "Property list reader did not return a property list. This is an implementation error. Please tell " "your developer."; error = true; } } return !error; } bool mitk::SceneReaderV1::DecorateBaseDataWithProperties(BaseData::Pointer data, TiXmlElement *baseDataNodeElem, const std::string &workingDir) { // check given variables, initialize error variable assert(baseDataNodeElem); bool error(false); // get the file name stored in the tag const char *baseDataPropertyFile(baseDataNodeElem->Attribute("file")); // check if the filename was found if (baseDataPropertyFile) { // PropertyList::Pointer dataPropList = data->GetPropertyList(); PropertyListDeserializer::Pointer propertyDeserializer = PropertyListDeserializer::New(); // initialize the property reader propertyDeserializer->SetFilename(workingDir + Poco::Path::separator() + baseDataPropertyFile); bool ioSuccess = propertyDeserializer->Deserialize(); error = !ioSuccess; // get the output PropertyList::Pointer inProperties = propertyDeserializer->GetOutput(); // store the read-in properties to the given node or throw error otherwise if (inProperties.IsNotNull()) { data->SetPropertyList(inProperties); } else { MITK_ERROR << "The property deserializer did not return a (valid) property list."; error = true; } } else { MITK_ERROR << "Function DecorateBaseDataWithProperties(...) called with false TiXmlElement. \n \t ->Given element " "does not contain a 'file' attribute. \n"; error = true; } return !error; } diff --git a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/QmitkMatchPoint.cpp b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/QmitkMatchPoint.cpp index 990ecb068b..637b5db3b3 100644 --- a/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/QmitkMatchPoint.cpp +++ b/Plugins/org.mitk.gui.qt.matchpoint.algorithm.control/src/internal/QmitkMatchPoint.cpp @@ -1,867 +1,867 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "org_mitk_gui_qt_matchpoint_algorithmcontrol_Activator.h" // Blueberry #include #include #include #include // Mitk #include #include #include #include #include -#include +#include #include #include #include #include #include #include // Qmitk #include "QmitkMatchPoint.h" #include #include // Qt #include #include #include #include #include // MatchPoint #include #include #include #include #include #include #include #include #include const std::string QmitkMatchPoint::VIEW_ID = "org.mitk.views.matchpoint.algorithm.control"; QmitkMatchPoint::QmitkMatchPoint() : m_Parent(nullptr), m_LoadedDLLHandle(nullptr), m_LoadedAlgorithm(nullptr) { m_CanLoadAlgorithm = false; m_ValidInputs = false; m_Working = false; m_spSelectedTargetData = nullptr; m_spSelectedMovingData = nullptr; m_spSelectedTargetMaskData = nullptr; m_spSelectedMovingMaskData = nullptr; } QmitkMatchPoint::~QmitkMatchPoint() { // remove selection service berry::ISelectionService* s = this->GetSite()->GetWorkbenchWindow()->GetSelectionService(); if (s) { s->RemoveSelectionListener(m_AlgorithmSelectionListener.data()); } } void QmitkMatchPoint::SetFocus() { } void QmitkMatchPoint::CreateConnections() { connect(m_Controls.targetNodeSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkMatchPoint::OnNodeSelectionChanged); connect(m_Controls.movingNodeSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkMatchPoint::OnNodeSelectionChanged); connect(m_Controls.targetMaskNodeSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkMatchPoint::OnNodeSelectionChanged); connect(m_Controls.movingMaskNodeSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkMatchPoint::OnNodeSelectionChanged); // ------ // Tab 1 - Shared library loading interface // ------ connect(m_Controls.m_pbLoadSelected, SIGNAL(clicked()), this, SLOT(OnLoadAlgorithmButtonPushed())); // ----- // Tab 2 - Execution // ----- connect(m_Controls.m_pbStartReg, SIGNAL(clicked()), this, SLOT(OnStartRegBtnPushed())); connect(m_Controls.m_pbStopReg, SIGNAL(clicked()), this, SLOT(OnStopRegBtnPushed())); connect(m_Controls.m_pbSaveLog, SIGNAL(clicked()), this, SLOT(OnSaveLogBtnPushed())); } const map::deployment::DLLInfo* QmitkMatchPoint::GetSelectedAlgorithmDLL() const { return m_SelectedAlgorithmInfo; } void QmitkMatchPoint::OnSelectedAlgorithmChanged() { std::stringstream descriptionString; ::map::deployment::DLLInfo::ConstPointer currentItemInfo = GetSelectedAlgorithmDLL(); if (!currentItemInfo) { Error(QStringLiteral("No valid algorithm is selected. ABORTING.")); return; } m_Controls.m_teAlgorithmDetails->updateInfo(currentItemInfo); m_Controls.m_lbSelectedAlgorithm->setText(QString::fromStdString( currentItemInfo->getAlgorithmUID().getName())); // enable loading m_CanLoadAlgorithm = true; this->AdaptFolderGUIElements(); } void QmitkMatchPoint::OnLoadAlgorithmButtonPushed() { map::deployment::DLLInfo::ConstPointer dllInfo = GetSelectedAlgorithmDLL(); if (!dllInfo) { Error(QStringLiteral("No valid algorithm is selected. Cannot load algorithm. ABORTING.")); return; } ::map::deployment::DLLHandle::Pointer tempDLLHandle = ::map::deployment::openDeploymentDLL( dllInfo->getLibraryFilePath()); ::map::algorithm::RegistrationAlgorithmBase::Pointer tempAlgorithm = ::map::deployment::getRegistrationAlgorithm(tempDLLHandle); if (tempAlgorithm.IsNull()) { Error(QStringLiteral("Error. Cannot load selected algorithm.")); return; } this->m_LoadedAlgorithm = tempAlgorithm; this->m_LoadedDLLHandle = tempDLLHandle; this->m_Controls.m_AlgoConfigurator->setAlgorithm(m_LoadedAlgorithm); typedef ::map::algorithm::facet::MaskedRegistrationAlgorithmInterface<3, 3> MaskRegInterface; const MaskRegInterface* pMaskReg = dynamic_cast (m_LoadedAlgorithm.GetPointer()); if (!pMaskReg) { m_spSelectedTargetMaskData = nullptr; m_spSelectedTargetMaskNode = nullptr; m_spSelectedMovingMaskData = nullptr; m_spSelectedMovingMaskNode = nullptr; m_Controls.targetMaskNodeSelector->SetCurrentSelection(QmitkAbstractNodeSelectionWidget::NodeList()); m_Controls.movingMaskNodeSelector->SetCurrentSelection(QmitkAbstractNodeSelectionWidget::NodeList()); } this->AdaptFolderGUIElements(); this->ConfigureNodeSelectors(); this->CheckInputs(); this->ConfigureRegistrationControls(); this->ConfigureProgressInfos(); this->m_Controls.m_tabs->setCurrentIndex(1); this->m_Controls.m_teLog->clear(); } void QmitkMatchPoint::Error(QString msg) { mitk::StatusBar::GetInstance()->DisplayErrorText(msg.toLatin1()); MITK_ERROR << msg.toStdString().c_str(); m_Controls.m_teLog->append(QStringLiteral("") + msg + QStringLiteral("")); } void QmitkMatchPoint::AdaptFolderGUIElements() { m_Controls.m_pbLoadSelected->setEnabled(m_CanLoadAlgorithm); } void QmitkMatchPoint::CreateQtPartControl(QWidget* parent) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); m_Parent = parent; m_Controls.m_tabs->setCurrentIndex(0); m_Controls.movingNodeSelector->SetDataStorage(this->GetDataStorage()); m_Controls.movingNodeSelector->SetSelectionIsOptional(false); m_Controls.targetNodeSelector->SetDataStorage(this->GetDataStorage()); m_Controls.targetNodeSelector->SetSelectionIsOptional(false); m_Controls.movingMaskNodeSelector->SetDataStorage(this->GetDataStorage()); m_Controls.movingMaskNodeSelector->SetSelectionIsOptional(true); m_Controls.targetMaskNodeSelector->SetDataStorage(this->GetDataStorage()); m_Controls.targetMaskNodeSelector->SetSelectionIsOptional(true); m_AlgorithmSelectionListener.reset(new berry::SelectionChangedAdapter(this, &QmitkMatchPoint::OnAlgorithmSelectionChanged)); // register selection listener GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddSelectionListener( m_AlgorithmSelectionListener.data()); this->CreateConnections(); this->AdaptFolderGUIElements(); this->CheckInputs(); this->ConfigureProgressInfos(); this->ConfigureRegistrationControls(); this->ConfigureNodeSelectors(); berry::ISelection::ConstPointer selection = GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.matchpoint.algorithm.browser"); this->UpdateAlgorithmSelection(selection); } mitk::Image::Pointer ExtractFirstFrame(const mitk::Image* dynamicImage) { mitk::ImageTimeSelector::Pointer imageTimeSelector = mitk::ImageTimeSelector::New(); imageTimeSelector->SetInput(dynamicImage); imageTimeSelector->SetTimeNr(0); imageTimeSelector->UpdateLargestPossibleRegion(); return imageTimeSelector->GetOutput(); } bool QmitkMatchPoint::CheckInputs() { if (m_LoadedAlgorithm.IsNull()) { m_spSelectedMovingNode = nullptr; m_spSelectedMovingData = nullptr; m_spSelectedTargetNode = nullptr; m_spSelectedTargetData = nullptr; m_spSelectedMovingMaskNode = nullptr; m_spSelectedMovingMaskData = nullptr; m_spSelectedTargetMaskNode = nullptr; m_spSelectedTargetMaskData = nullptr; } else { if (m_Controls.movingNodeSelector->GetSelectedNode().IsNull()) { m_spSelectedMovingNode = nullptr; m_spSelectedMovingData = nullptr; } else { m_spSelectedMovingNode = m_Controls.movingNodeSelector->GetSelectedNode(); m_spSelectedMovingData = m_spSelectedMovingNode->GetData(); auto movingImage = dynamic_cast(m_spSelectedMovingNode->GetData()); if (movingImage && movingImage->GetDimension() - 1 == m_LoadedAlgorithm->getMovingDimensions() && movingImage->GetTimeSteps() > 1) { m_spSelectedMovingData = ExtractFirstFrame(movingImage).GetPointer(); m_Controls.m_teLog->append( QStringLiteral("Selected moving image has multiple time steps. First time step is used as moving image.")); } } if (m_Controls.targetNodeSelector->GetSelectedNode().IsNull()) { m_spSelectedTargetNode = nullptr; m_spSelectedTargetData = nullptr; } else { m_spSelectedTargetNode = m_Controls.targetNodeSelector->GetSelectedNode(); m_spSelectedTargetData = m_spSelectedTargetNode->GetData(); auto targetImage = dynamic_cast(m_spSelectedTargetNode->GetData()); if (targetImage && targetImage->GetDimension() - 1 == m_LoadedAlgorithm->getTargetDimensions() && targetImage->GetTimeSteps() > 1) { m_spSelectedTargetData = ExtractFirstFrame(targetImage).GetPointer(); m_Controls.m_teLog->append( QStringLiteral("Selected target image has multiple time steps. First time step is used as target image.")); } } if (m_Controls.movingMaskNodeSelector->GetSelectedNode().IsNull()) { m_spSelectedMovingMaskNode = nullptr; m_spSelectedMovingMaskData = nullptr; } else { m_spSelectedMovingMaskNode = m_Controls.movingMaskNodeSelector->GetSelectedNode(); m_spSelectedMovingMaskData = dynamic_cast(m_spSelectedMovingMaskNode->GetData()); if (m_spSelectedMovingMaskData->GetDimension() - 1 == m_LoadedAlgorithm->getMovingDimensions() && m_spSelectedMovingMaskData->GetTimeSteps() > 1) { m_spSelectedMovingMaskData = ExtractFirstFrame(m_spSelectedMovingMaskData).GetPointer(); m_Controls.m_teLog->append( QStringLiteral("Selected moving mask has multiple time steps. First time step is used as moving mask.")); } } if (m_Controls.targetMaskNodeSelector->GetSelectedNode().IsNull()) { m_spSelectedTargetMaskNode = nullptr; m_spSelectedTargetMaskData = nullptr; } else { m_spSelectedTargetMaskNode = m_Controls.targetMaskNodeSelector->GetSelectedNode(); m_spSelectedTargetMaskData = dynamic_cast(m_spSelectedTargetMaskNode->GetData()); if (m_spSelectedTargetMaskData->GetDimension() - 1 == m_LoadedAlgorithm->getTargetDimensions() && m_spSelectedTargetMaskData->GetTimeSteps() > 1) { m_spSelectedTargetMaskData = ExtractFirstFrame(m_spSelectedTargetMaskData).GetPointer(); m_Controls.m_teLog->append( QStringLiteral("Selected target mask has multiple time steps. First time step is used as target mask.")); } } } m_ValidInputs = m_spSelectedMovingData.IsNotNull() && m_spSelectedTargetData.IsNotNull(); return m_ValidInputs; } std::string QmitkMatchPoint::GetInputNodeDisplayName(const mitk::DataNode* node) const { std::string result = "UNDEFINED/nullptr"; if (node) { result = node->GetName(); const mitk::PointSet* pointSet = dynamic_cast(node->GetData()); if (pointSet) { mitk::DataStorage::SetOfObjects::ConstPointer sources = this->GetDataStorage()->GetSources(node); if (sources.IsNotNull() && sources->Size() > 0) { result = result + " (" + sources->GetElement(0)->GetName() + ")"; } } } return result; } mitk::DataStorage::SetOfObjects::Pointer QmitkMatchPoint::GetRegNodes() const { mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->GetDataStorage()->GetAll(); mitk::DataStorage::SetOfObjects::Pointer result = mitk::DataStorage::SetOfObjects::New(); for (mitk::DataStorage::SetOfObjects::const_iterator pos = nodes->begin(); pos != nodes->end(); ++pos) { if (mitk::MITKRegistrationHelper::IsRegNode(*pos)) { result->push_back(*pos); } } return result; } std::string QmitkMatchPoint::GetDefaultRegJobName() const { mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->GetRegNodes().GetPointer(); mitk::DataStorage::SetOfObjects::ElementIdentifier estimatedIndex = nodes->Size(); bool isUnique = false; std::string result = "Unnamed Reg"; while (!isUnique) { ++estimatedIndex; result = "Reg #" +::map::core::convert::toStr(estimatedIndex); isUnique = this->GetDataStorage()->GetNamedNode(result) == nullptr; } return result; } void QmitkMatchPoint::ConfigureRegistrationControls() { m_Controls.m_tabSelection->setEnabled(!m_Working); m_Controls.m_leRegJobName->setEnabled(!m_Working); m_Controls.groupMasks->setEnabled(!m_Working); m_Controls.m_pbStartReg->setEnabled(false); m_Controls.m_pbStopReg->setEnabled(false); m_Controls.m_pbStopReg->setVisible(false); if (m_LoadedAlgorithm.IsNotNull()) { m_Controls.m_tabSettings->setEnabled(!m_Working); m_Controls.m_tabExecution->setEnabled(true); m_Controls.m_pbStartReg->setEnabled(m_ValidInputs && !m_Working); m_Controls.m_leRegJobName->setEnabled(!m_Working); m_Controls.m_checkMapEntity->setEnabled(!m_Working); m_Controls.targetNodeSelector->setEnabled(!m_Working); m_Controls.movingNodeSelector->setEnabled(!m_Working); m_Controls.targetMaskNodeSelector->setEnabled(!m_Working); m_Controls.movingMaskNodeSelector->setEnabled(!m_Working); const IStoppableAlgorithm* pIterativ = dynamic_cast (m_LoadedAlgorithm.GetPointer()); if (pIterativ) { m_Controls.m_pbStopReg->setVisible(pIterativ->isStoppable()); } typedef ::map::algorithm::facet::MaskedRegistrationAlgorithmInterface<3, 3> MaskRegInterface; const MaskRegInterface* pMaskReg = dynamic_cast (m_LoadedAlgorithm.GetPointer()); m_Controls.groupMasks->setVisible(pMaskReg != nullptr); //if the stop button is set to visible and the algorithm is working -> //then the algorithm is stoppable, thus enable the button. m_Controls.m_pbStopReg->setEnabled(m_Controls.m_pbStopReg->isVisible() && m_Working); this->m_Controls.m_lbLoadedAlgorithmName->setText( QString::fromStdString(m_LoadedAlgorithm->getUID()->toStr())); } else { m_Controls.m_tabSettings->setEnabled(false); m_Controls.m_tabExecution->setEnabled(false); this->m_Controls.m_lbLoadedAlgorithmName->setText( QStringLiteral("no algorithm loaded!")); m_Controls.groupMasks->setVisible(false); } if (!m_Working) { this->m_Controls.m_leRegJobName->setText(QString::fromStdString(this->GetDefaultRegJobName())); } } void QmitkMatchPoint::ConfigureNodeSelectors() { auto isImage = mitk::MITKRegistrationHelper::ImageNodePredicate(); auto isPointSet = mitk::MITKRegistrationHelper::PointSetNodePredicate(); auto isMask = mitk::MITKRegistrationHelper::MaskNodePredicate(); mitk::NodePredicateBase::Pointer dimensionPredicate = mitk::NodePredicateOr::New(mitk::NodePredicateDimension::New(3), mitk::NodePredicateDimension::New(4)).GetPointer(); m_Controls.movingNodeSelector->setEnabled(m_LoadedAlgorithm.IsNotNull()); m_Controls.targetNodeSelector->setEnabled(m_LoadedAlgorithm.IsNotNull()); m_Controls.movingMaskNodeSelector->setEnabled(m_LoadedAlgorithm.IsNotNull()); m_Controls.targetMaskNodeSelector->setEnabled(m_LoadedAlgorithm.IsNotNull()); if (m_LoadedAlgorithm.IsNotNull()) { mitk::NodePredicateBase::ConstPointer dataPredicate; if (m_LoadedAlgorithm->getMovingDimensions() == 2) { dimensionPredicate = mitk::NodePredicateDimension::New(2); } - if (mitk::MITKAlgorithmHelper::HasImageAlgorithmInterface(m_LoadedAlgorithm)) + if (mitk::MAPAlgorithmHelper::HasImageAlgorithmInterface(m_LoadedAlgorithm)) { dataPredicate = mitk::NodePredicateAnd::New(isImage, dimensionPredicate); m_Controls.movingNodeSelector->SetInvalidInfo("Select valid moving image."); m_Controls.movingNodeSelector->SetPopUpTitel("Select moving image."); m_Controls.movingNodeSelector->SetPopUpHint("Select the moving image that should be registered onto the target image."); m_Controls.targetNodeSelector->SetInvalidInfo("Select valid target image."); m_Controls.targetNodeSelector->SetPopUpTitel("Select target image."); m_Controls.targetNodeSelector->SetPopUpHint("Select the target image that should be used as reference for the registration."); } - if (mitk::MITKAlgorithmHelper::HasPointSetAlgorithmInterface(m_LoadedAlgorithm)) + if (mitk::MAPAlgorithmHelper::HasPointSetAlgorithmInterface(m_LoadedAlgorithm)) { if (dataPredicate.IsNull()) { dataPredicate = isPointSet; m_Controls.movingNodeSelector->SetInvalidInfo("Select valid moving point set."); m_Controls.movingNodeSelector->SetPopUpTitel("Select moving point set."); m_Controls.movingNodeSelector->SetPopUpHint("Select the moving point set that should be registered onto the target point set."); m_Controls.targetNodeSelector->SetInvalidInfo("Select valid target point set."); m_Controls.targetNodeSelector->SetPopUpTitel("Select target point set."); m_Controls.targetNodeSelector->SetPopUpHint("Select the target point set that should be used as reference for the registration."); } else { dataPredicate = mitk::NodePredicateOr::New(dataPredicate, isPointSet); m_Controls.movingNodeSelector->SetInvalidInfo("Select valid moving data."); m_Controls.movingNodeSelector->SetPopUpTitel("Select moving data."); m_Controls.movingNodeSelector->SetPopUpHint("Select the moving data that should be registered onto the target data. The algorithm supports images as well as point sets."); m_Controls.targetNodeSelector->SetInvalidInfo("Select valid target data."); m_Controls.targetNodeSelector->SetPopUpTitel("Select target data."); m_Controls.targetNodeSelector->SetPopUpHint("Select the target data that should be used as reference for the registration. The algorithm supports images as well as point sets."); } } mitk::NodePredicateBase::ConstPointer nodePredicate = dataPredicate; m_Controls.movingNodeSelector->SetNodePredicate(nodePredicate); m_Controls.targetNodeSelector->SetNodePredicate(nodePredicate); nodePredicate = mitk::NodePredicateAnd::New(isMask, dimensionPredicate); m_Controls.movingMaskNodeSelector->SetEmptyInfo("Select moving mask. (optional)"); m_Controls.movingMaskNodeSelector->SetPopUpTitel("Select moving mask"); m_Controls.movingMaskNodeSelector->SetPopUpHint("Select a segmentation that serves as moving mask for the registration."); m_Controls.targetMaskNodeSelector->SetEmptyInfo("Select target mask. (optional)"); m_Controls.targetMaskNodeSelector->SetPopUpTitel("Select target mask"); m_Controls.targetMaskNodeSelector->SetPopUpHint("Select a segmentation that serves as target mask for the registration."); m_Controls.movingMaskNodeSelector->SetNodePredicate(nodePredicate); m_Controls.targetMaskNodeSelector->SetNodePredicate(nodePredicate); } } void QmitkMatchPoint::ConfigureProgressInfos() { const IIterativeAlgorithm* pIterative = dynamic_cast (m_LoadedAlgorithm.GetPointer()); const IMultiResAlgorithm* pMultiRes = dynamic_cast (m_LoadedAlgorithm.GetPointer()); m_Controls.m_progBarIteration->setVisible(pIterative); m_Controls.m_lbProgBarIteration->setVisible(pIterative); if (pIterative) { QString format = "%p% (%v/%m)"; if (!pIterative->hasMaxIterationCount()) { format = "%v"; m_Controls.m_progBarIteration->setMaximum(0); } else { m_Controls.m_progBarIteration->setMaximum(pIterative->getMaxIterations()); } m_Controls.m_progBarIteration->setFormat(format); } m_Controls.m_progBarLevel->setVisible(pMultiRes); m_Controls.m_lbProgBarLevel->setVisible(pMultiRes); if (pMultiRes) { m_Controls.m_progBarLevel->setMaximum(pMultiRes->getResolutionLevels()); } else { m_Controls.m_progBarLevel->setMaximum(1); } m_Controls.m_progBarIteration->reset(); m_Controls.m_progBarLevel->reset(); } void QmitkMatchPoint::OnNodeSelectionChanged(QList /*nodes*/) { if (!m_Working) { CheckInputs(); ConfigureRegistrationControls(); } } void QmitkMatchPoint::OnStartRegBtnPushed() { this->m_Working = true; //////////////////////////////// //configure GUI this->ConfigureProgressInfos(); m_Controls.m_progBarIteration->reset(); m_Controls.m_progBarLevel->reset(); this->ConfigureRegistrationControls(); if (m_Controls.m_checkClearLog->checkState() == Qt::Checked) { this->m_Controls.m_teLog->clear(); } ///////////////////////// //create job and put it into the thread pool QmitkRegistrationJob* pJob = new QmitkRegistrationJob(m_LoadedAlgorithm); pJob->setAutoDelete(true); pJob->m_spTargetData = m_spSelectedTargetData; pJob->m_spMovingData = m_spSelectedMovingData; pJob->m_TargetDataUID = mitk::EnsureUID(this->m_spSelectedTargetNode->GetData()); pJob->m_MovingDataUID = mitk::EnsureUID(this->m_spSelectedMovingNode->GetData()); if (m_spSelectedTargetMaskData.IsNotNull()) { pJob->m_spTargetMask = m_spSelectedTargetMaskData; pJob->m_TargetMaskDataUID = mitk::EnsureUID(this->m_spSelectedTargetMaskNode->GetData()); } if (m_spSelectedMovingMaskData.IsNotNull()) { pJob->m_spMovingMask = m_spSelectedMovingMaskData; pJob->m_MovingMaskDataUID = mitk::EnsureUID(this->m_spSelectedMovingMaskNode->GetData()); } pJob->m_JobName = m_Controls.m_leRegJobName->text().toStdString(); pJob->m_StoreReg = true; connect(pJob, SIGNAL(Error(QString)), this, SLOT(OnRegJobError(QString))); connect(pJob, SIGNAL(Finished()), this, SLOT(OnRegJobFinished())); connect(pJob, SIGNAL(RegResultIsAvailable(mitk::MAPRegistrationWrapper::Pointer, const QmitkRegistrationJob*)), this, SLOT(OnRegResultIsAvailable(mitk::MAPRegistrationWrapper::Pointer, const QmitkRegistrationJob*)), Qt::BlockingQueuedConnection); connect(pJob, SIGNAL(AlgorithmInfo(QString)), this, SLOT(OnAlgorithmInfo(QString))); connect(pJob, SIGNAL(AlgorithmStatusChanged(QString)), this, SLOT(OnAlgorithmStatusChanged(QString))); connect(pJob, SIGNAL(AlgorithmIterated(QString, bool, unsigned long)), this, SLOT(OnAlgorithmIterated(QString, bool, unsigned long))); connect(pJob, SIGNAL(LevelChanged(QString, bool, unsigned long)), this, SLOT(OnLevelChanged(QString, bool, unsigned long))); QThreadPool* threadPool = QThreadPool::globalInstance(); threadPool->start(pJob); } void QmitkMatchPoint::OnStopRegBtnPushed() { if (m_LoadedAlgorithm.IsNotNull()) { IStoppableAlgorithm* pIterativ = dynamic_cast(m_LoadedAlgorithm.GetPointer()); if (pIterativ && pIterativ->isStoppable()) { if (pIterativ->stopAlgorithm()) { } else { } m_Controls.m_pbStopReg->setEnabled(false); } else { } } } void QmitkMatchPoint::OnSaveLogBtnPushed() { QDateTime currentTime = QDateTime::currentDateTime(); QString fileName = tr("registration_log_") + currentTime.toString(tr("yyyy-MM-dd_hh-mm-ss")) + tr(".txt"); fileName = QFileDialog::getSaveFileName(nullptr, tr("Save registration log"), fileName, tr("Text files (*.txt)")); if (fileName.isEmpty()) { QMessageBox::critical(nullptr, tr("No file selected!"), tr("Cannot save registration log file. Please selected a file.")); } else { std::ofstream file; std::ios_base::openmode iOpenFlag = std::ios_base::out | std::ios_base::trunc; file.open(fileName.toStdString().c_str(), iOpenFlag); if (!file.is_open()) { mitkThrow() << "Cannot open or create specified file to save. File path: " << fileName.toStdString(); } file << this->m_Controls.m_teLog->toPlainText().toStdString() << std::endl; file.close(); } } void QmitkMatchPoint::OnRegJobError(QString err) { Error(err); } void QmitkMatchPoint::OnRegJobFinished() { this->m_Working = false; this->GetRenderWindowPart()->RequestUpdate(); this->CheckInputs(); this->ConfigureRegistrationControls(); this->ConfigureProgressInfos(); } void QmitkMatchPoint::OnRegResultIsAvailable(mitk::MAPRegistrationWrapper::Pointer spResultRegistration, const QmitkRegistrationJob* pRegJob) { mitk::DataNode::Pointer spResultRegistrationNode = mitk::generateRegistrationResultNode( pRegJob->m_JobName, spResultRegistration, pRegJob->GetLoadedAlgorithm()->getUID()->toStr(), pRegJob->m_MovingDataUID, pRegJob->m_TargetDataUID); if (pRegJob->m_StoreReg) { m_Controls.m_teLog->append( QStringLiteral(" Storing registration object in data manager ... ")); this->GetDataStorage()->Add(spResultRegistrationNode); this->GetRenderWindowPart()->RequestUpdate(); } if (m_Controls.m_checkMapEntity->checkState() == Qt::Checked) { QmitkMappingJob* pMapJob = new QmitkMappingJob(); pMapJob->setAutoDelete(true); pMapJob->m_spInputData = pRegJob->m_spMovingData; pMapJob->m_InputDataUID = pRegJob->m_MovingDataUID; pMapJob->m_spRegNode = spResultRegistrationNode; pMapJob->m_doGeometryRefinement = false; pMapJob->m_spRefGeometry = pRegJob->m_spTargetData->GetGeometry()->Clone().GetPointer(); pMapJob->m_MappedName = pRegJob->m_JobName + std::string(" mapped moving data"); pMapJob->m_allowUndefPixels = true; pMapJob->m_paddingValue = 100; pMapJob->m_allowUnregPixels = true; pMapJob->m_errorValue = 200; pMapJob->m_InterpolatorLabel = "Linear Interpolation"; pMapJob->m_InterpolatorType = mitk::ImageMappingInterpolator::Linear; connect(pMapJob, SIGNAL(Error(QString)), this, SLOT(OnMapJobError(QString))); connect(pMapJob, SIGNAL(MapResultIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), this, SLOT(OnMapResultIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), Qt::BlockingQueuedConnection); connect(pMapJob, SIGNAL(AlgorithmInfo(QString)), this, SLOT(OnAlgorithmInfo(QString))); m_Controls.m_teLog->append( QStringLiteral("Started mapping input data...")); QThreadPool* threadPool = QThreadPool::globalInstance(); threadPool->start(pMapJob); } } void QmitkMatchPoint::OnMapJobError(QString err) { Error(err); } void QmitkMatchPoint::OnMapResultIsAvailable(mitk::BaseData::Pointer spMappedData, const QmitkMappingJob* job) { m_Controls.m_teLog->append(QStringLiteral("Mapped entity stored. Name: ") + QString::fromStdString(job->m_MappedName) + QStringLiteral("")); mitk::DataNode::Pointer spMappedNode = mitk::generateMappedResultNode(job->m_MappedName, spMappedData, job->GetRegistration()->getRegistrationUID(), job->m_InputDataUID, job->m_doGeometryRefinement, job->m_InterpolatorLabel); this->GetDataStorage()->Add(spMappedNode); this->GetRenderWindowPart()->RequestUpdate(); } void QmitkMatchPoint::OnAlgorithmIterated(QString info, bool hasIterationCount, unsigned long currentIteration) { if (hasIterationCount) { m_Controls.m_progBarIteration->setValue(currentIteration); } m_Controls.m_teLog->append(info); } void QmitkMatchPoint::OnLevelChanged(QString info, bool hasLevelCount, unsigned long currentLevel) { if (hasLevelCount) { m_Controls.m_progBarLevel->setValue(currentLevel); } m_Controls.m_teLog->append(QStringLiteral("") + info + QStringLiteral("")); } void QmitkMatchPoint::OnAlgorithmStatusChanged(QString info) { m_Controls.m_teLog->append(QStringLiteral("") + info + QStringLiteral(" ")); } void QmitkMatchPoint::OnAlgorithmInfo(QString info) { m_Controls.m_teLog->append(QStringLiteral("") + info + QStringLiteral("")); } void QmitkMatchPoint::OnAlgorithmSelectionChanged(const berry::IWorkbenchPart::Pointer& sourcepart, const berry::ISelection::ConstPointer& selection) { // check for null selection if (selection.IsNull()) { return; } if (sourcepart != this) { UpdateAlgorithmSelection(selection); } } void QmitkMatchPoint::UpdateAlgorithmSelection(berry::ISelection::ConstPointer selection) { mitk::MAPAlgorithmInfoSelection::ConstPointer currentSelection = selection.Cast(); if (currentSelection) { mitk::MAPAlgorithmInfoSelection::AlgorithmInfoVectorType infoVector = currentSelection->GetSelectedAlgorithmInfo(); if (!infoVector.empty()) { // only the first selection is of interest, the rest will be skipped. this->m_SelectedAlgorithmInfo = infoVector[0]; } } this->OnSelectedAlgorithmChanged(); } diff --git a/Plugins/org.mitk.gui.qt.matchpoint.evaluator/src/internal/QmitkMatchPointRegistrationEvaluator.cpp b/Plugins/org.mitk.gui.qt.matchpoint.evaluator/src/internal/QmitkMatchPointRegistrationEvaluator.cpp index 628984328e..86ba3b923a 100644 --- a/Plugins/org.mitk.gui.qt.matchpoint.evaluator/src/internal/QmitkMatchPointRegistrationEvaluator.cpp +++ b/Plugins/org.mitk.gui.qt.matchpoint.evaluator/src/internal/QmitkMatchPointRegistrationEvaluator.cpp @@ -1,304 +1,304 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ // Blueberry #include #include // Mitk #include #include #include #include "mitkRegVisPropertyTags.h" #include "mitkMatchPointPropertyTags.h" #include "mitkRegEvaluationObject.h" #include "mitkRegistrationHelper.h" #include "mitkRegEvaluationMapper2D.h" -#include +#include // Qmitk #include "QmitkRenderWindow.h" #include "QmitkMatchPointRegistrationEvaluator.h" // Qt #include #include #include const std::string QmitkMatchPointRegistrationEvaluator::VIEW_ID = "org.mitk.views.matchpoint.registration.evaluator"; const std::string QmitkMatchPointRegistrationEvaluator::HelperNodeName = "RegistrationEvaluationHelper"; QmitkMatchPointRegistrationEvaluator::QmitkMatchPointRegistrationEvaluator() : m_Parent(nullptr), m_activeEvaluation(false), m_currentSelectedTimeStep(0) { m_currentSelectedPosition.Fill(0.0); } QmitkMatchPointRegistrationEvaluator::~QmitkMatchPointRegistrationEvaluator() { if (this->m_selectedEvalNode.IsNotNull() && this->GetDataStorage().IsNotNull()) { this->GetDataStorage()->Remove(this->m_selectedEvalNode); } } void QmitkMatchPointRegistrationEvaluator::SetFocus() { } void QmitkMatchPointRegistrationEvaluator::Error(QString msg) { mitk::StatusBar::GetInstance()->DisplayErrorText(msg.toLatin1()); MITK_ERROR << msg.toStdString().c_str(); } void QmitkMatchPointRegistrationEvaluator::CreateQtPartControl(QWidget* parent) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); m_Parent = parent; this->m_Controls.registrationNodeSelector->SetDataStorage(this->GetDataStorage()); this->m_Controls.registrationNodeSelector->SetSelectionIsOptional(true); this->m_Controls.movingNodeSelector->SetDataStorage(this->GetDataStorage()); this->m_Controls.movingNodeSelector->SetSelectionIsOptional(false); this->m_Controls.targetNodeSelector->SetDataStorage(this->GetDataStorage()); this->m_Controls.targetNodeSelector->SetSelectionIsOptional(false); this->m_Controls.registrationNodeSelector->SetInvalidInfo("Select valid registration."); this->m_Controls.registrationNodeSelector->SetEmptyInfo("Assuming identity. Select registration to change."); this->m_Controls.registrationNodeSelector->SetPopUpTitel("Select registration."); this->m_Controls.registrationNodeSelector->SetPopUpHint("Select a registration object that should be evaluated. If no registration is selected, identity will be assumed for evaluation."); this->m_Controls.movingNodeSelector->SetInvalidInfo("Select moving image."); this->m_Controls.movingNodeSelector->SetPopUpTitel("Select moving image."); this->m_Controls.movingNodeSelector->SetPopUpHint("Select the moving image for the evaluation. This is the image that will be mapped by the registration."); this->m_Controls.targetNodeSelector->SetInvalidInfo("Select target image."); this->m_Controls.targetNodeSelector->SetPopUpTitel("Select target image."); this->m_Controls.targetNodeSelector->SetPopUpHint("Select the target image for the evaluation."); this->ConfigureNodePredicates(); connect(m_Controls.pbEval, SIGNAL(clicked()), this, SLOT(OnEvalBtnPushed())); connect(m_Controls.pbStop, SIGNAL(clicked()), this, SLOT(OnStopBtnPushed())); connect(m_Controls.evalSettings, SIGNAL(SettingsChanged(mitk::DataNode*)), this, SLOT(OnSettingsChanged(mitk::DataNode*))); connect(m_Controls.registrationNodeSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkMatchPointRegistrationEvaluator::OnNodeSelectionChanged); connect(m_Controls.movingNodeSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkMatchPointRegistrationEvaluator::OnNodeSelectionChanged); connect(m_Controls.targetNodeSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkMatchPointRegistrationEvaluator::OnNodeSelectionChanged); this->m_SliceChangeListener.RenderWindowPartActivated(this->GetRenderWindowPart()); connect(&m_SliceChangeListener, SIGNAL(SliceChanged()), this, SLOT(OnSliceChanged())); m_selectedEvalNode = this->GetDataStorage()->GetNamedNode(HelperNodeName); this->CheckInputs(); this->ConfigureControls(); } void QmitkMatchPointRegistrationEvaluator::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) { this->m_SliceChangeListener.RenderWindowPartActivated(renderWindowPart); } void QmitkMatchPointRegistrationEvaluator::RenderWindowPartDeactivated( mitk::IRenderWindowPart* renderWindowPart) { this->m_SliceChangeListener.RenderWindowPartDeactivated(renderWindowPart); } void QmitkMatchPointRegistrationEvaluator::ConfigureNodePredicates() { this->m_Controls.registrationNodeSelector->SetNodePredicate(mitk::MITKRegistrationHelper::RegNodePredicate()); this->m_Controls.movingNodeSelector->SetNodePredicate(mitk::MITKRegistrationHelper::ImageNodePredicate()); this->m_Controls.targetNodeSelector->SetNodePredicate(mitk::MITKRegistrationHelper::ImageNodePredicate()); } void QmitkMatchPointRegistrationEvaluator::CheckInputs() { if (!m_activeEvaluation) { this->m_spSelectedRegNode = this->m_Controls.registrationNodeSelector->GetSelectedNode(); this->m_spSelectedMovingNode = this->m_Controls.movingNodeSelector->GetSelectedNode(); this->m_spSelectedTargetNode = this->m_Controls.targetNodeSelector->GetSelectedNode(); if (this->m_spSelectedMovingNode.IsNull() && this->m_spSelectedRegNode.IsNotNull()) { mitk::BaseProperty* uidProp = m_spSelectedRegNode->GetData()->GetProperty(mitk::Prop_RegAlgMovingData); if (uidProp) { //search for the moving node mitk::NodePredicateDataProperty::Pointer predicate = mitk::NodePredicateDataProperty::New(mitk::Prop_UID, uidProp); mitk::DataNode::Pointer movingNode = this->GetDataStorage()->GetNode(predicate); if (movingNode.IsNotNull()) { this->m_spSelectedMovingNode = movingNode; QmitkSingleNodeSelectionWidget::NodeList selection({ movingNode }); this->m_Controls.movingNodeSelector->SetCurrentSelection(selection); } } } if (this->m_spSelectedTargetNode.IsNull() && this->m_spSelectedRegNode.IsNotNull()) { mitk::BaseProperty* uidProp = m_spSelectedRegNode->GetData()->GetProperty(mitk::Prop_RegAlgTargetData); if (uidProp) { //search for the target node mitk::NodePredicateDataProperty::Pointer predicate = mitk::NodePredicateDataProperty::New(mitk::Prop_UID, uidProp); mitk::DataNode::Pointer targetNode = this->GetDataStorage()->GetNode(predicate); if (targetNode.IsNotNull()) { this->m_spSelectedTargetNode = targetNode; QmitkSingleNodeSelectionWidget::NodeList selection({ targetNode }); this->m_Controls.targetNodeSelector->SetCurrentSelection(selection); } } } } } void QmitkMatchPointRegistrationEvaluator::OnNodeSelectionChanged(QList /*nodes*/) { this->CheckInputs(); this->ConfigureControls(); } void QmitkMatchPointRegistrationEvaluator::NodeRemoved(const mitk::DataNode* node) { if (node == this->m_spSelectedMovingNode || node == this->m_spSelectedRegNode || node == this->m_spSelectedTargetNode || node == this->m_selectedEvalNode) { if (node == this->m_selectedEvalNode) { this->m_selectedEvalNode = nullptr; } this->OnStopBtnPushed(); MITK_INFO << "Stopped current MatchPoint evaluation session, because at least one relevant node was removed from storage."; } } void QmitkMatchPointRegistrationEvaluator::ConfigureControls() { //config settings widget this->m_Controls.evalSettings->setVisible(m_activeEvaluation); this->m_Controls.pbEval->setEnabled(this->m_spSelectedMovingNode.IsNotNull() && this->m_spSelectedTargetNode.IsNotNull()); this->m_Controls.pbEval->setVisible(!m_activeEvaluation); this->m_Controls.pbStop->setVisible(m_activeEvaluation); this->m_Controls.registrationNodeSelector->setEnabled(!m_activeEvaluation); this->m_Controls.movingNodeSelector->setEnabled(!m_activeEvaluation); this->m_Controls.targetNodeSelector->setEnabled(!m_activeEvaluation); } void QmitkMatchPointRegistrationEvaluator::OnSliceChanged() { mitk::Point3D currentSelectedPosition = GetRenderWindowPart()->GetSelectedPosition(nullptr); unsigned int currentSelectedTimeStep = GetRenderWindowPart()->GetTimeNavigationController()->GetTime()->GetPos(); if (m_currentSelectedPosition != currentSelectedPosition || m_currentSelectedTimeStep != currentSelectedTimeStep || m_selectedNodeTime > m_currentPositionTime) { //the current position has been changed or the selected node has been changed since the last position validation -> check position m_currentSelectedPosition = currentSelectedPosition; m_currentSelectedTimeStep = currentSelectedTimeStep; m_currentPositionTime.Modified(); if (this->m_selectedEvalNode.IsNotNull()) { this->m_selectedEvalNode->SetProperty(mitk::nodeProp_RegEvalCurrentPosition, mitk::GenericProperty::New(currentSelectedPosition)); } } } void QmitkMatchPointRegistrationEvaluator::OnSettingsChanged(mitk::DataNode*) { this->GetRenderWindowPart()->RequestUpdate(); } void QmitkMatchPointRegistrationEvaluator::OnEvalBtnPushed() { //reinit view mitk::RenderingManager::GetInstance()->InitializeViews(m_spSelectedTargetNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); mitk::RegEvaluationObject::Pointer regEval = mitk::RegEvaluationObject::New(); mitk::MAPRegistrationWrapper::Pointer reg; if (m_spSelectedRegNode.IsNotNull()) { reg = dynamic_cast(this->m_spSelectedRegNode->GetData()); } else { //generate a dymme reg to use reg = mitk::GenerateIdentityRegistration3D(); } regEval->SetRegistration(reg); regEval->SetTargetNode(this->m_spSelectedTargetNode); regEval->SetMovingNode(this->m_spSelectedMovingNode); if (this->m_selectedEvalNode.IsNotNull()) { this->GetDataStorage()->Remove(this->m_selectedEvalNode); } this->m_selectedEvalNode = mitk::DataNode::New(); this->m_selectedEvalNode->SetData(regEval); mitk::RegEvaluationMapper2D::SetDefaultProperties(this->m_selectedEvalNode); this->m_selectedEvalNode->SetName(HelperNodeName); this->m_selectedEvalNode->SetBoolProperty("helper object", true); this->GetDataStorage()->Add(this->m_selectedEvalNode); this->m_Controls.evalSettings->SetNode(this->m_selectedEvalNode); this->OnSliceChanged(); this->GetRenderWindowPart()->RequestUpdate(); this->m_activeEvaluation = true; this->CheckInputs(); this->ConfigureControls(); } void QmitkMatchPointRegistrationEvaluator::OnStopBtnPushed() { this->m_activeEvaluation = false; if (this->m_selectedEvalNode.IsNotNull()) { this->GetDataStorage()->Remove(this->m_selectedEvalNode); } this->m_selectedEvalNode = nullptr; this->m_Controls.evalSettings->SetNode(this->m_selectedEvalNode); this->CheckInputs(); this->ConfigureControls(); this->GetRenderWindowPart()->RequestUpdate(); } diff --git a/Plugins/org.mitk.gui.qt.matchpoint.manipulator/src/internal/QmitkMatchPointRegistrationManipulator.cpp b/Plugins/org.mitk.gui.qt.matchpoint.manipulator/src/internal/QmitkMatchPointRegistrationManipulator.cpp index 533c6c8e22..4ac853520c 100644 --- a/Plugins/org.mitk.gui.qt.matchpoint.manipulator/src/internal/QmitkMatchPointRegistrationManipulator.cpp +++ b/Plugins/org.mitk.gui.qt.matchpoint.manipulator/src/internal/QmitkMatchPointRegistrationManipulator.cpp @@ -1,492 +1,492 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ // Blueberry #include #include // Mitk #include #include #include #include "mitkRegVisPropertyTags.h" #include "mitkMatchPointPropertyTags.h" #include "mitkRegEvaluationObject.h" #include "mitkRegistrationHelper.h" #include "mitkRegEvaluationMapper2D.h" -#include +#include #include #include // Qmitk #include "QmitkRenderWindow.h" #include "QmitkMatchPointRegistrationManipulator.h" #include // Qt #include #include #include #include //MatchPoint #include #include #include #include #include #include #include const std::string QmitkMatchPointRegistrationManipulator::VIEW_ID = "org.mitk.views.matchpoint.registration.manipulator"; const std::string QmitkMatchPointRegistrationManipulator::HelperNodeName = "RegistrationManipulationEvaluationHelper"; QmitkMatchPointRegistrationManipulator::QmitkMatchPointRegistrationManipulator() : m_Parent(nullptr), m_activeManipulation(false), m_currentSelectedTimeStep(0), m_internalUpdate(false) { m_currentSelectedPosition.Fill(0.0); } QmitkMatchPointRegistrationManipulator::~QmitkMatchPointRegistrationManipulator() { if (this->m_EvalNode.IsNotNull() && this->GetDataStorage().IsNotNull()) { this->GetDataStorage()->Remove(this->m_EvalNode); } } void QmitkMatchPointRegistrationManipulator::SetFocus() { } void QmitkMatchPointRegistrationManipulator::Error(QString msg) { mitk::StatusBar::GetInstance()->DisplayErrorText(msg.toLatin1()); MITK_ERROR << msg.toStdString().c_str(); } void QmitkMatchPointRegistrationManipulator::CreateQtPartControl(QWidget* parent) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); m_Parent = parent; this->m_Controls.registrationNodeSelector->SetDataStorage(this->GetDataStorage()); this->m_Controls.registrationNodeSelector->SetSelectionIsOptional(false); this->m_Controls.movingNodeSelector->SetDataStorage(this->GetDataStorage()); this->m_Controls.movingNodeSelector->SetSelectionIsOptional(false); this->m_Controls.targetNodeSelector->SetDataStorage(this->GetDataStorage()); this->m_Controls.targetNodeSelector->SetSelectionIsOptional(false); this->m_Controls.registrationNodeSelector->SetInvalidInfo("Select base registration."); this->m_Controls.registrationNodeSelector->SetPopUpTitel("Select registration."); this->m_Controls.registrationNodeSelector->SetPopUpHint("Select a registration object that should be used as starting point for the manual manipulation."); this->m_Controls.movingNodeSelector->SetInvalidInfo("Select moving image."); this->m_Controls.movingNodeSelector->SetPopUpTitel("Select moving image."); this->m_Controls.movingNodeSelector->SetPopUpHint("Select the moving image for the evaluation. This is the image that will be mapped by the registration."); this->m_Controls.targetNodeSelector->SetInvalidInfo("Select target image."); this->m_Controls.targetNodeSelector->SetPopUpTitel("Select target image."); this->m_Controls.targetNodeSelector->SetPopUpHint("Select the target image for the evaluation."); this->ConfigureNodePredicates(); connect(m_Controls.pbStart, SIGNAL(clicked()), this, SLOT(OnStartBtnPushed())); connect(m_Controls.pbCancel, SIGNAL(clicked()), this, SLOT(OnCancelBtnPushed())); connect(m_Controls.pbStore, SIGNAL(clicked()), this, SLOT(OnStoreBtnPushed())); connect(m_Controls.evalSettings, SIGNAL(SettingsChanged(mitk::DataNode*)), this, SLOT(OnSettingsChanged(mitk::DataNode*))); connect(m_Controls.radioSelectedReg, SIGNAL(toggled(bool)), this, SLOT(OnRegSourceChanged())); connect(m_Controls.comboCenter, SIGNAL(currentIndexChanged(int)), this, SLOT(OnCenterTypeChanged(int))); connect(m_Controls.manipulationWidget, SIGNAL(RegistrationChanged(map::core::RegistrationBase*)), this, SLOT(OnRegistrationChanged())); connect(m_Controls.registrationNodeSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkMatchPointRegistrationManipulator::OnNodeSelectionChanged); connect(m_Controls.movingNodeSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkMatchPointRegistrationManipulator::OnNodeSelectionChanged); connect(m_Controls.targetNodeSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkMatchPointRegistrationManipulator::OnNodeSelectionChanged); this->m_SliceChangeListener.RenderWindowPartActivated(this->GetRenderWindowPart()); connect(&m_SliceChangeListener, SIGNAL(SliceChanged()), this, SLOT(OnSliceChanged())); m_Controls.radioNewReg->setChecked(true); m_EvalNode = this->GetDataStorage()->GetNamedNode(HelperNodeName); this->CheckInputs(); this->StopSession(); this->ConfigureControls(); } void QmitkMatchPointRegistrationManipulator::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) { this->m_SliceChangeListener.RenderWindowPartActivated(renderWindowPart); } void QmitkMatchPointRegistrationManipulator::RenderWindowPartDeactivated( mitk::IRenderWindowPart* renderWindowPart) { this->m_SliceChangeListener.RenderWindowPartDeactivated(renderWindowPart); } void QmitkMatchPointRegistrationManipulator::ConfigureNodePredicates() { this->m_Controls.registrationNodeSelector->SetNodePredicate(mitk::MITKRegistrationHelper::RegNodePredicate()); this->m_Controls.movingNodeSelector->SetNodePredicate(mitk::MITKRegistrationHelper::ImageNodePredicate()); this->m_Controls.targetNodeSelector->SetNodePredicate(mitk::MITKRegistrationHelper::ImageNodePredicate()); } void QmitkMatchPointRegistrationManipulator::CheckInputs() { if (!m_activeManipulation) { this->m_SelectedPreRegNode = this->m_Controls.registrationNodeSelector->GetSelectedNode(); this->m_SelectedMovingNode = this->m_Controls.movingNodeSelector->GetSelectedNode(); this->m_SelectedTargetNode = this->m_Controls.targetNodeSelector->GetSelectedNode(); if (this->m_SelectedPreRegNode.IsNotNull()) { mitk::MAPRegistrationWrapper* regWrapper = dynamic_cast(m_SelectedPreRegNode->GetData()); if (regWrapper) { this->m_SelectedPreReg = dynamic_cast(regWrapper->GetRegistration()); } } if (this->m_SelectedMovingNode.IsNull() && this->m_SelectedPreRegNode.IsNotNull()) { mitk::BaseProperty* uidProp = m_SelectedPreRegNode->GetData()->GetProperty(mitk::Prop_RegAlgMovingData); if (uidProp) { //search for the moving node mitk::NodePredicateDataProperty::Pointer predicate = mitk::NodePredicateDataProperty::New(mitk::Prop_UID, uidProp); mitk::DataNode::Pointer movingNode = this->GetDataStorage()->GetNode(predicate); if (movingNode.IsNotNull()) { this->m_SelectedMovingNode = movingNode; QmitkSingleNodeSelectionWidget::NodeList selection({ movingNode }); this->m_Controls.movingNodeSelector->SetCurrentSelection(selection); } } } if (this->m_SelectedTargetNode.IsNull() && this->m_SelectedPreRegNode.IsNotNull()) { mitk::BaseProperty* uidProp = m_SelectedPreRegNode->GetData()->GetProperty(mitk::Prop_RegAlgTargetData); if (uidProp) { //search for the target node mitk::NodePredicateDataProperty::Pointer predicate = mitk::NodePredicateDataProperty::New(mitk::Prop_UID, uidProp); mitk::DataNode::Pointer targetNode = this->GetDataStorage()->GetNode(predicate); if (targetNode.IsNotNull()) { this->m_SelectedTargetNode = targetNode; QmitkSingleNodeSelectionWidget::NodeList selection({ targetNode }); this->m_Controls.targetNodeSelector->SetCurrentSelection(selection); } } } } } void QmitkMatchPointRegistrationManipulator::OnRegSourceChanged() { this->CheckInputs(); this->ConfigureControls(); } void QmitkMatchPointRegistrationManipulator::OnNodeSelectionChanged(QList /*nodes*/) { this->CheckInputs(); this->ConfigureControls(); } void QmitkMatchPointRegistrationManipulator::NodeRemoved(const mitk::DataNode* node) { if (node == this->m_SelectedMovingNode || node == this->m_SelectedTargetNode || node == this->m_EvalNode) { if (node == this->m_EvalNode) { this->m_EvalNode = nullptr; } if (this->m_activeManipulation) { MITK_INFO << "Stopped current MatchPoint manual registration session, because at least one relevant node was removed from storage."; } this->OnCancelBtnPushed(); } } void QmitkMatchPointRegistrationManipulator::ConfigureControls() { if (!m_activeManipulation) { QString name = "ManuelRegistration"; if (m_SelectedPreRegNode.IsNotNull()) { name = QString::fromStdString(m_SelectedPreRegNode->GetName()) + " manual refined"; } this->m_Controls.lbNewRegName->setText(name); } //config settings widget this->m_Controls.groupReg->setEnabled(!m_activeManipulation); this->m_Controls.pbStart->setEnabled(this->m_SelectedMovingNode.IsNotNull() && this->m_SelectedTargetNode.IsNotNull() && !m_activeManipulation && (this->m_Controls.radioNewReg->isChecked() || this->m_SelectedPreReg.IsNotNull())); this->m_Controls.lbNewRegName->setEnabled(m_activeManipulation); this->m_Controls.checkMapEntity->setEnabled(m_activeManipulation); this->m_Controls.tabWidget->setEnabled(m_activeManipulation); this->m_Controls.pbCancel->setEnabled(m_activeManipulation); this->m_Controls.pbStore->setEnabled(m_activeManipulation); this->m_Controls.registrationNodeSelector->setEnabled(!m_activeManipulation && this->m_Controls.radioSelectedReg->isChecked()); this->m_Controls.movingNodeSelector->setEnabled(!m_activeManipulation); this->m_Controls.targetNodeSelector->setEnabled(!m_activeManipulation); } void QmitkMatchPointRegistrationManipulator::InitSession() { if (this->m_Controls.radioNewReg->isChecked()) { //init to map the image centers auto movingCenter = m_SelectedMovingNode->GetData()->GetTimeGeometry()->GetCenterInWorld(); auto targetCenter = m_SelectedTargetNode->GetData()->GetTimeGeometry()->GetCenterInWorld(); this->m_Controls.manipulationWidget->Initialize(movingCenter, targetCenter); } else { //use selected pre registration as baseline m_Controls.manipulationWidget->Initialize(m_SelectedPreReg); } this->m_CurrentRegistration = m_Controls.manipulationWidget->GetInterimRegistration(); this->m_CurrentRegistrationWrapper = mitk::MAPRegistrationWrapper::New(m_CurrentRegistration); this->m_Controls.comboCenter->setCurrentIndex(0); this->OnCenterTypeChanged(0); //reinit view mitk::RenderingManager::GetInstance()->InitializeViews(m_SelectedTargetNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); //generate evaluation node mitk::RegEvaluationObject::Pointer regEval = mitk::RegEvaluationObject::New(); regEval->SetRegistration(this->m_CurrentRegistrationWrapper); regEval->SetTargetNode(this->m_SelectedTargetNode); regEval->SetMovingNode(this->m_SelectedMovingNode); this->m_EvalNode = mitk::DataNode::New(); this->m_EvalNode->SetData(regEval); mitk::RegEvaluationMapper2D::SetDefaultProperties(this->m_EvalNode); this->m_EvalNode->SetName(HelperNodeName); this->m_EvalNode->SetBoolProperty("helper object", true); this->GetDataStorage()->Add(this->m_EvalNode); this->m_Controls.evalSettings->SetNode(this->m_EvalNode); this->m_activeManipulation = true; } void QmitkMatchPointRegistrationManipulator::StopSession() { this->m_activeManipulation = false; if (this->m_EvalNode.IsNotNull()) { this->GetDataStorage()->Remove(this->m_EvalNode); } this->m_EvalNode = nullptr; this->m_CurrentRegistration = nullptr; this->m_CurrentRegistrationWrapper = nullptr; m_Controls.manipulationWidget->Initialize(); } void QmitkMatchPointRegistrationManipulator::OnRegistrationChanged() { if (this->m_EvalNode.IsNotNull()) { this->m_EvalNode->Modified(); } if (this->m_CurrentRegistrationWrapper.IsNotNull()) { this->m_CurrentRegistrationWrapper->Modified(); } this->GetRenderWindowPart()->RequestUpdate(); } void QmitkMatchPointRegistrationManipulator::OnSliceChanged() { mitk::Point3D currentSelectedPosition = GetRenderWindowPart()->GetSelectedPosition(nullptr); unsigned int currentSelectedTimeStep = GetRenderWindowPart()->GetTimeNavigationController()->GetTime()->GetPos(); if (m_currentSelectedPosition != currentSelectedPosition || m_currentSelectedTimeStep != currentSelectedTimeStep || m_selectedNodeTime > m_currentPositionTime) { //the current position has been changed or the selected node has been changed since the last position validation -> check position m_currentSelectedPosition = currentSelectedPosition; m_currentSelectedTimeStep = currentSelectedTimeStep; m_currentPositionTime.Modified(); if (this->m_EvalNode.IsNotNull()) { this->m_EvalNode->SetProperty(mitk::nodeProp_RegEvalCurrentPosition, mitk::GenericProperty::New(currentSelectedPosition)); } if (m_activeManipulation && m_Controls.comboCenter->currentIndex() == 2) { //update transform with the current position. m_Controls.manipulationWidget->SetCenterOfRotation(m_currentSelectedPosition); } } } void QmitkMatchPointRegistrationManipulator::OnSettingsChanged(mitk::DataNode*) { this->GetRenderWindowPart()->RequestUpdate(); } void QmitkMatchPointRegistrationManipulator::OnStartBtnPushed() { this->InitSession(); this->OnSliceChanged(); this->GetRenderWindowPart()->RequestUpdate(); this->CheckInputs(); this->ConfigureControls(); } void QmitkMatchPointRegistrationManipulator::OnCancelBtnPushed() { this->StopSession(); this->CheckInputs(); this->ConfigureControls(); if (this->GetRenderWindowPart()) { this->GetRenderWindowPart()->RequestUpdate(); } } void QmitkMatchPointRegistrationManipulator::OnStoreBtnPushed() { map::core::RegistrationBase::Pointer newReg = this->m_Controls.manipulationWidget->GenerateRegistration(); - mitk::MAPRegistrationWrapper::Pointer newRegWrapper = mitk::MAPRegistrationWrapper::New(newReg); + auto newRegWrapper = mitk::MAPRegistrationWrapper::New(newReg); mitk::DataNode::Pointer spResultRegistrationNode = mitk::generateRegistrationResultNode( this->m_Controls.lbNewRegName->text().toStdString(), newRegWrapper, "org.mitk::manual_registration", mitk::EnsureUID(m_SelectedMovingNode->GetData()), mitk::EnsureUID(m_SelectedTargetNode->GetData())); this->GetDataStorage()->Add(spResultRegistrationNode); if (m_Controls.checkMapEntity->checkState() == Qt::Checked) { QmitkMappingJob* pMapJob = new QmitkMappingJob(); pMapJob->setAutoDelete(true); pMapJob->m_spInputData = this->m_SelectedMovingNode->GetData(); pMapJob->m_InputDataUID = mitk::EnsureUID(m_SelectedMovingNode->GetData()); pMapJob->m_spRegNode = spResultRegistrationNode; pMapJob->m_doGeometryRefinement = false; pMapJob->m_spRefGeometry = this->m_SelectedTargetNode->GetData()->GetGeometry()->Clone().GetPointer(); pMapJob->m_MappedName = this->m_Controls.lbNewRegName->text().toStdString() + std::string(" mapped moving data"); pMapJob->m_allowUndefPixels = true; pMapJob->m_paddingValue = 100; pMapJob->m_allowUnregPixels = true; pMapJob->m_errorValue = 200; pMapJob->m_InterpolatorLabel = "Linear Interpolation"; pMapJob->m_InterpolatorType = mitk::ImageMappingInterpolator::Linear; connect(pMapJob, SIGNAL(Error(QString)), this, SLOT(Error(QString))); connect(pMapJob, SIGNAL(MapResultIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), this, SLOT(OnMapResultIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), Qt::BlockingQueuedConnection); QThreadPool* threadPool = QThreadPool::globalInstance(); threadPool->start(pMapJob); } this->StopSession(); this->CheckInputs(); this->ConfigureControls(); this->GetRenderWindowPart()->RequestUpdate(); } void QmitkMatchPointRegistrationManipulator::OnMapResultIsAvailable(mitk::BaseData::Pointer spMappedData, const QmitkMappingJob* job) { mitk::DataNode::Pointer spMappedNode = mitk::generateMappedResultNode(job->m_MappedName, spMappedData, job->GetRegistration()->getRegistrationUID(), job->m_InputDataUID, job->m_doGeometryRefinement, job->m_InterpolatorLabel); this->GetDataStorage()->Add(spMappedNode); this->GetRenderWindowPart()->RequestUpdate(); } void QmitkMatchPointRegistrationManipulator::OnCenterTypeChanged(int index) { ConfigureTransformCenter(index); if (this->m_EvalNode.IsNotNull()) { this->m_EvalNode->Modified(); } if (this->m_CurrentRegistrationWrapper.IsNotNull()) { this->m_CurrentRegistrationWrapper->Modified(); } this->GetRenderWindowPart()->RequestUpdate(); } void QmitkMatchPointRegistrationManipulator::ConfigureTransformCenter(int centerType) { if (centerType == 0) { //image center auto center = m_SelectedMovingNode->GetData()->GetTimeGeometry()->GetCenterInWorld(); m_Controls.manipulationWidget->SetCenterOfRotationIsRelativeToTarget(false); m_Controls.manipulationWidget->SetCenterOfRotation(center); } else if (centerType == 1) { //world origin mitk::Point3D center; center.Fill(0.0); m_Controls.manipulationWidget->SetCenterOfRotationIsRelativeToTarget(false); m_Controls.manipulationWidget->SetCenterOfRotation(center); } else { //current selected point m_Controls.manipulationWidget->SetCenterOfRotationIsRelativeToTarget(true); m_Controls.manipulationWidget->SetCenterOfRotation(m_currentSelectedPosition); } } diff --git a/Plugins/org.mitk.gui.qt.matchpoint.mapper/src/internal/QmitkMatchPointMapper.cpp b/Plugins/org.mitk.gui.qt.matchpoint.mapper/src/internal/QmitkMatchPointMapper.cpp index cbf0d65d8d..31243b624a 100644 --- a/Plugins/org.mitk.gui.qt.matchpoint.mapper/src/internal/QmitkMatchPointMapper.cpp +++ b/Plugins/org.mitk.gui.qt.matchpoint.mapper/src/internal/QmitkMatchPointMapper.cpp @@ -1,580 +1,580 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "org_mitk_gui_qt_matchpoint_mapper_Activator.h" // Blueberry #include #include // Mitk #include #include #include "mitkImageMappingHelper.h" #include "mitkMAPRegistrationWrapper.h" #include "mitkMatchPointPropertyTags.h" #include "mitkRegistrationHelper.h" #include #include -#include +#include #include #include #include #include #include // Qmitk #include "QmitkMatchPointMapper.h" // Qt #include #include #include #include const std::string QmitkMatchPointMapper::VIEW_ID = "org.mitk.views.matchpoint.mapper"; QmitkMatchPointMapper::QmitkMatchPointMapper() : m_Parent(nullptr), m_preparedForBinaryInput(false) { } void QmitkMatchPointMapper::SetFocus() { //m_Controls.buttonPerformImageProcessing->setFocus(); } void QmitkMatchPointMapper::CreateConnections() { connect(m_Controls.registrationNodeSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkMatchPointMapper::OnRegNodeSelectionChanged); connect(m_Controls.inputNodeSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkMatchPointMapper::OnInputNodeSelectionChanged); connect(m_Controls.referenceNodeSelector, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkMatchPointMapper::OnReferenceNodeSelectionChanged); connect(m_Controls.m_cbManualRef, SIGNAL(clicked()), this, SLOT(OnManualRefChecked())); connect(m_Controls.m_cbLinkFactors, SIGNAL(clicked()), this, SLOT(OnLinkSampleFactorChecked())); connect(m_Controls.m_sbXFactor, SIGNAL(valueChanged(double)), this, SLOT(OnXFactorChanged(double))); connect(m_Controls.m_pbMap, SIGNAL(clicked()), this, SLOT(OnMapBtnPushed())); connect(m_Controls.m_pbRefine, SIGNAL(clicked()), this, SLOT(OnRefineBtnPushed())); } void QmitkMatchPointMapper::Error(QString msg) { mitk::StatusBar::GetInstance()->DisplayErrorText(msg.toLatin1()); MITK_ERROR << msg.toStdString().c_str(); m_Controls.m_teLog->append(QStringLiteral("") + msg + QStringLiteral("")); } void QmitkMatchPointMapper::CreateQtPartControl(QWidget* parent) { // create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); m_Parent = parent; this->m_Controls.registrationNodeSelector->SetDataStorage(this->GetDataStorage()); this->m_Controls.registrationNodeSelector->SetSelectionIsOptional(true); this->m_Controls.inputNodeSelector->SetDataStorage(this->GetDataStorage()); this->m_Controls.inputNodeSelector->SetSelectionIsOptional(false); this->m_Controls.referenceNodeSelector->SetDataStorage(this->GetDataStorage()); this->m_Controls.referenceNodeSelector->SetSelectionIsOptional(false); this->m_Controls.registrationNodeSelector->SetInvalidInfo("Select valid registration."); this->m_Controls.registrationNodeSelector->SetEmptyInfo("Assuming identity mapping. Select registration to change."); this->m_Controls.registrationNodeSelector->SetPopUpTitel("Select registration."); this->m_Controls.registrationNodeSelector->SetPopUpHint("Select a registration object that should be used for the mapping of the input data. If no registration is selected, identity will be assumed for the mapping."); this->m_Controls.inputNodeSelector->SetInvalidInfo("Select input data."); this->m_Controls.inputNodeSelector->SetPopUpTitel("Select input data."); this->m_Controls.inputNodeSelector->SetPopUpHint("Select the input data for the mapping. (Images or point sets are supported so far)."); this->m_Controls.referenceNodeSelector->SetInvalidInfo("Select the reference image."); this->m_Controls.referenceNodeSelector->SetPopUpTitel("Select the reference image."); this->m_Controls.referenceNodeSelector->SetPopUpHint("Select the reference image that specifies the target geometrie the input should be mapped into."); this->ConfigureRegNodePredicate(); this->ConfigureNodePredicates(); // show first page m_Controls.m_tabs->setCurrentIndex(0); this->CreateConnections(); this->CheckInputs(); this->ConfigureProgressInfos(); this->ConfigureMappingControls(); } /** Method checks if the currently selected reg node has a direct kernel that * can be decomposed in a rotation matrix and a offset. If this is true, true * is returned. In all other cases false is returned.*/ bool QmitkMatchPointMapper::IsAbleToRefineGeometry() const { bool result = false; if (this->m_spSelectedRegNode.IsNotNull()) { const mitk::MAPRegistrationWrapper* wrapper = dynamic_cast (this->m_spSelectedRegNode->GetData()); //if the helper does not return null, we can refine the geometry. result = mitk::MITKRegistrationHelper::getAffineMatrix(wrapper, false).IsNotNull(); } return result; } bool QmitkMatchPointMapper::IsBinaryInput() const { auto maskPredicate = mitk::MITKRegistrationHelper::MaskNodePredicate(); bool result = false; if(this->m_spSelectedInputNode.IsNotNull()) { result = maskPredicate->CheckNode(this->m_spSelectedInputNode); } return result; } bool QmitkMatchPointMapper::IsPointSetInput() const { bool result = false; if (this->m_spSelectedInputNode.IsNotNull()) { result = dynamic_cast(this->m_spSelectedInputNode->GetData()) != nullptr; } return result; } mitk::DataNode::Pointer QmitkMatchPointMapper::GetAutoRefNodeByReg() { mitk::DataNode::Pointer spResult = nullptr; if (this->m_spSelectedRegNode.IsNotNull() && this->m_spSelectedRegNode->GetData()) { std::string nodeName; mitk::BaseProperty* uidProp = m_spSelectedRegNode->GetData()->GetProperty(mitk::Prop_RegAlgTargetData); if (uidProp) { //search for the target node mitk::NodePredicateDataProperty::Pointer predicate = mitk::NodePredicateDataProperty::New(mitk::Prop_UID, uidProp); spResult = this->GetDataStorage()->GetNode(predicate); } } if (spResult.IsNull() && this->m_spSelectedInputNode.IsNotNull()) { //no really reference is available -> use the input as reference spResult = this->m_spSelectedInputNode; if (this->m_spSelectedRefNode != spResult) { m_Controls.m_teLog->append( QStringLiteral("Cannot determine reference automatically. Use input image as reference.")); } } return spResult; } void QmitkMatchPointMapper::ConfigureRegNodePredicate(const mitk::DataNode* input) { mitk::NodePredicateBase::ConstPointer nodePredicate = mitk::MITKRegistrationHelper::RegNodePredicate(); if (input != nullptr) { unsigned int dimension = 0; auto inputImage = dynamic_cast(input->GetData()); auto pointset = dynamic_cast(input->GetData()); if (inputImage) { dimension = inputImage->GetDimension(); if (inputImage->GetTimeSteps() > 1) { //images has multiple time steps -> remove one dimension. dimension -= 1; } } else if (pointset) { dimension = 3; } auto dimCheck = [dimension](const mitk::DataNode * node) { const mitk::MAPRegistrationWrapper* wrapper = dynamic_cast < const mitk::MAPRegistrationWrapper* >(node->GetData()); return wrapper != nullptr && wrapper->GetMovingDimensions() == dimension; }; mitk::NodePredicateFunction::Pointer hasCorrectDim = mitk::NodePredicateFunction::New(dimCheck); nodePredicate = mitk::NodePredicateAnd::New(nodePredicate, hasCorrectDim).GetPointer(); } this->m_Controls.registrationNodeSelector->SetNodePredicate(nodePredicate); } std::function GenerateDimCheckLambda(unsigned int dim) { auto dimCheck = [dim](const mitk::DataNode * node) { auto inputImage = dynamic_cast(node->GetData()); return inputImage != nullptr && (inputImage->GetDimension() == dim || (inputImage->GetDimension() == dim + 1 && inputImage->GetTimeSteps()>1)); }; return dimCheck; } void QmitkMatchPointMapper::ConfigureNodePredicates(const mitk::DataNode* reg) { auto isImage = mitk::MITKRegistrationHelper::ImageNodePredicate(); auto isPointSet = mitk::MITKRegistrationHelper::PointSetNodePredicate(); auto isData = mitk::NodePredicateOr::New(isImage, isPointSet); mitk::NodePredicateBase::ConstPointer inputPredicate = isData.GetPointer(); mitk::NodePredicateBase::ConstPointer refPredicate = isImage.GetPointer(); if (reg != nullptr) { const mitk::MAPRegistrationWrapper* wrapper = dynamic_cast (reg->GetData()); if (wrapper != nullptr) { auto movingDim = wrapper->GetMovingDimensions(); auto dimCheck = GenerateDimCheckLambda(movingDim); auto hasCorrectDim = mitk::NodePredicateFunction::New(dimCheck); if (movingDim == 3) { //Remark: Point sets are always 3D auto is3DInput = mitk::NodePredicateOr::New(isPointSet, mitk::NodePredicateAnd::New(isImage, hasCorrectDim)); inputPredicate = is3DInput.GetPointer(); } else { auto is2DInput = mitk::NodePredicateAnd::New(isImage, hasCorrectDim); inputPredicate = is2DInput.GetPointer(); } auto targetDim = wrapper->GetTargetDimensions(); auto targetDimCheck = GenerateDimCheckLambda(targetDim); auto hasCorrectTargetDim = mitk::NodePredicateFunction::New(targetDimCheck); auto isRef = mitk::NodePredicateAnd::New(isImage, hasCorrectTargetDim); refPredicate = isRef; } } this->m_Controls.inputNodeSelector->SetNodePredicate(inputPredicate); this->m_Controls.referenceNodeSelector->SetNodePredicate(refPredicate); } void QmitkMatchPointMapper::CheckInputs() { this->m_spSelectedRegNode = this->m_Controls.registrationNodeSelector->GetSelectedNode(); this->m_spSelectedInputNode = this->m_Controls.inputNodeSelector->GetSelectedNode(); this->m_spSelectedRefNode = this->m_Controls.referenceNodeSelector->GetSelectedNode(); if (!(m_Controls.m_cbManualRef->isChecked())) { auto autoRefNode = this->GetAutoRefNodeByReg(); if (this->m_spSelectedRefNode != autoRefNode) { this->m_spSelectedRefNode = autoRefNode; QmitkSingleNodeSelectionWidget::NodeList selection; if (this->m_spSelectedRefNode.IsNotNull()) { selection.append(this->m_spSelectedRefNode); } this->m_Controls.referenceNodeSelector->SetCurrentSelection(selection); } } if (this->m_spSelectedRefNode.IsNotNull() && this->m_spSelectedRefNode->GetData() && this->m_spSelectedRefNode->GetData()->GetTimeSteps() > 1) { m_Controls.m_teLog->append( QStringLiteral("Selected reference image has multiple time steps. Only geometry of time step 1 is used as reference.")); } } void QmitkMatchPointMapper::ConfigureMappingControls() { bool validInput = m_spSelectedInputNode.IsNotNull(); bool validRef = m_spSelectedRefNode.IsNotNull(); this->m_Controls.referenceNodeSelector->setEnabled(this->m_Controls.m_cbManualRef->isChecked()); this->m_Controls.m_pbMap->setEnabled(validInput && validRef); this->m_Controls.m_pbRefine->setEnabled(validInput && this->IsAbleToRefineGeometry() && !this->IsPointSetInput()); if (validInput) { if (m_spSelectedRegNode.IsNotNull()) { this->m_Controls.m_leMappedName->setText(tr("mapped_") + QString::fromStdString(m_spSelectedInputNode->GetName()) + tr("_by_") + QString::fromStdString(m_spSelectedRegNode->GetName())); } else { this->m_Controls.m_leMappedName->setText(tr("resampled_") + QString::fromStdString(m_spSelectedInputNode->GetName())); } } else { this->m_Controls.m_leMappedName->setText(tr("mappedData")); } if (this->IsBinaryInput() != this->m_preparedForBinaryInput) { if (this->IsBinaryInput()) { m_Controls.m_teLog->append( QStringLiteral("Binary input (mask) detected. Preparing for mask mapping (default interpolation: nearest neigbour; padding value: 0)")); this->m_Controls.m_comboInterpolator->setCurrentIndex(0); this->m_Controls.m_sbErrorValue->setValue(0); this->m_Controls.m_sbPaddingValue->setValue(0); } else { this->m_Controls.m_comboInterpolator->setCurrentIndex(1); } this->m_preparedForBinaryInput = this->IsBinaryInput(); } OnLinkSampleFactorChecked(); } void QmitkMatchPointMapper::ConfigureProgressInfos() { } void QmitkMatchPointMapper::OnRegNodeSelectionChanged(QList nodes) { mitk::DataNode::Pointer regNode; if (!nodes.isEmpty()) { regNode = nodes.front(); } this->ConfigureNodePredicates(regNode); this->CheckInputs(); this->ConfigureMappingControls(); } void QmitkMatchPointMapper::OnInputNodeSelectionChanged(QList nodes) { mitk::DataNode::Pointer inputNode; if (!nodes.isEmpty()) { inputNode = nodes.front(); } this->ConfigureRegNodePredicate(inputNode); this->CheckInputs(); this->ConfigureMappingControls(); } void QmitkMatchPointMapper::OnReferenceNodeSelectionChanged(QList /*nodes*/) { this->CheckInputs(); this->ConfigureMappingControls(); } void QmitkMatchPointMapper::OnManualRefChecked() { this->CheckInputs(); this->ConfigureMappingControls(); } void QmitkMatchPointMapper::OnLinkSampleFactorChecked() { this->m_Controls.m_sbYFactor->setEnabled(!(this->m_Controls.m_cbLinkFactors->isChecked())); this->m_Controls.m_sbZFactor->setEnabled(!(this->m_Controls.m_cbLinkFactors->isChecked())); if (m_Controls.m_cbLinkFactors->isChecked()) { this->m_Controls.m_sbYFactor->setValue(this->m_Controls.m_sbXFactor->value()); this->m_Controls.m_sbZFactor->setValue(this->m_Controls.m_sbXFactor->value()); } } void QmitkMatchPointMapper::OnMapBtnPushed() { SpawnMappingJob(); } void QmitkMatchPointMapper::OnRefineBtnPushed() { SpawnMappingJob(true); } void QmitkMatchPointMapper::SpawnMappingJob(bool doGeometryRefinement) { if (m_Controls.m_checkClearLog->checkState() == Qt::Checked) { this->m_Controls.m_teLog->clear(); } ///////////////////////// //create job and put it into the thread pool QmitkMappingJob* pJob = new QmitkMappingJob(); pJob->setAutoDelete(true); pJob->m_spInputData = this->m_spSelectedInputNode->GetData(); pJob->m_InputDataUID = mitk::EnsureUID(this->m_spSelectedInputNode->GetData()); pJob->m_doGeometryRefinement = doGeometryRefinement; pJob->m_spRegNode = m_spSelectedRegNode; if (m_spSelectedRegNode.IsNull()) { pJob->m_spRegNode = mitk::DataNode::New(); pJob->m_spRegNode->SetData(mitk::GenerateIdentityRegistration3D().GetPointer()); pJob->m_spRegNode->SetName("Auto_Generated_Identity_Transform"); m_Controls.m_teLog->append( QStringLiteral("No registration selected. Preforming mapping with identity transform")); } if (!doGeometryRefinement) { pJob->m_spRefGeometry = m_spSelectedRefNode->GetData()->GetGeometry()->Clone().GetPointer(); //check for super/sub sampling if (m_Controls.m_groupActivateSampling->isChecked()) { //change the pixel count and spacing of the geometry mitk::BaseGeometry::BoundsArrayType geoBounds = pJob->m_spRefGeometry->GetBounds(); auto oldSpacing = pJob->m_spRefGeometry->GetSpacing(); mitk::Vector3D geoSpacing; geoSpacing[0] = oldSpacing[0] / m_Controls.m_sbXFactor->value(); geoSpacing[1] = oldSpacing[1] / m_Controls.m_sbYFactor->value(); geoSpacing[2] = oldSpacing[2] / m_Controls.m_sbZFactor->value(); geoBounds[1] = geoBounds[1] * m_Controls.m_sbXFactor->value(); geoBounds[3] = geoBounds[3] * m_Controls.m_sbYFactor->value(); geoBounds[5] = geoBounds[5] * m_Controls.m_sbZFactor->value(); pJob->m_spRefGeometry->SetBounds(geoBounds); pJob->m_spRefGeometry->SetSpacing(geoSpacing); auto oldOrigin = pJob->m_spRefGeometry->GetOrigin(); //if we change the spacing we must also correct the origin to ensure //that the voxel matrix still covers the same space. This is due the fact //that the origin is not in the corner of the voxel matrix, but in the center // of the voxel that is in the corner. mitk::Point3D newOrigin; for (mitk::Point3D::SizeType i = 0; i < 3; ++i) { newOrigin[i] = 0.5* (geoSpacing[i] - oldSpacing[i]) + oldOrigin[i]; } pJob->m_spRefGeometry->SetOrigin(newOrigin); } } pJob->m_MappedName = m_Controls.m_leMappedName->text().toStdString(); pJob->m_allowUndefPixels = m_Controls.m_groupAllowUndefPixels->isChecked(); pJob->m_paddingValue = m_Controls.m_sbPaddingValue->value(); pJob->m_allowUnregPixels = m_Controls.m_groupAllowUnregPixels->isChecked(); pJob->m_errorValue = m_Controls.m_sbErrorValue->value(); pJob->m_InterpolatorLabel = m_Controls.m_comboInterpolator->currentText().toStdString(); switch (m_Controls.m_comboInterpolator->currentIndex()) { case 0: pJob->m_InterpolatorType = mitk::ImageMappingInterpolator::NearestNeighbor; break; case 1: pJob->m_InterpolatorType = mitk::ImageMappingInterpolator::Linear; break; case 2: pJob->m_InterpolatorType = mitk::ImageMappingInterpolator::BSpline_3; break; case 3: pJob->m_InterpolatorType = mitk::ImageMappingInterpolator::WSinc_Hamming; break; case 4: pJob->m_InterpolatorType = mitk::ImageMappingInterpolator::WSinc_Welch; break; } connect(pJob, SIGNAL(Error(QString)), this, SLOT(OnMapJobError(QString))); connect(pJob, SIGNAL(MapResultIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), this, SLOT(OnMapResultIsAvailable(mitk::BaseData::Pointer, const QmitkMappingJob*)), Qt::BlockingQueuedConnection); connect(pJob, SIGNAL(AlgorithmInfo(QString)), this, SLOT(OnMappingInfo(QString))); m_Controls.m_teLog->append(QStringLiteral("Started mapping job. Name: ") + m_Controls.m_leMappedName->text() + QStringLiteral("")); QThreadPool* threadPool = QThreadPool::globalInstance(); threadPool->start(pJob); } void QmitkMatchPointMapper::OnMapJobError(QString err) { Error(err); } void QmitkMatchPointMapper::OnMapResultIsAvailable(mitk::BaseData::Pointer spMappedData, const QmitkMappingJob* job) { m_Controls.m_teLog->append(QStringLiteral("Mapped entity stored. Name: ") + QString::fromStdString(job->m_MappedName) + QStringLiteral("")); mitk::DataNode::Pointer spMappedNode = mitk::generateMappedResultNode(job->m_MappedName, spMappedData, job->GetRegistration()->getRegistrationUID(), job->m_InputDataUID, job->m_doGeometryRefinement, job->m_InterpolatorLabel); this->GetDataStorage()->Add(spMappedNode); this->GetRenderWindowPart()->RequestUpdate(); this->CheckInputs(); this->ConfigureMappingControls(); } void QmitkMatchPointMapper::OnMappingInfo(QString info) { m_Controls.m_teLog->append(QStringLiteral("") + info + QStringLiteral("")); } void QmitkMatchPointMapper::OnXFactorChanged(double d) { if (m_Controls.m_cbLinkFactors->isChecked()) { this->m_Controls.m_sbYFactor->setValue(d); this->m_Controls.m_sbZFactor->setValue(d); } } diff --git a/Wrapping/Common/mitk_swig_classes.i b/Wrapping/Common/mitk_swig_classes.i index 89bfc0fad8..9241ec56b9 100644 --- a/Wrapping/Common/mitk_swig_classes.i +++ b/Wrapping/Common/mitk_swig_classes.i @@ -1,157 +1,157 @@ // // Defining some Macros that make problems with SWIG as the // corresponding definitions are not included by default. // Luckely, these includes are not necessary for SWIG. // #define ITK_NOEXCEPT #define ITKCommon_EXPORT #define ITK_OVERRIDE #define MITKCORE_EXPORT #define MITKCLCORE_EXPORT #define MITKCLUTILITIES_EXPORT #define ITKCommon_EXPORT #define MITKMATCHPOINTREGISTRATION_EXPORT #define MAPDeployment_EXPORT #define MAPAlgorithms_EXPORT #define MITKSEGMENTATION_EXPORT #define MITKMULTILABEL_EXPORT #define ITKCommon_EXPORT #define ITK_FORWARD_EXPORT #define ITK_OVERRIDE #define ITK_NOEXCEPT %include %include %include %include %include %include #define DEPRECATED(func) func #undef ITK_DISALLOW_COPY_AND_ASSIGN #define ITK_DISALLOW_COPY_AND_ASSIGN(TypeName) %pythoncode %{ convertion_list = {} %} SWIG_ADD_NONOBJECT_CLASS(Indent, itkIndent.h, itk) SWIG_ADD_MITK_CLASS(LightObject, itkLightObject.h, itk) SWIG_ADD_MITK_CLASS(Object, itkObject.h, itk) SWIG_ADD_MITK_CLASS(DataObject, itkDataObject.h, itk) SWIG_ADD_MITK_CLASS(TimeGeometry, mitkTimeGeometry.h, mitk) SWIG_ADD_MITK_CLASS(ArbitraryTimeGeometry, mitkArbitraryTimeGeometry.h, mitk) SWIG_ADD_MITK_CLASS(ProportionalTimeGeometry, mitkProportionalTimeGeometry.h, mitk) SWIG_ADD_MITK_CLASS(BaseGeometry, mitkBaseGeometry.h, mitk) SWIG_ADD_MITK_CLASS(Geometry3D, mitkGeometry3D.h, mitk) SWIG_ADD_MITK_CLASS(SlicedGeometry3D, mitkSlicedGeometry3D.h, mitk) SWIG_ADD_MITK_CLASS(PlaneGeometry , mitkPlaneGeometry.h, mitk) SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(BoundingBox, mitkBaseGeometry.h, mitk) SWIG_ADD_NONOBJECT_CLASS(TimeBounds, mitkBaseGeometry.h, mitk) SWIG_ADD_NONOBJECT_CLASS(FixedArrayType, mitkBaseGeometry.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point2D, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point3D, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point4D, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point2I, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point3I, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point4I, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(VnlVector, mitkVector.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Vector2D, mitkVector.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Vector3D, mitkVector.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Vector4D, mitkVector.h, mitk) SWIG_ADD_MITK_CLASS(BaseData, mitkBaseData.h, mitk) SWIG_ADD_MITK_CLASS(SlicedData, mitkSlicedData.h, mitk) SWIG_ADD_MITK_CLASS(Image, mitkImage.h, mitk) SWIG_ADD_MITK_CLASS(LabelSetImage, mitkLabelSetImage.h, mitk) SWIG_ADD_MITK_CLASS(PointSet, mitkPointSet.h, mitk) %{ using mitk::Message; %} // // Phenotyping Related Classes // SWIG_ADD_MITK_CLASS(AbstractGlobalImageFeature, mitkAbstractGlobalImageFeature.h, mitk) SWIG_ADD_MITK_CLASS(GIFImageDescriptionFeatures, mitkGIFImageDescriptionFeatures.h, mitk) SWIG_ADD_MITK_CLASS(GIFFirstOrderStatistics, mitkGIFFirstOrderStatistics.h, mitk) SWIG_ADD_MITK_CLASS(GIFFirstOrderHistogramStatistics, mitkGIFFirstOrderHistogramStatistics.h, mitk) SWIG_ADD_MITK_CLASS(GIFVolumetricStatistics, mitkGIFVolumetricStatistics.h, mitk) SWIG_ADD_MITK_CLASS(GIFVolumetricDensityStatistics, mitkGIFVolumetricDensityStatistics.h, mitk) SWIG_ADD_MITK_CLASS(GIFCooccurenceMatrix2, mitkGIFCooccurenceMatrix2.h, mitk) SWIG_ADD_MITK_CLASS(GIFNeighbouringGreyLevelDependenceFeature, mitkGIFNeighbouringGreyLevelDependenceFeatures.h, mitk) SWIG_ADD_MITK_CLASS(GIFGreyLevelRunLength, mitkGIFGreyLevelRunLength.h, mitk) SWIG_ADD_MITK_CLASS(GIFGreyLevelSizeZone, mitkGIFGreyLevelSizeZone.h, mitk) SWIG_ADD_MITK_CLASS(GIFGreyLevelDistanceZone, mitkGIFGreyLevelDistanceZone.h, mitk) SWIG_ADD_MITK_CLASS(GIFLocalIntensity, mitkGIFLocalIntensity.h, mitk) SWIG_ADD_MITK_CLASS(GIFIntensityVolumeHistogramFeatures, mitkGIFIntensityVolumeHistogramFeatures.h, mitk) SWIG_ADD_MITK_CLASS(GIFNeighbourhoodGreyToneDifferenceFeatures, mitkGIFNeighbourhoodGreyToneDifferenceFeatures.h, mitk) SWIG_ADD_MITK_CLASS(GIFCurvatureStatistic, mitkGIFCurvatureStatistic.h, mitk) // // Conversion and Segmentation based Classes // SWIG_ADD_MITK_CLASS(ContourModelSetToImageFilter, mitkContourModelSetToImageFilter.h, mitk) SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(BooleanOperation, mitkBooleanOperation.h, mitk) SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(MorphologicalOperations, mitkMorphologicalOperations.h, mitk) %{ #include typedef itk::DataObject::DataObjectIdentifierType DataObjectIdentifierType; typedef itk::ProcessObject::DataObjectPointerArraySizeType DataObjectPointerArraySizeType; %} // // MatchPoint Related Classes // %ignore DLLHandle::LibraryHandleType; %{ #include namespace core { typedef std::string String; } typedef map::deployment::DLLHandle::LibraryHandleType LibraryHandleType; typedef map::deployment::DLLHandle DLLHandle; %} namespace core { typedef std::string String; } %nodefaultctor LibraryHandleType; struct LibraryHandleType {}; %include SWIG_ADD_MITK_CLASS(UID,mapUID.h, map::algorithm) SWIG_ADD_MITK_CLASS(DLLInfo, mapDeploymentDLLInfo.h, map::deployment) //SWIG_ADD_MITK_CLASS_VECTORFREE(DLLHandle, mapDeploymentDLLHandle.h, map::deployment) SWIG_ADD_MITK_CLASS_VECTORFREE(DLLDirectoryBrowser, mapDeploymentDLLDirectoryBrowser.h, ::map::deployment) MITKSWIG_ADD_HEADERFILE(mapDeploymentDLLAccess.h) %{ DLLHandle const * ConvertDLLHandleSmartPointerToPointer(itk::SmartPointer p) { return p.GetPointer(); } %} DLLHandle const * ConvertDLLHandleSmartPointerToPointer(DLLHandle::Pointer p); -MITKSWIG_ADD_CLASS(MITKAlgorithmHelper, mitkAlgorithmHelper.h, mitk) +MITKSWIG_ADD_CLASS(MAPAlgorithmHelper, mitkMAPAlgorithmHelper.h, mitk) MITKSWIG_ADD_CLASS(RegistrationType, mitkImageMappingHelper.h, mitk::ImageMappingHelper) MITKSWIG_ADD_CLASS(MITKRegistrationType, mitkImageMappingHelper.h, mitk::ImageMappingHelper) // SWIG_ADD_MITK_CLASS(FastSymmetricForcesDemonsMultiResDefaultRegistrationAlgorithm, mitkFastSymmetricForcesDemonsMultiResDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(LevelSetMotionMultiResDefaultRegistrationAlgorithm, mitkLevelSetMotionMultiResDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(MultiModalAffineDefaultRegistrationAlgorithm, mitkMultiModalAffineDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(MultiModalRigidDefaultRegistrationAlgorithm, mitkMultiModalRigidDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(MultiModalTransDefaultRegistrationAlgorithm, mitkMultiModalTransDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(RigidClosedFormPointsDefaultRegistrationAlgorithm, mitkRigidClosedFormPointsDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(RigidICPDefaultRegistrationAlgorithm, mitkRigidICPDefaultRegistrationAlgorithm.h, mitk) \ No newline at end of file