diff --git a/Modules/DiffusionImaging/DiffusionCore/include/IODataStructures/Properties/mitkDiffusionPropertyHelper.h b/Modules/DiffusionImaging/DiffusionCore/include/IODataStructures/Properties/mitkDiffusionPropertyHelper.h index b35ba0904c..e73ecfa823 100644 --- a/Modules/DiffusionImaging/DiffusionCore/include/IODataStructures/Properties/mitkDiffusionPropertyHelper.h +++ b/Modules/DiffusionImaging/DiffusionCore/include/IODataStructures/Properties/mitkDiffusionPropertyHelper.h @@ -1,122 +1,124 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKDIFFUSIONPROPERTYHELPER_H #define MITKDIFFUSIONPROPERTYHELPER_H #include #include #include #include #include #include #include namespace mitk { /** \brief Helper class for mitk::Images containing diffusion weighted data * * This class takes a pointer to a mitk::Image containing diffusion weighted information and provides * functions to manipulate the diffusion meta-data. Will log an error if required information is * missing. */ class MITKDIFFUSIONCORE_EXPORT DiffusionPropertyHelper { public: typedef short DiffusionPixelType; typedef mitk::BValueMapProperty::BValueMap BValueMapType; typedef GradientDirectionsProperty::GradientDirectionType GradientDirectionType; typedef GradientDirectionsProperty::GradientDirectionsContainerType GradientDirectionsContainerType; typedef mitk::MeasurementFrameProperty::MeasurementFrameType MeasurementFrameType; typedef itk::VectorImage< DiffusionPixelType, 3> ImageType; static bool IsDiffusionWeightedImage(const mitk::Image *); static bool IsDiffusionWeightedImage(const mitk::DataNode* node); static void ClearMeasurementFrameAndRotationMatrixFromGradients(mitk::Image* image); static void CopyProperties(mitk::Image* source, mitk::Image* target, bool ignore_original_gradients=false); static ImageType::Pointer GetItkVectorImage(Image *image); static const BValueMapType & GetBValueMap(const mitk::Image *); static float GetReferenceBValue(const mitk::Image *); static std::vector< int > GetBValueVector(const mitk::Image *); static const MeasurementFrameType & GetMeasurementFrame(const mitk::Image *); static GradientDirectionsContainerType::Pointer GetOriginalGradientContainer(const mitk::Image *); static GradientDirectionsContainerType::Pointer GetGradientContainer(const mitk::Image *); static void SetMeasurementFrame(mitk::Image* image, MeasurementFrameType mf); static void SetReferenceBValue(mitk::Image* image, float b_value); static void SetBValueMap(mitk::Image* image, BValueMapType map); static void SetOriginalGradientContainer(mitk::Image* image, GradientDirectionsContainerType::Pointer g_cont); static void SetGradientContainer(mitk::Image* image, GradientDirectionsContainerType::Pointer g_cont); + static void RotateGradients(mitk::Image* image, vnl_matrix_fixed rotation_matrix, bool normalize_columns); + static void RotateOriginalGradients(mitk::Image* image, vnl_matrix_fixed rotation_matrix, bool normalize_columns); static void AverageRedundantGradients(mitk::Image* image, double precision); static void InitializeImage(mitk::Image* image); static GradientDirectionsContainerType::Pointer CalcAveragedDirectionSet(double precision, GradientDirectionsContainerType::Pointer directions); static void SetupProperties(); // called in DiffusionCoreIOActivator static const std::string GetBvaluePropertyName() { return BVALUEMAPPROPERTYNAME; } static const std::string GetGradientContainerPropertyName() { return GRADIENTCONTAINERPROPERTYNAME; } static const std::string GetMeasurementFramePropertyName() { return MEASUREMENTFRAMEPROPERTYNAME; } protected: DiffusionPropertyHelper(); ~DiffusionPropertyHelper(); static const std::string GRADIENTCONTAINERPROPERTYNAME; static const std::string ORIGINALGRADIENTCONTAINERPROPERTYNAME; static const std::string MEASUREMENTFRAMEPROPERTYNAME; static const std::string REFERENCEBVALUEPROPERTYNAME; static const std::string BVALUEMAPPROPERTYNAME; static const std::string MODALITY; static const std::string KEEP_ORIGINAL_DIRECTIONS; /** * \brief Apply the previously set MeasurementFrame and the image rotation matrix to all gradients * * \warning first set the MeasurementFrame */ static void ApplyMeasurementFrameAndRotationMatrix(mitk::Image* image); /** * \brief Apply the inverse of the previously set MeasurementFrame and the image rotation matrix to all gradients * * \warning first set the MeasurementFrame */ static void UnApplyMeasurementFrameAndRotationMatrix(mitk::Image* image); /** * \brief Update the BValueMap (m_B_ValueMap) using the current gradient directions (m_Directions) * * \warning Have to be called after each manipulation on the GradientDirectionContainer * !especially after manipulation of the m_Directions (GetDirections()) container via pointer access! */ static void UpdateBValueMap(mitk::Image* image); /// Determines whether gradients can be considered to be equal static bool AreAlike(GradientDirectionType g1, GradientDirectionType g2, double precision); /// Get the b value belonging to an index static float GetB_Value(const mitk::Image* image, unsigned int i); }; } #endif diff --git a/Modules/DiffusionImaging/DiffusionCore/src/IODataStructures/Properties/mitkDiffusionPropertyHelper.cpp b/Modules/DiffusionImaging/DiffusionCore/src/IODataStructures/Properties/mitkDiffusionPropertyHelper.cpp index 5057c10a97..a6fd6c1555 100644 --- a/Modules/DiffusionImaging/DiffusionCore/src/IODataStructures/Properties/mitkDiffusionPropertyHelper.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/src/IODataStructures/Properties/mitkDiffusionPropertyHelper.cpp @@ -1,579 +1,615 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkDiffusionPropertyHelper.h" #include #include #include #include #include #include #include #include #include const std::string mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME = "DWMRI.GradientDirections"; const std::string mitk::DiffusionPropertyHelper::ORIGINALGRADIENTCONTAINERPROPERTYNAME = "DWMRI.OriginalGradientDirections"; const std::string mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME = "DWMRI.MeasurementFrame"; const std::string mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME = "DWMRI.ReferenceBValue"; const std::string mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME = "DWMRI.BValueMap"; const std::string mitk::DiffusionPropertyHelper::MODALITY = "DWMRI.Modality"; const std::string mitk::DiffusionPropertyHelper::KEEP_ORIGINAL_DIRECTIONS = "DWMRI.KeepOriginalDirections"; mitk::DiffusionPropertyHelper::DiffusionPropertyHelper() { } mitk::DiffusionPropertyHelper::~DiffusionPropertyHelper() { } mitk::DiffusionPropertyHelper::ImageType::Pointer mitk::DiffusionPropertyHelper::GetItkVectorImage(mitk::Image* image) { ImageType::Pointer vectorImage = ImageType::New(); mitk::CastToItkImage(image, vectorImage); return vectorImage; } mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::Pointer mitk::DiffusionPropertyHelper::CalcAveragedDirectionSet(double precision, GradientDirectionsContainerType::Pointer directions) { // save old and construct new direction container GradientDirectionsContainerType::Pointer newDirections = GradientDirectionsContainerType::New(); // fill new direction container for(GradientDirectionsContainerType::ConstIterator gdcitOld = directions->Begin(); gdcitOld != directions->End(); ++gdcitOld) { // already exists? bool found = false; for(GradientDirectionsContainerType::ConstIterator gdcitNew = newDirections->Begin(); gdcitNew != newDirections->End(); ++gdcitNew) { if(AreAlike(gdcitNew.Value(), gdcitOld.Value(), precision)) { found = true; break; } } // if not found, add it to new container if(!found) { newDirections->push_back(gdcitOld.Value()); } } return newDirections; } void mitk::DiffusionPropertyHelper::AverageRedundantGradients(mitk::Image* image, double precision) { GradientDirectionsContainerType::Pointer oldDirs = GetOriginalGradientContainer(image); GradientDirectionsContainerType::Pointer newDirs = CalcAveragedDirectionSet(precision, oldDirs); // if sizes equal, we do not need to do anything in this function if(oldDirs->size() == newDirs->size()) return; // new image ImageType::Pointer oldImage = ImageType::New(); mitk::CastToItkImage( image, oldImage); ImageType::Pointer newITKImage = ImageType::New(); newITKImage->SetSpacing( oldImage->GetSpacing() ); // Set the image spacing newITKImage->SetOrigin( oldImage->GetOrigin() ); // Set the image origin newITKImage->SetDirection( oldImage->GetDirection() ); // Set the image direction newITKImage->SetLargestPossibleRegion( oldImage->GetLargestPossibleRegion() ); newITKImage->SetVectorLength( newDirs->size() ); newITKImage->SetBufferedRegion( oldImage->GetLargestPossibleRegion() ); newITKImage->Allocate(); // average image data that corresponds to identical directions itk::ImageRegionIterator< ImageType > newIt(newITKImage, newITKImage->GetLargestPossibleRegion()); newIt.GoToBegin(); itk::ImageRegionIterator< ImageType > oldIt(oldImage, oldImage->GetLargestPossibleRegion()); oldIt.GoToBegin(); // initial new value of voxel ImageType::PixelType newVec; newVec.SetSize(newDirs->size()); newVec.AllocateElements(newDirs->size()); // find which gradients should be averaged GradientDirectionsContainerType::Pointer oldDirections = oldDirs; std::vector > dirIndices; for(GradientDirectionsContainerType::ConstIterator gdcitNew = newDirs->Begin(); gdcitNew != newDirs->End(); ++gdcitNew) { dirIndices.push_back(std::vector(0)); for(GradientDirectionsContainerType::ConstIterator gdcitOld = oldDirs->Begin(); gdcitOld != oldDirections->End(); ++gdcitOld) { if(AreAlike(gdcitNew.Value(), gdcitOld.Value(), precision)) { //MITK_INFO << gdcitNew.Value() << " " << gdcitOld.Value(); dirIndices[gdcitNew.Index()].push_back(gdcitOld.Index()); } } } //int ind1 = -1; while(!newIt.IsAtEnd()) { // init new vector with zeros newVec.Fill(0.0); // the old voxel value with duplicates ImageType::PixelType oldVec = oldIt.Get(); for(unsigned int i=0; iGetProperty(mitk::DiffusionPropertyHelper::ORIGINALGRADIENTCONTAINERPROPERTYNAME.c_str()).IsNull() ) { return; } GradientDirectionsContainerType::Pointer originalDirections = GetOriginalGradientContainer(image); MeasurementFrameType measurementFrame = GetMeasurementFrame(image); mitk::Vector3D s = image->GetGeometry()->GetSpacing(); mitk::VnlVector c0 = image->GetGeometry()->GetMatrixColumn(0)/s[0]; mitk::VnlVector c1 = image->GetGeometry()->GetMatrixColumn(1)/s[1]; mitk::VnlVector c2 = image->GetGeometry()->GetMatrixColumn(2)/s[2]; MeasurementFrameType imageRotationMatrix; imageRotationMatrix[0][0] = c0[0]; imageRotationMatrix[1][0] = c0[1]; imageRotationMatrix[2][0] = c0[2]; imageRotationMatrix[0][1] = c1[0]; imageRotationMatrix[1][1] = c1[1]; imageRotationMatrix[2][1] = c1[2]; imageRotationMatrix[0][2] = c2[0]; imageRotationMatrix[1][2] = c2[1]; imageRotationMatrix[2][2] = c2[2]; GradientDirectionsContainerType::Pointer directions = GradientDirectionsContainerType::New(); if( originalDirections.IsNull() || ( originalDirections->size() == 0 ) ) { // original direction container was not set return; } bool keep_originals = false; image->GetPropertyList()->GetBoolProperty(mitk::DiffusionPropertyHelper::KEEP_ORIGINAL_DIRECTIONS.c_str(), keep_originals); // if (!keep_originals) // { // MITK_INFO << "Applying measurement frame to diffusion-gradient directions:"; // std::cout << measurementFrame << std::endl; // MITK_INFO << "Applying image rotation to diffusion-gradient directions:"; // std::cout << imageRotationMatrix << std::endl; // } int c = 0; for(GradientDirectionsContainerType::ConstIterator gdcit = originalDirections->Begin(); gdcit != originalDirections->End(); ++gdcit) { vnl_vector vec = gdcit.Value(); if (!keep_originals) { vec = vec.pre_multiply(measurementFrame); vec = vec.pre_multiply(imageRotationMatrix); } directions->InsertElement(c, vec); c++; } SetGradientContainer(image, directions); } void mitk::DiffusionPropertyHelper::UnApplyMeasurementFrameAndRotationMatrix(mitk::Image* image) { if( image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).IsNull() ) { return; } GradientDirectionsContainerType::Pointer modifiedDirections = GetGradientContainer(image); MeasurementFrameType measurementFrame = GetMeasurementFrame(image); measurementFrame = vnl_matrix_inverse(measurementFrame).pinverse(); mitk::Vector3D s = image->GetGeometry()->GetSpacing(); mitk::VnlVector c0 = image->GetGeometry()->GetMatrixColumn(0)/s[0]; mitk::VnlVector c1 = image->GetGeometry()->GetMatrixColumn(1)/s[1]; mitk::VnlVector c2 = image->GetGeometry()->GetMatrixColumn(2)/s[2]; MeasurementFrameType imageRotationMatrix; imageRotationMatrix[0][0] = c0[0]; imageRotationMatrix[1][0] = c0[1]; imageRotationMatrix[2][0] = c0[2]; imageRotationMatrix[0][1] = c1[0]; imageRotationMatrix[1][1] = c1[1]; imageRotationMatrix[2][1] = c1[2]; imageRotationMatrix[0][2] = c2[0]; imageRotationMatrix[1][2] = c2[1]; imageRotationMatrix[2][2] = c2[2]; imageRotationMatrix = vnl_matrix_inverse(imageRotationMatrix).pinverse(); GradientDirectionsContainerType::Pointer directions = GradientDirectionsContainerType::New(); if( modifiedDirections.IsNull() || ( modifiedDirections->size() == 0 ) ) { // original direction container was not set return; } bool keep_originals = false; image->GetPropertyList()->GetBoolProperty(mitk::DiffusionPropertyHelper::KEEP_ORIGINAL_DIRECTIONS.c_str(), keep_originals); // if (!keep_originals) // { // MITK_INFO << "Reverting image rotation to diffusion-gradient directions:"; // std::cout << imageRotationMatrix << std::endl; // MITK_INFO << "Reverting measurement frame to diffusion-gradient directions:"; // std::cout << measurementFrame << std::endl; // } int c = 0; for(GradientDirectionsContainerType::ConstIterator gdcit = modifiedDirections->Begin(); gdcit != modifiedDirections->End(); ++gdcit) { vnl_vector vec = gdcit.Value(); if (!keep_originals) { vec = vec.pre_multiply(imageRotationMatrix); vec = vec.pre_multiply(measurementFrame); } directions->InsertElement(c, vec); c++; } SetOriginalGradientContainer(image, directions); } void mitk::DiffusionPropertyHelper::ClearMeasurementFrameAndRotationMatrixFromGradients(mitk::Image* image) { GradientDirectionsContainerType::Pointer originalDirections = GetOriginalGradientContainer(image); GradientDirectionsContainerType::Pointer directions = GradientDirectionsContainerType::New(); if(originalDirections.IsNull() || originalDirections->size()==0) return; int c = 0; for(GradientDirectionsContainerType::ConstIterator gdcit = originalDirections->Begin(); gdcit != originalDirections->End(); ++gdcit) { vnl_vector vec = gdcit.Value(); directions->InsertElement(c, vec); c++; } image->GetPropertyList()->ReplaceProperty( mitk::DiffusionPropertyHelper::KEEP_ORIGINAL_DIRECTIONS.c_str(), mitk::BoolProperty::New(true) ); SetGradientContainer(image, directions); } void mitk::DiffusionPropertyHelper::UpdateBValueMap(mitk::Image* image) { BValueMapType b_ValueMap; if(image->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).IsNotNull()) b_ValueMap = GetBValueMap(image); if(!b_ValueMap.empty()) b_ValueMap.clear(); if(GetGradientContainer(image).IsNotNull()) { GradientDirectionsContainerType::Pointer directions = GetGradientContainer(image); for(auto gdcit = directions->Begin(); gdcit!=directions->End(); ++gdcit) { b_ValueMap[GetB_Value(image, gdcit.Index())].push_back(gdcit.Index()); } } SetBValueMap(image, b_ValueMap); } bool mitk::DiffusionPropertyHelper::AreAlike(GradientDirectionType g1, GradientDirectionType g2, double precision) { GradientDirectionType diff = g1 - g2; GradientDirectionType diff2 = g1 + g2; return diff.two_norm() < precision || diff2.two_norm() < precision; } float mitk::DiffusionPropertyHelper::GetB_Value(const mitk::Image* image, unsigned int i) { GradientDirectionsContainerType::Pointer directions = GetGradientContainer(image); float b_value = GetReferenceBValue(image); if(i > directions->Size()-1) return -1; if(directions->ElementAt(i).one_norm() <= 0.0) { return 0; } else { double twonorm = directions->ElementAt(i).two_norm(); double bval = b_value*twonorm*twonorm; if (bval<0) bval = ceil(bval - 0.5); else bval = floor(bval + 0.5); return bval; } } void mitk::DiffusionPropertyHelper::CopyProperties(mitk::Image* source, mitk::Image* target, bool ignore_original_gradients) { mitk::PropertyList::Pointer props = source->GetPropertyList()->Clone(); if (ignore_original_gradients) props->RemoveProperty(mitk::DiffusionPropertyHelper::ORIGINALGRADIENTCONTAINERPROPERTYNAME); target->SetPropertyList(props); } void mitk::DiffusionPropertyHelper::InitializeImage(mitk::Image* image) { if ( image->GetProperty(mitk::DiffusionPropertyHelper::KEEP_ORIGINAL_DIRECTIONS.c_str()).IsNull() ) image->SetProperty( mitk::DiffusionPropertyHelper::KEEP_ORIGINAL_DIRECTIONS.c_str(), mitk::BoolProperty::New(false) ); if( image->GetProperty(mitk::DiffusionPropertyHelper::ORIGINALGRADIENTCONTAINERPROPERTYNAME.c_str()).IsNull() ) { // we don't have the original gradient directions. Therefore use the modified directions and roatate them back. UnApplyMeasurementFrameAndRotationMatrix(image); } else ApplyMeasurementFrameAndRotationMatrix(image); UpdateBValueMap(image); // initialize missing properties mitk::MeasurementFrameProperty::Pointer mf = dynamic_cast( image->GetProperty(MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer()); if( mf.IsNull() ) { //no measurement frame present, identity is assumed MeasurementFrameType identity; identity.set_identity(); image->GetPropertyList()->ReplaceProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( identity )); } } bool mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(const mitk::DataNode* node) { if ( node==nullptr ) return false; if ( node->GetData()==nullptr ) return false; return IsDiffusionWeightedImage(dynamic_cast(node->GetData())); } bool mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(const mitk::Image * image) { bool isDiffusionWeightedImage( true ); if( image == nullptr ) { isDiffusionWeightedImage = false; } if( isDiffusionWeightedImage ) { mitk::FloatProperty::Pointer referenceBValue = dynamic_cast(image->GetProperty(REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer()); if( referenceBValue.IsNull() ) { isDiffusionWeightedImage = false; } } unsigned int gradientDirections( 0 ); if( isDiffusionWeightedImage ) { mitk::GradientDirectionsProperty::Pointer gradientDirectionsProperty = dynamic_cast(image->GetProperty(GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer()); if( gradientDirectionsProperty.IsNull() ) { isDiffusionWeightedImage = false; } else { gradientDirections = gradientDirectionsProperty->GetGradientDirectionsContainer()->size(); } } if( isDiffusionWeightedImage ) { unsigned int components = image->GetPixelType().GetNumberOfComponents(); if( components != gradientDirections ) { isDiffusionWeightedImage = false; } } return isDiffusionWeightedImage; } const mitk::DiffusionPropertyHelper::BValueMapType & mitk::DiffusionPropertyHelper::GetBValueMap(const mitk::Image *image) { return dynamic_cast(image->GetProperty(BVALUEMAPPROPERTYNAME.c_str()).GetPointer())->GetBValueMap(); } std::vector< int > mitk::DiffusionPropertyHelper::GetBValueVector(const mitk::Image* image) { auto gcon = mitk::DiffusionPropertyHelper::GetGradientContainer(image); float b_value = mitk::DiffusionPropertyHelper::GetReferenceBValue(image); std::vector< int > bvalues; for (unsigned int i=0; iSize(); ++i) { double twonorm = gcon->ElementAt(i).two_norm(); double bval = b_value*twonorm*twonorm; if (bval<0) bval = ceil(bval - 0.5); else bval = floor(bval + 0.5); bvalues.push_back(bval); } return bvalues; } float mitk::DiffusionPropertyHelper::GetReferenceBValue(const mitk::Image *image) { return dynamic_cast(image->GetProperty(REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer())->GetValue(); } const mitk::DiffusionPropertyHelper::MeasurementFrameType & mitk::DiffusionPropertyHelper::GetMeasurementFrame(const mitk::Image *image) { mitk::MeasurementFrameProperty::Pointer mf = dynamic_cast( image->GetProperty(MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer()); if( mf.IsNull() ) { //no measurement frame present, identity is assumed MeasurementFrameType identity; identity.set_identity(); mf = mitk::MeasurementFrameProperty::New( identity ); } return mf->GetMeasurementFrame(); } mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::Pointer mitk::DiffusionPropertyHelper::GetOriginalGradientContainer(const mitk::Image *image) { return dynamic_cast(image->GetProperty(ORIGINALGRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer())->GetGradientDirectionsContainer(); } mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::Pointer mitk::DiffusionPropertyHelper::GetGradientContainer(const mitk::Image *image) { return dynamic_cast(image->GetProperty(GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer())->GetGradientDirectionsContainer(); } void mitk::DiffusionPropertyHelper::SetReferenceBValue(mitk::Image* image, float b_value) { image->GetPropertyList()->ReplaceProperty(REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New(b_value)); } void mitk::DiffusionPropertyHelper::SetBValueMap(mitk::Image* image, BValueMapType map) { image->GetPropertyList()->ReplaceProperty( mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str(), mitk::BValueMapProperty::New(map)); } void mitk::DiffusionPropertyHelper::SetOriginalGradientContainer(mitk::Image* image, GradientDirectionsContainerType::Pointer g_cont) { image->GetPropertyList()->ReplaceProperty(ORIGINALGRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New(g_cont)); } void mitk::DiffusionPropertyHelper::SetGradientContainer(mitk::Image* image, GradientDirectionsContainerType::Pointer g_cont) { image->GetPropertyList()->ReplaceProperty(GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New(g_cont)); } void mitk::DiffusionPropertyHelper::SetMeasurementFrame(mitk::Image* image, MeasurementFrameType mf) { image->GetPropertyList()->ReplaceProperty( MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( mf ) ); } +void mitk::DiffusionPropertyHelper::RotateGradients(mitk::Image* image, vnl_matrix_fixed rotation_matrix, bool normalize_columns) +{ + if (normalize_columns) + rotation_matrix = rotation_matrix.normalize_columns(); + + int c = 0; + auto new_gradients = GradientDirectionsContainerType::New(); + auto old_gradients = GetGradientContainer(image); + for(auto gdcit = old_gradients->Begin(); gdcit != old_gradients->End(); ++gdcit) + { + vnl_vector vec = gdcit.Value(); + vec = vec.pre_multiply(rotation_matrix); + new_gradients->InsertElement(c, vec); + c++; + } + SetGradientContainer(image, new_gradients); +} + +void mitk::DiffusionPropertyHelper::RotateOriginalGradients(mitk::Image* image, vnl_matrix_fixed rotation_matrix, bool normalize_columns) +{ + if (normalize_columns) + rotation_matrix = rotation_matrix.normalize_columns(); + + int c = 0; + auto new_gradients = GradientDirectionsContainerType::New(); + auto old_gradients = GetOriginalGradientContainer(image); + for(auto gdcit = old_gradients->Begin(); gdcit != old_gradients->End(); ++gdcit) + { + vnl_vector vec = gdcit.Value(); + vec = vec.pre_multiply(rotation_matrix); + new_gradients->InsertElement(c, vec); + c++; + } + SetOriginalGradientContainer(image, new_gradients); +} + void mitk::DiffusionPropertyHelper::SetupProperties() { //register relevant properties //non-persistent properties mitk::CoreServices::GetPropertyDescriptions()->AddDescription(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME, "This map stores which b values belong to which gradients."); mitk::CoreServices::GetPropertyDescriptions()->AddDescription(mitk::DiffusionPropertyHelper::ORIGINALGRADIENTCONTAINERPROPERTYNAME, "The original gradients used during acquisition. This property may be empty."); //persistent properties mitk::CoreServices::GetPropertyDescriptions()->AddDescription(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME, "The reference b value the gradients are normalized to."); mitk::CoreServices::GetPropertyDescriptions()->AddDescription(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME, "The measurment frame used during acquisition."); mitk::CoreServices::GetPropertyDescriptions()->AddDescription(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME, "The gradients after applying measurement frame and image matrix."); mitk::CoreServices::GetPropertyDescriptions()->AddDescription(mitk::DiffusionPropertyHelper::MODALITY, "Defines the modality used for acquisition. DWMRI signifies diffusion weighted images."); mitk::PropertyPersistenceInfo::Pointer PPI_referenceBValue = mitk::PropertyPersistenceInfo::New(); PPI_referenceBValue->SetNameAndKey(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME, "DWMRI_b-value"); mitk::PropertyPersistenceInfo::Pointer PPI_measurementFrame = mitk::PropertyPersistenceInfo::New(); PPI_measurementFrame->SetNameAndKey(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME, "measurement frame"); mitk::PropertyPersistenceInfo::Pointer PPI_gradientContainer = mitk::PropertyPersistenceInfo::New(); PPI_gradientContainer->SetNameAndKey(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME, "DWMRI_gradient"); mitk::PropertyPersistenceInfo::Pointer PPI_modality = mitk::PropertyPersistenceInfo::New(); PPI_modality->SetNameAndKey(mitk::DiffusionPropertyHelper::MODALITY, "modality"); mitk::CoreServices::GetPropertyPersistence()->AddInfo(PPI_referenceBValue.GetPointer() , true); mitk::CoreServices::GetPropertyPersistence()->AddInfo(PPI_measurementFrame.GetPointer(), true); mitk::CoreServices::GetPropertyPersistence()->AddInfo(PPI_gradientContainer.GetPointer(), true); mitk::CoreServices::GetPropertyPersistence()->AddInfo(PPI_modality.GetPointer(), true); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.python/src/internal/QmitkDipyReconstructionsViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging.python/src/internal/QmitkDipyReconstructionsViewControls.ui index 6285b76025..86018dabe3 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.python/src/internal/QmitkDipyReconstructionsViewControls.ui +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.python/src/internal/QmitkDipyReconstructionsViewControls.ui @@ -1,669 +1,669 @@ QmitkDipyReconstructionsViewControls 0 0 435 1036 Form QCommandLinkButton:disabled { border: none; } QGroupBox { background-color: transparent; } 25 QFrame::NoFrame QFrame::Raised 0 0 0 0 3D-SHORE Sparse Fascicle Model Constrained Spherical Deconvolution CSA-QBALL Orientation Probability Density Transform Input Image: Model: Mask Image: 3D-SHORE Parameters 6 6 6 6 2 100 2 6 Zeta: Radial Order: LambdaN: LambdaL: 9999 700 1e-8 1e-8 Orientation Probability Density Transform Parameters 6 6 6 6 QFrame::NoFrame QFrame::Raised 0 0 0 0 0 2 100 2 6 Lambda: SH Order: 4 1.000000000000000 0.001000000000000 0.006000000000000 false Start Reconstruction Qt::Vertical 20 40 Sparse Fascicle Model Parameters 6 6 6 6 FA Threshold: 3 1.000000000000000 0.100000000000000 0.700000000000000 CSA-QBALL Parameters 6 6 6 6 QFrame::NoFrame QFrame::Raised 0 0 0 0 0 2 100 2 6 Lambda: SH Order: 4 1.000000000000000 0.001000000000000 0.006000000000000 Constrained Spherical Deconvolution Parameters 6 6 6 6 SH Order: QFrame::NoFrame QFrame::Raised 0 0 0 0 0 2 100 2 6 FA Threshold: 3 1.000000000000000 0.100000000000000 0.700000000000000 Extract Peaks 1 100 1 3 Relative Threshold: Min. Separation Angle: 0 90 1 15 1.000000000000000 0.100000000000000 0.400000000000000 Calculate Peaks: Max. Peaks: - Mas. Normalize Peaks: + Normalize Peaks: QmitkDataStorageComboBox QComboBox
QmitkDataStorageComboBox.h
QmitkDataStorageComboBoxWithSelectNone QComboBox
QmitkDataStorageComboBoxWithSelectNone.h
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.registration/src/internal/QmitkSimpleRegistrationView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.registration/src/internal/QmitkSimpleRegistrationView.cpp index 78454562e8..15933e1b06 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.registration/src/internal/QmitkSimpleRegistrationView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.registration/src/internal/QmitkSimpleRegistrationView.cpp @@ -1,391 +1,396 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ //misc #define _USE_MATH_DEFINES #include // Blueberry #include #include // Qmitk #include "QmitkSimpleRegistrationView.h" // MITK #include #include #include #include #include #include #include #include #include #include #include +#include // Qt #include #define _USE_MATH_DEFINES #include const std::string QmitkSimpleRegistrationView::VIEW_ID = "org.mitk.views.simpleregistrationview"; QmitkSimpleRegistrationView::QmitkSimpleRegistrationView() : QmitkAbstractView() , m_Controls( 0 ) , m_RegistrationType(0) { } // Destructor QmitkSimpleRegistrationView::~QmitkSimpleRegistrationView() { } void QmitkSimpleRegistrationView::StartRegistration() { QmitkRegistrationJob* pJob; if (m_Controls->m_RegBox->currentIndex()==0) { mitk::MultiModalRigidDefaultRegistrationAlgorithm< ItkFloatImageType >::Pointer algo = mitk::MultiModalRigidDefaultRegistrationAlgorithm< ItkFloatImageType >::New(); pJob = new QmitkRegistrationJob(algo); m_RegistrationType = 0; } else { mitk::MultiModalAffineDefaultRegistrationAlgorithm< ItkFloatImageType >::Pointer algo = mitk::MultiModalAffineDefaultRegistrationAlgorithm< ItkFloatImageType >::New(); pJob = new QmitkRegistrationJob(algo); m_RegistrationType = 1; } pJob->setAutoDelete(true); m_MovingImageNode = m_Controls->m_MovingImageBox->GetSelectedNode(); mitk::Image::Pointer movingImage = dynamic_cast(m_MovingImageNode->GetData()); if (mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(movingImage)) { ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); mitk::CastToItkImage(movingImage, itkVectorImagePointer); itk::ExtractDwiChannelFilter< short >::Pointer filter = itk::ExtractDwiChannelFilter< short >::New(); filter->SetInput( itkVectorImagePointer); filter->SetChannelIndex(m_Controls->m_MovingChannelBox->value()); filter->Update(); mitk::Image::Pointer newImage = mitk::Image::New(); newImage->InitializeByItk( filter->GetOutput() ); newImage->SetImportChannel( filter->GetOutput()->GetBufferPointer() ); pJob->m_spMovingData = newImage; } else pJob->m_spMovingData = movingImage; mitk::Image::Pointer fixedImage = dynamic_cast(m_Controls->m_FixedImageBox->GetSelectedNode()->GetData()); if (mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(fixedImage)) { ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); mitk::CastToItkImage(fixedImage, itkVectorImagePointer); itk::ExtractDwiChannelFilter< short >::Pointer filter = itk::ExtractDwiChannelFilter< short >::New(); filter->SetInput( itkVectorImagePointer); filter->SetChannelIndex(m_Controls->m_MovingChannelBox->value()); filter->Update(); mitk::Image::Pointer newImage = mitk::Image::New(); newImage->InitializeByItk( filter->GetOutput() ); newImage->SetImportChannel( filter->GetOutput()->GetBufferPointer() ); pJob->m_spTargetData = newImage; } else pJob->m_spTargetData = fixedImage; pJob->m_TargetDataUID = mitk::EnsureUID(m_Controls->m_FixedImageBox->GetSelectedNode()->GetData()); pJob->m_MovingDataUID = mitk::EnsureUID(m_Controls->m_MovingImageBox->GetSelectedNode()->GetData()); connect(pJob, SIGNAL(RegResultIsAvailable(mitk::MAPRegistrationWrapper::Pointer, const QmitkRegistrationJob*)), this, SLOT(OnRegResultIsAvailable(mitk::MAPRegistrationWrapper::Pointer, const QmitkRegistrationJob*)), Qt::BlockingQueuedConnection); QThreadPool* threadPool = QThreadPool::globalInstance(); threadPool->start(pJob); m_Controls->m_RegistrationStartButton->setEnabled(false); m_Controls->m_RegistrationStartButton->setText("Registration in progress ..."); } void QmitkSimpleRegistrationView::OnRegResultIsAvailable(mitk::MAPRegistrationWrapper::Pointer spResultRegistration, const QmitkRegistrationJob* job) { mitk::Image::Pointer movingImage = dynamic_cast(m_MovingImageNode->GetData()); mitk::Image::Pointer image; - if (m_RegistrationType==0) + if (m_RegistrationType==0 && !m_Controls->m_ResampleBox->isChecked()) { image = mitk::ImageMappingHelper::refineGeometry(movingImage, spResultRegistration, true); } else { if (!mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(movingImage)) { image = mitk::ImageMappingHelper::map(movingImage, spResultRegistration, false, 0, job->m_spTargetData->GetGeometry(), false, 0, mitk::ImageMappingInterpolator::BSpline_3); } else { typedef itk::ComposeImageFilter < ITKDiffusionVolumeType > ComposeFilterType; ComposeFilterType::Pointer composer = ComposeFilterType::New(); ItkDwiType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::GetItkVectorImage(movingImage); for (unsigned int i=0; iGetVectorLength(); ++i) { itk::ExtractDwiChannelFilter< short >::Pointer filter = itk::ExtractDwiChannelFilter< short >::New(); filter->SetInput( itkVectorImagePointer); filter->SetChannelIndex(i); filter->Update(); mitk::Image::Pointer gradientVolume = mitk::Image::New(); gradientVolume->InitializeByItk( filter->GetOutput() ); gradientVolume->SetImportChannel( filter->GetOutput()->GetBufferPointer() ); mitk::Image::Pointer registered_mitk_image = mitk::ImageMappingHelper::map(gradientVolume, spResultRegistration, false, 0, job->m_spTargetData->GetGeometry(), false, 0, mitk::ImageMappingInterpolator::BSpline_3); ITKDiffusionVolumeType::Pointer registered_itk_image = ITKDiffusionVolumeType::New(); mitk::CastToItkImage(registered_mitk_image, registered_itk_image); composer->SetInput(i, registered_itk_image); } composer->Update(); image = mitk::GrabItkImageMemory( composer->GetOutput() ); mitk::DiffusionPropertyHelper::CopyProperties(movingImage, image, true); + + auto reg = spResultRegistration->GetRegistration(); + typedef mitk::DiffusionImageCorrectionFilter CorrectionFilterType; + CorrectionFilterType::Pointer corrector = CorrectionFilterType::New(); + corrector->SetImage( image ); + corrector->CorrectDirections( mitk::MITKRegistrationHelper::getAffineMatrix(reg, false)->GetMatrix().GetVnlMatrix() ); } } if (mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image)) - { mitk::DiffusionPropertyHelper::InitializeImage( image ); - } mitk::DataNode::Pointer resultNode = mitk::DataNode::New(); resultNode->SetData(image); if (m_MovingImageNode.IsNotNull()) { m_MovingImageNode->SetVisibility(false); QString name = m_MovingImageNode->GetName().c_str(); if (m_RegistrationType==0) resultNode->SetName((name+"_registered (rigid)").toStdString().c_str()); else resultNode->SetName((name+"_registered (affine)").toStdString().c_str()); } else { if (m_RegistrationType==0) resultNode->SetName("Registered (rigid)"); else resultNode->SetName("Registered (affine)"); } // resultNode->SetOpacity(0.6); // resultNode->SetColor(0.0, 0.0, 1.0); GetDataStorage()->Add(resultNode); mitk::RenderingManager::GetInstance()->InitializeViews( resultNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true); if (m_Controls->m_RegOutputBox->isChecked()) { mitk::DataNode::Pointer registration_node = mitk::DataNode::New(); registration_node->SetData(spResultRegistration); if (m_RegistrationType==0) registration_node->SetName("Registration Object (rigid)"); else registration_node->SetName("Registration Object (affine)"); GetDataStorage()->Add(registration_node, resultNode); } this->GetRenderWindowPart()->RequestUpdate(); m_Controls->m_RegistrationStartButton->setEnabled(true); m_Controls->m_RegistrationStartButton->setText("Start Registration"); m_MovingImageNode = nullptr; TractoChanged(); } void QmitkSimpleRegistrationView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkSimpleRegistrationViewControls; m_Controls->setupUi( parent ); m_Controls->m_FixedImageBox->SetDataStorage(this->GetDataStorage()); m_Controls->m_MovingImageBox->SetDataStorage(this->GetDataStorage()); mitk::TNodePredicateDataType::Pointer isImagePredicate = mitk::TNodePredicateDataType::New(); m_Controls->m_FixedImageBox->SetPredicate(isImagePredicate); m_Controls->m_MovingImageBox->SetPredicate(isImagePredicate); mitk::TNodePredicateDataType::Pointer isFib = mitk::TNodePredicateDataType::New(); mitk::TNodePredicateDataType::Pointer isReg = mitk::TNodePredicateDataType::New(); m_Controls->m_TractoBox->SetDataStorage(this->GetDataStorage()); m_Controls->m_RegObjectBox->SetDataStorage(this->GetDataStorage()); m_Controls->m_TractoBox->SetPredicate(isFib); m_Controls->m_RegObjectBox->SetPredicate(isReg); connect( m_Controls->m_FixedImageBox, SIGNAL(currentIndexChanged(int)), this, SLOT(FixedImageChanged()) ); connect( m_Controls->m_MovingImageBox, SIGNAL(currentIndexChanged(int)), this, SLOT(MovingImageChanged()) ); connect( m_Controls->m_TractoBox, SIGNAL(currentIndexChanged(int)), this, SLOT(TractoChanged()) ); connect( m_Controls->m_RegObjectBox, SIGNAL(currentIndexChanged(int)), this, SLOT(TractoChanged()) ); connect( m_Controls->m_RegistrationStartButton, SIGNAL(clicked()), this, SLOT(StartRegistration()) ); connect( m_Controls->m_TractoRegistrationStartButton, SIGNAL(clicked()), this, SLOT(StartTractoRegistration()) ); FixedImageChanged(); MovingImageChanged(); TractoChanged(); } } void QmitkSimpleRegistrationView::StartTractoRegistration() { mitk::FiberBundle::Pointer fib = dynamic_cast(m_Controls->m_TractoBox->GetSelectedNode()->GetData()); mitk::MAPRegistrationWrapper::Pointer reg = dynamic_cast(m_Controls->m_RegObjectBox->GetSelectedNode()->GetData()); mitk::MITKRegistrationHelper::Affine3DTransformType::Pointer affine = mitk::MITKRegistrationHelper::getAffineMatrix(reg, false); mitk::FiberBundle::Pointer fib_copy = fib->GetDeepCopy(); fib_copy->TransformFibers(affine); mitk::DataNode::Pointer registration_node = mitk::DataNode::New(); registration_node->SetData(fib_copy); QString name = m_Controls->m_TractoBox->GetSelectedNode()->GetName().c_str(); registration_node->SetName((name+"_registered").toStdString().c_str()); GetDataStorage()->Add(registration_node, m_Controls->m_TractoBox->GetSelectedNode()); } void QmitkSimpleRegistrationView::TractoChanged() { if (m_Controls->m_RegObjectBox->GetSelectedNode().IsNotNull() && m_Controls->m_TractoBox->GetSelectedNode().IsNotNull()) m_Controls->m_TractoRegistrationStartButton->setEnabled(true); else m_Controls->m_TractoRegistrationStartButton->setEnabled(false); } void QmitkSimpleRegistrationView::FixedImageChanged() { if (m_Controls->m_FixedImageBox->GetSelectedNode().IsNotNull()) { mitk::Image::Pointer image = dynamic_cast(m_Controls->m_FixedImageBox->GetSelectedNode()->GetData()); int channels = image->GetNumberOfChannels(); int dims = image->GetDimension(); int fourth_dim_size = image->GetTimeSteps(); bool isdiff = mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image); if (dims==4 || channels>1) { m_Controls->m_FixedChannelBox->setEnabled(false); m_Controls->m_RegistrationStartButton->setEnabled(false); } if (isdiff) { m_Controls->m_FixedChannelBox->setEnabled(true); if (fourth_dim_size>1) m_Controls->m_FixedChannelBox->setMaximum(fourth_dim_size-1); else if (isdiff) m_Controls->m_FixedChannelBox->setMaximum(mitk::DiffusionPropertyHelper::GetGradientContainer(image)->Size()-1); } else { m_Controls->m_FixedChannelBox->setEnabled(false); } m_Controls->m_RegistrationStartButton->setEnabled(true); } else { m_Controls->m_FixedChannelBox->setEnabled(false); m_Controls->m_RegistrationStartButton->setEnabled(false); } } void QmitkSimpleRegistrationView::MovingImageChanged() { if (m_Controls->m_MovingImageBox->GetSelectedNode().IsNotNull()) { mitk::Image::Pointer image = dynamic_cast(m_Controls->m_MovingImageBox->GetSelectedNode()->GetData()); int channels = image->GetNumberOfChannels(); int dims = image->GetDimension(); int fourth_dim_size = image->GetTimeSteps(); bool isdiff = mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image); if (dims==4 || channels>1) { m_Controls->m_MovingChannelBox->setEnabled(false); m_Controls->m_RegistrationStartButton->setEnabled(false); } if (isdiff) { m_Controls->m_MovingChannelBox->setEnabled(true); if (fourth_dim_size>1) m_Controls->m_MovingChannelBox->setMaximum(fourth_dim_size-1); else if (isdiff) m_Controls->m_MovingChannelBox->setMaximum(mitk::DiffusionPropertyHelper::GetGradientContainer(image)->Size()-1); } else { m_Controls->m_MovingChannelBox->setEnabled(false); } m_Controls->m_RegistrationStartButton->setEnabled(true); } else { m_Controls->m_MovingChannelBox->setEnabled(false); m_Controls->m_RegistrationStartButton->setEnabled(false); } } void QmitkSimpleRegistrationView::OnSelectionChanged(berry::IWorkbenchPart::Pointer, const QList& ) { FixedImageChanged(); MovingImageChanged(); TractoChanged(); } void QmitkSimpleRegistrationView::SetFocus() { m_Controls->m_RegistrationStartButton->setFocus(); FixedImageChanged(); MovingImageChanged(); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.registration/src/internal/QmitkSimpleRegistrationViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging.registration/src/internal/QmitkSimpleRegistrationViewControls.ui index 005a0cec60..a61c2080ef 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.registration/src/internal/QmitkSimpleRegistrationViewControls.ui +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.registration/src/internal/QmitkSimpleRegistrationViewControls.ui @@ -1,288 +1,302 @@ - + QmitkSimpleRegistrationViewControls 0 0 435 744 Form QCommandLinkButton:disabled { border: none; } QGroupBox { background-color: transparent; } 25 Qt::Vertical 20 40 Image Registration 6 6 6 6 false - + Start Registration QFrame::NoFrame QFrame::Raised 0 0 0 0 + + + + Registration Type: + + + Rigid Affine - - - - Registration Type: - - - - + Output Registration Object: + + + + Always Resample to Target: + + + + + + + + + + QFrame::NoFrame QFrame::Raised 0 0 0 0 - + Moving Image: - + false Select dMRI volume used to calculate transformation. false Select dMRI volume used to calculate transformation. Fixed Image: QFrame::NoFrame QFrame::Raised 0 0 0 0 false - + Start Tractography Registration Tractography Registration 6 6 6 6 Registration Object: - + Tractogram: - + QmitkDataStorageComboBox QComboBox
QmitkDataStorageComboBox.h
- - -
\ No newline at end of file + + +