diff --git a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/Properties/mitkDiffusionPropertyHelper.cpp b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/Properties/mitkDiffusionPropertyHelper.cpp index 9d463749d1..05a5c1f262 100644 --- a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/Properties/mitkDiffusionPropertyHelper.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/Properties/mitkDiffusionPropertyHelper.cpp @@ -1,410 +1,408 @@ /*=================================================================== 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 const std::string mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME = "meta.GradientDirections"; const std::string mitk::DiffusionPropertyHelper::ORIGINALGRADIENTCONTAINERPROPERTYNAME = "meta.OriginalGradientDirections"; const std::string mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME = "meta.MeasurementFrame"; const std::string mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME = "meta.ReferenceBValue"; const std::string mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME = "BValueMap"; mitk::DiffusionPropertyHelper::DiffusionPropertyHelper() { } mitk::DiffusionPropertyHelper::DiffusionPropertyHelper( mitk::Image* inputImage) : m_Image( inputImage ) { // Update props } mitk::DiffusionPropertyHelper::~DiffusionPropertyHelper() { } 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(double precision) { mitk::GradientDirectionsProperty* DirectionsProperty = static_cast( m_Image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() ); GradientDirectionsContainerType::Pointer oldDirs = DirectionsProperty->GetGradientDirectionsContainer(); 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( m_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()) { // progress //typename ImageType::IndexType ind = newIt.GetIndex(); //ind1 = ind.m_Index[2]; // 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; iSetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( newDirs ) ); m_Image->SetProperty( mitk::DiffusionPropertyHelper::ORIGINALGRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( newDirs ) ); ApplyMeasurementFrame(); UpdateBValueMap(); std::cout << std::endl; } void mitk::DiffusionPropertyHelper::ApplyMeasurementFrame() { if( m_Image->GetProperty(mitk::DiffusionPropertyHelper::ORIGINALGRADIENTCONTAINERPROPERTYNAME.c_str()).IsNull() ) { return; } GradientDirectionsContainerType::Pointer originalDirections = static_cast( m_Image->GetProperty(mitk::DiffusionPropertyHelper::ORIGINALGRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer())->GetGradientDirectionsContainer(); MeasurementFrameType measurementFrame = GetMeasurementFrame(m_Image); GradientDirectionsContainerType::Pointer directions = GradientDirectionsContainerType::New(); if( originalDirections.IsNull() || ( originalDirections->size() == 0 ) ) { // original direction container was not set return; } int c = 0; for(GradientDirectionsContainerType::ConstIterator gdcit = originalDirections->Begin(); gdcit != originalDirections->End(); ++gdcit) { vnl_vector vec = gdcit.Value(); vec = vec.pre_multiply(measurementFrame); - MITK_INFO << gdcit.Value(); directions->InsertElement(c, vec); c++; } m_Image->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( directions ) ); } void mitk::DiffusionPropertyHelper::UpdateBValueMap() { BValueMapType b_ValueMap; if(m_Image->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).IsNull()) { } else { b_ValueMap = static_cast(m_Image->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap(); } if(!b_ValueMap.empty()) { b_ValueMap.clear(); } if( m_Image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).IsNotNull() ) { GradientDirectionsContainerType::Pointer directions = static_cast( m_Image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer(); GradientDirectionsContainerType::ConstIterator gdcit; for( gdcit = directions->Begin(); gdcit != directions->End(); ++gdcit) { - MITK_INFO << gdcit.Value(); b_ValueMap[GetB_Value(gdcit.Index())].push_back(gdcit.Index()); } } m_Image->SetProperty( mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str(), mitk::BValueMapProperty::New( 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(unsigned int i) { GradientDirectionsContainerType::Pointer directions = static_cast( m_Image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer(); float b_value = static_cast(m_Image->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue(); 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::InitializeImage() { this->ApplyMeasurementFrame(); this->UpdateBValueMap(); // initialize missing properties mitk::MeasurementFrameProperty::Pointer mf = dynamic_cast( m_Image->GetProperty(MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer()); if( mf.IsNull() ) { //no measurement frame present, identity is assumed MeasurementFrameType identity; identity.set_identity(); m_Image->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( identity )); } } bool mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(const mitk::DataNode* node) { return IsDiffusionWeightedImage(dynamic_cast(node->GetData())); } bool mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(const mitk::Image * image) { bool isDiffusionWeightedImage( true ); if( image == NULL ) { 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(); } 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(); } bool mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage() const { return IsDiffusionWeightedImage(m_Image); } const mitk::DiffusionPropertyHelper::BValueMapType &mitk::DiffusionPropertyHelper::GetBValueMap() const { return GetBValueMap(m_Image); } float mitk::DiffusionPropertyHelper::GetReferenceBValue() const { return GetReferenceBValue(m_Image); } const mitk::DiffusionPropertyHelper::MeasurementFrameType & mitk::DiffusionPropertyHelper::GetMeasurementFrame() const { return GetMeasurementFrame(m_Image); } mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::Pointer mitk::DiffusionPropertyHelper::GetOriginalGradientContainer() const { return GetOriginalGradientContainer(m_Image); } mitk::DiffusionPropertyHelper::GradientDirectionsContainerType::Pointer mitk::DiffusionPropertyHelper::GetGradientContainer() const { return GetGradientContainer(m_Image); } diff --git a/Modules/DiffusionImaging/DiffusionIO/mitkFiberBundleXMapper3D.cpp b/Modules/DiffusionImaging/DiffusionIO/mitkFiberBundleXMapper3D.cpp index ec4f4e88a3..38b3af487f 100644 --- a/Modules/DiffusionImaging/DiffusionIO/mitkFiberBundleXMapper3D.cpp +++ b/Modules/DiffusionImaging/DiffusionIO/mitkFiberBundleXMapper3D.cpp @@ -1,187 +1,190 @@ /*=================================================================== 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 "mitkFiberBundleXMapper3D.h" #include #include #include #include #include #include #include #include #include mitk::FiberBundleXMapper3D::FiberBundleXMapper3D() : m_TubeRadius(0.0) , m_TubeSides(15) , m_LineWidth(1) { m_lut = vtkLookupTable::New(); m_lut->Build(); } mitk::FiberBundleXMapper3D::~FiberBundleXMapper3D() { } const mitk::FiberBundleX* mitk::FiberBundleXMapper3D::GetInput() { return static_cast ( GetDataNode()->GetData() ); } /* This method is called once the mapper gets new input, for UI rotation or changes in colorcoding this method is NOT called */ void mitk::FiberBundleXMapper3D::InternalGenerateData(mitk::BaseRenderer *renderer) { mitk::FiberBundleX* fiberBundle = dynamic_cast (GetDataNode()->GetData()); if (fiberBundle == NULL) return; vtkSmartPointer fiberPolyData = fiberBundle->GetFiberPolyData(); if (fiberPolyData == NULL) return; fiberPolyData->GetPointData()->AddArray(fiberBundle->GetFiberColors()); float tmpopa; this->GetDataNode()->GetOpacity(tmpopa, NULL); FBXLocalStorage3D *localStorage = m_LocalStorageHandler.GetLocalStorage(renderer); if (m_TubeRadius>0.0) { vtkSmartPointer tubeFilter = vtkSmartPointer::New(); tubeFilter->SetInputData(fiberPolyData); tubeFilter->SetNumberOfSides(m_TubeSides); tubeFilter->SetRadius(m_TubeRadius); tubeFilter->Update(); fiberPolyData = tubeFilter->GetOutput(); } if (tmpopa<1) { vtkSmartPointer depthSort = vtkSmartPointer::New(); depthSort->SetInputData( fiberPolyData ); depthSort->SetCamera( renderer->GetVtkRenderer()->GetActiveCamera() ); - depthSort->SetDirectionToFrontToBack(); + if (m_TubeRadius>0.0) + depthSort->SetDirectionToBackToFront(); + else + depthSort->SetDirectionToFrontToBack(); depthSort->Update(); fiberPolyData = depthSort->GetOutput(); } localStorage->m_FiberMapper->SetInputData(fiberPolyData); localStorage->m_FiberMapper->SelectColorArray("FIBER_COLORS"); localStorage->m_FiberMapper->ScalarVisibilityOn(); localStorage->m_FiberMapper->SetScalarModeToUsePointFieldData(); localStorage->m_FiberActor->SetMapper(localStorage->m_FiberMapper); localStorage->m_FiberMapper->SetLookupTable(m_lut); // set Opacity localStorage->m_FiberActor->GetProperty()->SetOpacity((double) tmpopa); localStorage->m_FiberActor->GetProperty()->SetLineWidth(m_LineWidth); localStorage->m_FiberAssembly->AddPart(localStorage->m_FiberActor); localStorage->m_LastUpdateTime.Modified(); } void mitk::FiberBundleXMapper3D::GenerateDataForRenderer( mitk::BaseRenderer *renderer ) { bool visible = true; GetDataNode()->GetVisibility(visible, renderer, "visible"); if ( !visible ) return; const DataNode* node = this->GetDataNode(); FBXLocalStorage3D* localStorage = m_LocalStorageHandler.GetLocalStorage(renderer); mitk::FiberBundleX* fiberBundle = dynamic_cast(node->GetData()); // did any rendering properties change? float tubeRadius = 0; node->GetFloatProperty("TubeRadius", tubeRadius); if (m_TubeRadius!=tubeRadius) { m_TubeRadius = tubeRadius; fiberBundle->RequestUpdate3D(); } int tubeSides = 0; node->GetIntProperty("TubeSides", tubeSides); if (m_TubeSides!=tubeSides) { m_TubeSides = tubeSides; fiberBundle->RequestUpdate3D(); } int lineWidth = 0; node->GetIntProperty("LineWidth", lineWidth); if (m_LineWidth!=lineWidth) { m_LineWidth = lineWidth; fiberBundle->RequestUpdate3D(); } if (localStorage->m_LastUpdateTime>=fiberBundle->GetUpdateTime3D()) return; // Calculate time step of the input data for the specified renderer (integer value) // this method is implemented in mitkMapper this->CalculateTimeStep( renderer ); this->InternalGenerateData(renderer); } void mitk::FiberBundleXMapper3D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite) { Superclass::SetDefaultProperties(node, renderer, overwrite); node->AddProperty( "LineWidth", mitk::IntProperty::New( true ), renderer, overwrite ); node->AddProperty( "opacity", mitk::FloatProperty::New( 1.0 ), renderer, overwrite); node->AddProperty( "color", mitk::ColorProperty::New(1.0,1.0,1.0), renderer, overwrite); node->AddProperty( "pickable", mitk::BoolProperty::New( true ), renderer, overwrite); node->AddProperty( "TubeRadius",mitk::FloatProperty::New( 0.0 ), renderer, overwrite); node->AddProperty( "TubeSides",mitk::IntProperty::New( 15 ), renderer, overwrite); } vtkProp* mitk::FiberBundleXMapper3D::GetVtkProp(mitk::BaseRenderer *renderer) { return m_LocalStorageHandler.GetLocalStorage(renderer)->m_FiberAssembly; } void mitk::FiberBundleXMapper3D::UpdateVtkObjects() { } void mitk::FiberBundleXMapper3D::SetVtkMapperImmediateModeRendering(vtkMapper *) { } mitk::FiberBundleXMapper3D::FBXLocalStorage3D::FBXLocalStorage3D() { m_FiberActor = vtkSmartPointer::New(); m_FiberMapper = vtkSmartPointer::New(); m_FiberAssembly = vtkSmartPointer::New(); } diff --git a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.cpp b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.cpp index 230788c36c..4a0071773b 100755 --- a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.cpp @@ -1,1434 +1,1437 @@ /*=================================================================== 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 "itkTractsToDWIImageFilter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace itk { template< class PixelType > TractsToDWIImageFilter< PixelType >::TractsToDWIImageFilter() : m_FiberBundle(NULL) , m_StatusText("") , m_UseConstantRandSeed(false) , m_RandGen(itk::Statistics::MersenneTwisterRandomVariateGenerator::New()) { m_RandGen->SetSeed(); } template< class PixelType > TractsToDWIImageFilter< PixelType >::~TractsToDWIImageFilter() { } template< class PixelType > TractsToDWIImageFilter< PixelType >::DoubleDwiType::Pointer TractsToDWIImageFilter< PixelType >::DoKspaceStuff( std::vector< DoubleDwiType::Pointer >& images ) { int numFiberCompartments = m_Parameters.m_FiberModelList.size(); // create slice object ImageRegion<2> sliceRegion; sliceRegion.SetSize(0, m_UpsampledImageRegion.GetSize()[0]); sliceRegion.SetSize(1, m_UpsampledImageRegion.GetSize()[1]); Vector< double, 2 > sliceSpacing; sliceSpacing[0] = m_UpsampledSpacing[0]; sliceSpacing[1] = m_UpsampledSpacing[1]; // frequency map slice SliceType::Pointer fMapSlice = NULL; if (m_Parameters.m_SignalGen.m_FrequencyMap.IsNotNull()) { fMapSlice = SliceType::New(); ImageRegion<2> region; region.SetSize(0, m_UpsampledImageRegion.GetSize()[0]); region.SetSize(1, m_UpsampledImageRegion.GetSize()[1]); fMapSlice->SetLargestPossibleRegion( region ); fMapSlice->SetBufferedRegion( region ); fMapSlice->SetRequestedRegion( region ); fMapSlice->Allocate(); fMapSlice->FillBuffer(0.0); } DoubleDwiType::Pointer newImage = DoubleDwiType::New(); newImage->SetSpacing( m_Parameters.m_SignalGen.m_ImageSpacing ); newImage->SetOrigin( m_Parameters.m_SignalGen.m_ImageOrigin ); newImage->SetDirection( m_Parameters.m_SignalGen.m_ImageDirection ); newImage->SetLargestPossibleRegion( m_Parameters.m_SignalGen.m_ImageRegion ); newImage->SetBufferedRegion( m_Parameters.m_SignalGen.m_ImageRegion ); newImage->SetRequestedRegion( m_Parameters.m_SignalGen.m_ImageRegion ); newImage->SetVectorLength( images.at(0)->GetVectorLength() ); newImage->Allocate(); std::vector< unsigned int > spikeVolume; for (unsigned int i=0; iGetIntegerVariate()%(images.at(0)->GetVectorLength()-1)+1); std::sort (spikeVolume.begin(), spikeVolume.end()); std::reverse (spikeVolume.begin(), spikeVolume.end()); m_StatusText += "0% 10 20 30 40 50 60 70 80 90 100%\n"; m_StatusText += "|----|----|----|----|----|----|----|----|----|----|\n*"; unsigned long lastTick = 0; boost::progress_display disp(2*images.at(0)->GetVectorLength()*images.at(0)->GetLargestPossibleRegion().GetSize(2)); for (unsigned int g=0; gGetVectorLength(); g++) { std::vector< unsigned int > spikeSlice; while (!spikeVolume.empty() && spikeVolume.back()==g) { spikeSlice.push_back(m_RandGen->GetIntegerVariate()%images.at(0)->GetLargestPossibleRegion().GetSize(2)); spikeVolume.pop_back(); } std::sort (spikeSlice.begin(), spikeSlice.end()); std::reverse (spikeSlice.begin(), spikeSlice.end()); for (unsigned int z=0; zGetLargestPossibleRegion().GetSize(2); z++) { std::vector< SliceType::Pointer > compartmentSlices; std::vector< double > t2Vector; for (unsigned int i=0; i* signalModel; if (iSetLargestPossibleRegion( sliceRegion ); slice->SetBufferedRegion( sliceRegion ); slice->SetRequestedRegion( sliceRegion ); slice->SetSpacing(sliceSpacing); slice->Allocate(); slice->FillBuffer(0.0); // extract slice from channel g for (unsigned int y=0; yGetLargestPossibleRegion().GetSize(1); y++) for (unsigned int x=0; xGetLargestPossibleRegion().GetSize(0); x++) { SliceType::IndexType index2D; index2D[0]=x; index2D[1]=y; DoubleDwiType::IndexType index3D; index3D[0]=x; index3D[1]=y; index3D[2]=z; slice->SetPixel(index2D, images.at(i)->GetPixel(index3D)[g]); if (fMapSlice.IsNotNull() && i==0) fMapSlice->SetPixel(index2D, m_Parameters.m_SignalGen.m_FrequencyMap->GetPixel(index3D)); } compartmentSlices.push_back(slice); t2Vector.push_back(signalModel->GetT2()); } if (this->GetAbortGenerateData()) return NULL; // create k-sapce (inverse fourier transform slices) itk::Size<2> outSize; outSize.SetElement(0, m_Parameters.m_SignalGen.m_ImageRegion.GetSize(0)); outSize.SetElement(1, m_Parameters.m_SignalGen.m_ImageRegion.GetSize(1)); itk::KspaceImageFilter< SliceType::PixelType >::Pointer idft = itk::KspaceImageFilter< SliceType::PixelType >::New(); idft->SetCompartmentImages(compartmentSlices); idft->SetT2(t2Vector); idft->SetUseConstantRandSeed(m_UseConstantRandSeed); idft->SetParameters(m_Parameters); idft->SetZ((double)z-(double)images.at(0)->GetLargestPossibleRegion().GetSize(2)/2.0); idft->SetDiffusionGradientDirection(m_Parameters.m_SignalGen.GetGradientDirection(g)); idft->SetFrequencyMapSlice(fMapSlice); idft->SetOutSize(outSize); int numSpikes = 0; while (!spikeSlice.empty() && spikeSlice.back()==z) { numSpikes++; spikeSlice.pop_back(); } idft->SetSpikesPerSlice(numSpikes); idft->Update(); ComplexSliceType::Pointer fSlice; fSlice = idft->GetOutput(); ++disp; unsigned long newTick = 50*disp.count()/disp.expected_count(); for (unsigned long tick = 0; tick<(newTick-lastTick); tick++) m_StatusText += "*"; lastTick = newTick; // fourier transform slice SliceType::Pointer newSlice; itk::DftImageFilter< SliceType::PixelType >::Pointer dft = itk::DftImageFilter< SliceType::PixelType >::New(); dft->SetInput(fSlice); dft->Update(); newSlice = dft->GetOutput(); // put slice back into channel g for (unsigned int y=0; yGetLargestPossibleRegion().GetSize(1); y++) for (unsigned int x=0; xGetLargestPossibleRegion().GetSize(0); x++) { DoubleDwiType::IndexType index3D; index3D[0]=x; index3D[1]=y; index3D[2]=z; SliceType::IndexType index2D; index2D[0]=x; index2D[1]=y; DoubleDwiType::PixelType pix3D = newImage->GetPixel(index3D); pix3D[g] = newSlice->GetPixel(index2D); newImage->SetPixel(index3D, pix3D); } ++disp; newTick = 50*disp.count()/disp.expected_count(); for (unsigned long tick = 0; tick<(newTick-lastTick); tick++) m_StatusText += "*"; lastTick = newTick; } } m_StatusText += "\n\n"; return newImage; } template< class PixelType > void TractsToDWIImageFilter< PixelType >::GenerateData() { m_TimeProbe.Start(); m_StatusText = "Starting simulation\n"; // check input data if (m_FiberBundle.IsNull()) itkExceptionMacro("Input fiber bundle is NULL!"); if (m_Parameters.m_FiberModelList.empty()) itkExceptionMacro("No diffusion model for fiber compartments defined!"); if (m_Parameters.m_NonFiberModelList.empty()) itkExceptionMacro("No diffusion model for non-fiber compartments defined!"); int baselineIndex = m_Parameters.m_SignalGen.GetFirstBaselineIndex(); if (baselineIndex<0) itkExceptionMacro("No baseline index found!"); if (!m_Parameters.m_SignalGen.m_SimulateKspaceAcquisition) m_Parameters.m_SignalGen.m_DoAddGibbsRinging = false; if (m_UseConstantRandSeed) // always generate the same random numbers? m_RandGen->SetSeed(0); else m_RandGen->SetSeed(); // initialize output dwi image ImageRegion<3> croppedRegion = m_Parameters.m_SignalGen.m_ImageRegion; croppedRegion.SetSize(1, croppedRegion.GetSize(1)*m_Parameters.m_SignalGen.m_CroppingFactor); itk::Point shiftedOrigin = m_Parameters.m_SignalGen.m_ImageOrigin; shiftedOrigin[1] += (m_Parameters.m_SignalGen.m_ImageRegion.GetSize(1)-croppedRegion.GetSize(1))*m_Parameters.m_SignalGen.m_ImageSpacing[1]/2; typename OutputImageType::Pointer outImage = OutputImageType::New(); outImage->SetSpacing( m_Parameters.m_SignalGen.m_ImageSpacing ); outImage->SetOrigin( shiftedOrigin ); outImage->SetDirection( m_Parameters.m_SignalGen.m_ImageDirection ); outImage->SetLargestPossibleRegion( croppedRegion ); outImage->SetBufferedRegion( croppedRegion ); outImage->SetRequestedRegion( croppedRegion ); outImage->SetVectorLength( m_Parameters.m_SignalGen.GetNumVolumes() ); outImage->Allocate(); typename OutputImageType::PixelType temp; temp.SetSize(m_Parameters.m_SignalGen.GetNumVolumes()); temp.Fill(0.0); outImage->FillBuffer(temp); // ADJUST GEOMETRY FOR FURTHER PROCESSING // is input slize size a power of two? unsigned int x=m_Parameters.m_SignalGen.m_ImageRegion.GetSize(0); unsigned int y=m_Parameters.m_SignalGen.m_ImageRegion.GetSize(1); ItkDoubleImgType::SizeType pad; pad[0]=x%2; pad[1]=y%2; pad[2]=0; m_Parameters.m_SignalGen.m_ImageRegion.SetSize(0, x+pad[0]); m_Parameters.m_SignalGen.m_ImageRegion.SetSize(1, y+pad[1]); if (m_Parameters.m_SignalGen.m_FrequencyMap.IsNotNull() && (pad[0]>0 || pad[1]>0)) { itk::ConstantPadImageFilter::Pointer zeroPadder = itk::ConstantPadImageFilter::New(); zeroPadder->SetInput(m_Parameters.m_SignalGen.m_FrequencyMap); zeroPadder->SetConstant(0); zeroPadder->SetPadUpperBound(pad); zeroPadder->Update(); m_Parameters.m_SignalGen.m_FrequencyMap = zeroPadder->GetOutput(); } if (m_Parameters.m_SignalGen.m_MaskImage.IsNotNull() && (pad[0]>0 || pad[1]>0)) { itk::ConstantPadImageFilter::Pointer zeroPadder = itk::ConstantPadImageFilter::New(); zeroPadder->SetInput(m_Parameters.m_SignalGen.m_MaskImage); zeroPadder->SetConstant(0); zeroPadder->SetPadUpperBound(pad); zeroPadder->Update(); m_Parameters.m_SignalGen.m_MaskImage = zeroPadder->GetOutput(); } // Apply in-plane upsampling for Gibbs ringing artifact double upsampling = 1; if (m_Parameters.m_SignalGen.m_DoAddGibbsRinging) upsampling = 2; m_UpsampledSpacing = m_Parameters.m_SignalGen.m_ImageSpacing; m_UpsampledSpacing[0] /= upsampling; m_UpsampledSpacing[1] /= upsampling; m_UpsampledImageRegion = m_Parameters.m_SignalGen.m_ImageRegion; m_UpsampledImageRegion.SetSize(0, m_Parameters.m_SignalGen.m_ImageRegion.GetSize()[0]*upsampling); m_UpsampledImageRegion.SetSize(1, m_Parameters.m_SignalGen.m_ImageRegion.GetSize()[1]*upsampling); m_UpsampledOrigin = m_Parameters.m_SignalGen.m_ImageOrigin; m_UpsampledOrigin[0] -= m_Parameters.m_SignalGen.m_ImageSpacing[0]/2; m_UpsampledOrigin[0] += m_UpsampledSpacing[0]/2; m_UpsampledOrigin[1] -= m_Parameters.m_SignalGen.m_ImageSpacing[1]/2; m_UpsampledOrigin[1] += m_UpsampledSpacing[1]/2; m_UpsampledOrigin[2] -= m_Parameters.m_SignalGen.m_ImageSpacing[2]/2; m_UpsampledOrigin[2] += m_UpsampledSpacing[2]/2; // generate double images to store the individual compartment signals m_CompartmentImages.clear(); int numFiberCompartments = m_Parameters.m_FiberModelList.size(); int numNonFiberCompartments = m_Parameters.m_NonFiberModelList.size(); for (int i=0; iSetSpacing( m_UpsampledSpacing ); doubleDwi->SetOrigin( m_UpsampledOrigin ); doubleDwi->SetDirection( m_Parameters.m_SignalGen.m_ImageDirection ); doubleDwi->SetLargestPossibleRegion( m_UpsampledImageRegion ); doubleDwi->SetBufferedRegion( m_UpsampledImageRegion ); doubleDwi->SetRequestedRegion( m_UpsampledImageRegion ); doubleDwi->SetVectorLength( m_Parameters.m_SignalGen.GetNumVolumes() ); doubleDwi->Allocate(); DoubleDwiType::PixelType pix; pix.SetSize(m_Parameters.m_SignalGen.GetNumVolumes()); pix.Fill(0.0); doubleDwi->FillBuffer(pix); m_CompartmentImages.push_back(doubleDwi); } // initialize output volume fraction images m_VolumeFractions.clear(); for (int i=0; iSetSpacing( m_UpsampledSpacing ); doubleImg->SetOrigin( m_UpsampledOrigin ); doubleImg->SetDirection( m_Parameters.m_SignalGen.m_ImageDirection ); doubleImg->SetLargestPossibleRegion( m_UpsampledImageRegion ); doubleImg->SetBufferedRegion( m_UpsampledImageRegion ); doubleImg->SetRequestedRegion( m_UpsampledImageRegion ); doubleImg->Allocate(); doubleImg->FillBuffer(0); m_VolumeFractions.push_back(doubleImg); } // get volume fraction images ItkDoubleImgType::Pointer sumImage = ItkDoubleImgType::New(); bool foundVolumeFractionImage = false; for (int i=0; iGetVolumeFractionImage().IsNotNull()) { foundVolumeFractionImage = true; itk::ConstantPadImageFilter::Pointer zeroPadder = itk::ConstantPadImageFilter::New(); zeroPadder->SetInput(m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()); zeroPadder->SetConstant(0); zeroPadder->SetPadUpperBound(pad); zeroPadder->Update(); m_Parameters.m_NonFiberModelList[i]->SetVolumeFractionImage(zeroPadder->GetOutput()); sumImage->SetSpacing( m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetSpacing() ); sumImage->SetOrigin( m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetOrigin() ); sumImage->SetDirection( m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetDirection() ); sumImage->SetLargestPossibleRegion( m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetLargestPossibleRegion() ); sumImage->SetBufferedRegion( m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetLargestPossibleRegion() ); sumImage->SetRequestedRegion( m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetLargestPossibleRegion() ); sumImage->Allocate(); sumImage->FillBuffer(0); break; } } if (!foundVolumeFractionImage) { sumImage->SetSpacing( m_UpsampledSpacing ); sumImage->SetOrigin( m_UpsampledOrigin ); sumImage->SetDirection( m_Parameters.m_SignalGen.m_ImageDirection ); sumImage->SetLargestPossibleRegion( m_UpsampledImageRegion ); sumImage->SetBufferedRegion( m_UpsampledImageRegion ); sumImage->SetRequestedRegion( m_UpsampledImageRegion ); sumImage->Allocate(); sumImage->FillBuffer(0.0); } for (int i=0; iGetVolumeFractionImage().IsNull()) { ItkDoubleImgType::Pointer doubleImg = ItkDoubleImgType::New(); doubleImg->SetSpacing( sumImage->GetSpacing() ); doubleImg->SetOrigin( sumImage->GetOrigin() ); doubleImg->SetDirection( sumImage->GetDirection() ); doubleImg->SetLargestPossibleRegion( sumImage->GetLargestPossibleRegion() ); doubleImg->SetBufferedRegion( sumImage->GetLargestPossibleRegion() ); doubleImg->SetRequestedRegion( sumImage->GetLargestPossibleRegion() ); doubleImg->Allocate(); doubleImg->FillBuffer(1.0/numNonFiberCompartments); m_Parameters.m_NonFiberModelList[i]->SetVolumeFractionImage(doubleImg); } ImageRegionIterator it(m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage(), m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetLargestPossibleRegion()); while(!it.IsAtEnd()) { sumImage->SetPixel(it.GetIndex(), sumImage->GetPixel(it.GetIndex())+it.Get()); ++it; } } for (int i=0; i it(m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage(), m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetLargestPossibleRegion()); while(!it.IsAtEnd()) { if (sumImage->GetPixel(it.GetIndex())>0) it.Set(it.Get()/sumImage->GetPixel(it.GetIndex())); ++it; } } // resample mask image and frequency map to fit upsampled geometry if (m_Parameters.m_SignalGen.m_DoAddGibbsRinging) { if (m_Parameters.m_SignalGen.m_MaskImage.IsNotNull()) { // rescale mask image (otherwise there are problems with the resampling) itk::RescaleIntensityImageFilter::Pointer rescaler = itk::RescaleIntensityImageFilter::New(); rescaler->SetInput(0,m_Parameters.m_SignalGen.m_MaskImage); rescaler->SetOutputMaximum(100); rescaler->SetOutputMinimum(0); rescaler->Update(); // resample mask image itk::ResampleImageFilter::Pointer resampler = itk::ResampleImageFilter::New(); resampler->SetInput(rescaler->GetOutput()); resampler->SetOutputParametersFromImage(m_Parameters.m_SignalGen.m_MaskImage); resampler->SetSize(m_UpsampledImageRegion.GetSize()); resampler->SetOutputSpacing(m_UpsampledSpacing); resampler->SetOutputOrigin(m_UpsampledOrigin); itk::NearestNeighborInterpolateImageFunction::Pointer nn_interpolator = itk::NearestNeighborInterpolateImageFunction::New(); resampler->SetInterpolator(nn_interpolator); resampler->Update(); m_Parameters.m_SignalGen.m_MaskImage = resampler->GetOutput(); itk::ImageFileWriter::Pointer w = itk::ImageFileWriter::New(); w->SetFileName("/local/mask_ups.nrrd"); w->SetInput(m_Parameters.m_SignalGen.m_MaskImage); w->Update(); } // resample frequency map if (m_Parameters.m_SignalGen.m_FrequencyMap.IsNotNull()) { itk::ResampleImageFilter::Pointer resampler = itk::ResampleImageFilter::New(); resampler->SetInput(m_Parameters.m_SignalGen.m_FrequencyMap); resampler->SetOutputParametersFromImage(m_Parameters.m_SignalGen.m_FrequencyMap); resampler->SetSize(m_UpsampledImageRegion.GetSize()); resampler->SetOutputSpacing(m_UpsampledSpacing); resampler->SetOutputOrigin(m_UpsampledOrigin); itk::NearestNeighborInterpolateImageFunction::Pointer nn_interpolator = itk::NearestNeighborInterpolateImageFunction::New(); resampler->SetInterpolator(nn_interpolator); resampler->Update(); m_Parameters.m_SignalGen.m_FrequencyMap = resampler->GetOutput(); } } // no input tissue mask is set -> create default m_MaskImageSet = true; if (m_Parameters.m_SignalGen.m_MaskImage.IsNull()) { m_StatusText += "No tissue mask set\n"; MITK_INFO << "No tissue mask set"; m_Parameters.m_SignalGen.m_MaskImage = ItkUcharImgType::New(); m_Parameters.m_SignalGen.m_MaskImage->SetSpacing( m_UpsampledSpacing ); m_Parameters.m_SignalGen.m_MaskImage->SetOrigin( m_UpsampledOrigin ); m_Parameters.m_SignalGen.m_MaskImage->SetDirection( m_Parameters.m_SignalGen.m_ImageDirection ); m_Parameters.m_SignalGen.m_MaskImage->SetLargestPossibleRegion( m_UpsampledImageRegion ); m_Parameters.m_SignalGen.m_MaskImage->SetBufferedRegion( m_UpsampledImageRegion ); m_Parameters.m_SignalGen.m_MaskImage->SetRequestedRegion( m_UpsampledImageRegion ); m_Parameters.m_SignalGen.m_MaskImage->Allocate(); m_Parameters.m_SignalGen.m_MaskImage->FillBuffer(1); m_MaskImageSet = false; } else { m_StatusText += "Using tissue mask\n"; MITK_INFO << "Using tissue mask"; } m_Parameters.m_SignalGen.m_ImageRegion = croppedRegion; x=m_Parameters.m_SignalGen.m_ImageRegion.GetSize(0); y=m_Parameters.m_SignalGen.m_ImageRegion.GetSize(1); if ( x%2 == 1 ) m_Parameters.m_SignalGen.m_ImageRegion.SetSize(0, x+1); if ( y%2 == 1 ) m_Parameters.m_SignalGen.m_ImageRegion.SetSize(1, y+1); // resample fiber bundle for sufficient voxel coverage m_StatusText += "\n"+this->GetTime()+" > Resampling fibers ...\n"; double segmentVolume = 0.0001; float minSpacing = 1; if(m_UpsampledSpacing[0]GetDeepCopy(); double volumeAccuracy = 10; m_FiberBundleWorkingCopy->ResampleSpline(minSpacing/volumeAccuracy); double mmRadius = m_Parameters.m_SignalGen.m_AxonRadius/1000; if (mmRadius>0) segmentVolume = M_PI*mmRadius*mmRadius*minSpacing/volumeAccuracy; double maxVolume = 0; m_VoxelVolume = m_UpsampledSpacing[0]*m_UpsampledSpacing[1]*m_UpsampledSpacing[2]; if (m_Parameters.m_SignalGen.m_DoAddMotion) { std::string fileName = "fiberfox_motion_0.log"; std::string filePath = mitk::IOUtil::GetTempPath(); if (m_Parameters.m_Misc.m_OutputPath.size()>0) filePath = m_Parameters.m_Misc.m_OutputPath; int c = 1; while (itksys::SystemTools::FileExists((filePath+fileName).c_str())) { fileName = "fiberfox_motion_"; fileName += boost::lexical_cast(c); fileName += ".log"; c++; } m_Logfile.open((filePath+fileName).c_str()); m_Logfile << "0 rotation: 0,0,0; translation: 0,0,0\n"; if (m_Parameters.m_SignalGen.m_DoRandomizeMotion) { m_StatusText += "Adding random motion artifacts:\n"; m_StatusText += "Maximum rotation: +/-" + boost::lexical_cast(m_Parameters.m_SignalGen.m_Rotation) + "°\n"; m_StatusText += "Maximum translation: +/-" + boost::lexical_cast(m_Parameters.m_SignalGen.m_Translation) + "mm\n"; } else { m_StatusText += "Adding linear motion artifacts:\n"; m_StatusText += "Maximum rotation: " + boost::lexical_cast(m_Parameters.m_SignalGen.m_Rotation) + "°\n"; m_StatusText += "Maximum translation: " + boost::lexical_cast(m_Parameters.m_SignalGen.m_Translation) + "mm\n"; } m_StatusText += "Motion logfile: " + (filePath+fileName) + "\n"; MITK_INFO << "Adding motion artifacts"; MITK_INFO << "Maximum rotation: " << m_Parameters.m_SignalGen.m_Rotation; MITK_INFO << "Maxmimum translation: " << m_Parameters.m_SignalGen.m_Translation; } maxVolume = 0; m_StatusText += "\n"+this->GetTime()+" > Generating " + boost::lexical_cast(numFiberCompartments+numNonFiberCompartments) + "-compartment diffusion-weighted signal.\n"; MITK_INFO << "Generating " << numFiberCompartments+numNonFiberCompartments << "-compartment diffusion-weighted signal."; int numFibers = m_FiberBundle->GetNumFibers(); boost::progress_display disp(numFibers*m_Parameters.m_SignalGen.GetNumVolumes()); // get transform for motion artifacts m_FiberBundleTransformed = m_FiberBundleWorkingCopy; m_Rotation = m_Parameters.m_SignalGen.m_Rotation/m_Parameters.m_SignalGen.GetNumVolumes(); m_Translation = m_Parameters.m_SignalGen.m_Translation/m_Parameters.m_SignalGen.GetNumVolumes(); // creat image to hold transformed mask (motion artifact) m_MaskImage = ItkUcharImgType::New(); itk::ImageDuplicator::Pointer duplicator = itk::ImageDuplicator::New(); duplicator->SetInputImage(m_Parameters.m_SignalGen.m_MaskImage); duplicator->Update(); m_MaskImage = duplicator->GetOutput(); // second upsampling needed for motion artifacts ImageRegion<3> upsampledImageRegion = m_UpsampledImageRegion; DoubleVectorType upsampledSpacing = m_UpsampledSpacing; upsampledSpacing[0] /= 4; upsampledSpacing[1] /= 4; upsampledSpacing[2] /= 4; upsampledImageRegion.SetSize(0, m_UpsampledImageRegion.GetSize()[0]*4); upsampledImageRegion.SetSize(1, m_UpsampledImageRegion.GetSize()[1]*4); upsampledImageRegion.SetSize(2, m_UpsampledImageRegion.GetSize()[2]*4); itk::Point upsampledOrigin = m_UpsampledOrigin; upsampledOrigin[0] -= m_UpsampledSpacing[0]/2; upsampledOrigin[0] += upsampledSpacing[0]/2; upsampledOrigin[1] -= m_UpsampledSpacing[1]/2; upsampledOrigin[1] += upsampledSpacing[1]/2; upsampledOrigin[2] -= m_UpsampledSpacing[2]/2; upsampledOrigin[2] += upsampledSpacing[2]/2; m_UpsampledMaskImage = ItkUcharImgType::New(); itk::ResampleImageFilter::Pointer upsampler = itk::ResampleImageFilter::New(); upsampler->SetInput(m_Parameters.m_SignalGen.m_MaskImage); upsampler->SetOutputParametersFromImage(m_Parameters.m_SignalGen.m_MaskImage); upsampler->SetSize(upsampledImageRegion.GetSize()); upsampler->SetOutputSpacing(upsampledSpacing); upsampler->SetOutputOrigin(upsampledOrigin); itk::NearestNeighborInterpolateImageFunction::Pointer nn_interpolator = itk::NearestNeighborInterpolateImageFunction::New(); upsampler->SetInterpolator(nn_interpolator); upsampler->Update(); m_UpsampledMaskImage = upsampler->GetOutput(); if (m_HelperTdi.IsNotNull()) { itk::ResampleImageFilter::Pointer upsampler = itk::ResampleImageFilter::New(); upsampler->SetInput(m_HelperTdi); upsampler->SetOutputParametersFromImage(m_HelperTdi); upsampler->SetSize(upsampledImageRegion.GetSize()); upsampler->SetOutputSpacing(upsampledSpacing); upsampler->SetOutputOrigin(upsampledOrigin); - itk::NearestNeighborInterpolateImageFunction::Pointer nn_interpolator - = itk::NearestNeighborInterpolateImageFunction::New(); + itk::LinearInterpolateImageFunction::Pointer nn_interpolator + = itk::LinearInterpolateImageFunction::New(); upsampler->SetInterpolator(nn_interpolator); upsampler->Update(); m_HelperTdiUpsampled = upsampler->GetOutput(); m_HelperTdiTransformed = ItkFloatImgType::New(); itk::ImageDuplicator::Pointer duplicator = itk::ImageDuplicator::New(); duplicator->SetInputImage(m_HelperTdi); duplicator->Update(); m_HelperTdiTransformed = duplicator->GetOutput(); m_HelperTdiCounter = ItkUcharImgType::New(); itk::ImageDuplicator::Pointer duplicator2 = itk::ImageDuplicator::New(); duplicator2->SetInputImage(m_MaskImage); duplicator2->Update(); m_HelperTdiCounter = duplicator2->GetOutput(); } unsigned long lastTick = 0; int signalModelSeed = m_RandGen->GetIntegerVariate(); switch (m_Parameters.m_SignalGen.m_DiffusionDirectionMode) { case(SignalGenerationParameters::FIBER_TANGENT_DIRECTIONS): // use fiber tangent directions to determine diffusion direction { m_StatusText += "0% 10 20 30 40 50 60 70 80 90 100%\n"; m_StatusText += "|----|----|----|----|----|----|----|----|----|----|\n*"; for (unsigned int g=0; gSetSeed(signalModelSeed); for (int i=0; iSetSeed(signalModelSeed); ItkDoubleImgType::Pointer intraAxonalVolumeImage = ItkDoubleImgType::New(); intraAxonalVolumeImage->SetSpacing( m_UpsampledSpacing ); intraAxonalVolumeImage->SetOrigin( m_UpsampledOrigin ); intraAxonalVolumeImage->SetDirection( m_Parameters.m_SignalGen.m_ImageDirection ); intraAxonalVolumeImage->SetLargestPossibleRegion( m_UpsampledImageRegion ); intraAxonalVolumeImage->SetBufferedRegion( m_UpsampledImageRegion ); intraAxonalVolumeImage->SetRequestedRegion( m_UpsampledImageRegion ); intraAxonalVolumeImage->Allocate(); intraAxonalVolumeImage->FillBuffer(0); vtkPolyData* fiberPolyData = m_FiberBundleTransformed->GetFiberPolyData(); // GET TDI ItkDoubleImgType::Pointer TDI = ItkDoubleImgType::New(); TDI->SetSpacing( m_UpsampledSpacing ); TDI->SetOrigin( m_UpsampledOrigin ); TDI->SetDirection( m_Parameters.m_SignalGen.m_ImageDirection ); TDI->SetLargestPossibleRegion( m_UpsampledImageRegion ); TDI->SetBufferedRegion( m_UpsampledImageRegion ); TDI->SetRequestedRegion( m_UpsampledImageRegion ); TDI->Allocate(); TDI->FillBuffer(0); itk::TractDensityImageFilter< ItkDoubleImgType >::Pointer tdiFilter = itk::TractDensityImageFilter< ItkDoubleImgType >::New(); tdiFilter->SetFiberBundle(m_FiberBundleTransformed); tdiFilter->SetBinaryOutput(false); tdiFilter->SetOutputAbsoluteValues(false); tdiFilter->SetInputImage(TDI); tdiFilter->SetUseImageGeometry(true); tdiFilter->SetDoFiberResampling(false); tdiFilter->Update(); TDI = tdiFilter->GetOutput(); // generate fiber signal (if there are any fiber models present) if (!m_Parameters.m_FiberModelList.empty()) for( int i=0; iGetFiberWeight(i); vtkCell* cell = fiberPolyData->GetCell(i); int numPoints = cell->GetNumberOfPoints(); vtkPoints* points = cell->GetPoints(); if (numPoints<2) continue; for( int j=0; jGetAbortGenerateData()) { m_StatusText += "\n"+this->GetTime()+" > Simulation aborted\n"; return; } double* temp = points->GetPoint(j); itk::Point vertex = GetItkPoint(temp); itk::Vector v = GetItkVector(temp); itk::Vector dir(3); if (jGetPoint(j+1))-v; else dir = v-GetItkVector(points->GetPoint(j-1)); if (dir.GetSquaredNorm()<0.0001 || dir[0]!=dir[0] || dir[1]!=dir[1] || dir[2]!=dir[2]) continue; itk::Index<3> idx; itk::ContinuousIndex contIndex; m_MaskImage->TransformPhysicalPointToIndex(vertex, idx); m_MaskImage->TransformPhysicalPointToContinuousIndex(vertex, contIndex); if (!m_MaskImage->GetLargestPossibleRegion().IsInside(idx) || m_MaskImage->GetPixel(idx)<=0) continue; double TdCorrectionFactor = 1; if (m_HelperTdiTransformed.IsNotNull()) { double TD = TDI->GetPixel(idx); - itk::Index<3> idx2; m_HelperTdiTransformed->TransformPhysicalPointToIndex(vertex, idx2); double HTD = m_HelperTdiTransformed->GetPixel(idx2); - if (TD>0) - TdCorrectionFactor = HTD/TD; + if (TD>0.00001) + TdCorrectionFactor = sqrt(HTD)/TD; } // generate signal for each fiber compartment for (int k=0; kSetFiberDirection(dir); DoubleDwiType::PixelType pix = m_CompartmentImages.at(k)->GetPixel(idx); pix[g] += TdCorrectionFactor*fiberWeight*segmentVolume*m_Parameters.m_FiberModelList[k]->SimulateMeasurement(g); m_CompartmentImages.at(k)->SetPixel(idx, pix); } // update fiber volume image double vol = intraAxonalVolumeImage->GetPixel(idx) + segmentVolume*fiberWeight*TdCorrectionFactor; intraAxonalVolumeImage->SetPixel(idx, vol); if (g==0 && vol>maxVolume) maxVolume = vol; } // progress report ++disp; unsigned long newTick = 50*disp.count()/disp.expected_count(); for (unsigned int tick = 0; tick<(newTick-lastTick); tick++) m_StatusText += "*"; lastTick = newTick; } // generate non-fiber signal ImageRegionIterator it3(m_MaskImage, m_MaskImage->GetLargestPossibleRegion()); double fact = 1; if (m_Parameters.m_SignalGen.m_AxonRadius<0.0001 || maxVolume>m_VoxelVolume) fact = m_VoxelVolume/maxVolume; while(!it3.IsAtEnd()) { if (it3.Get()>0) { DoubleDwiType::IndexType index = it3.GetIndex(); // adjust intra-axonal signal to abtain an only-fiber voxel if (fabs(fact-1.0)>0.0001) { for (int i=0; iGetPixel(index); pix[g] *= fact; m_CompartmentImages.at(i)->SetPixel(index, pix); } } - // double w = 1; - // double intraAxonalVolume = intraAxonalVolumeImage->GetPixel(index)*fact; - // if (intraAxonalVolume>0.0001 && intraAxonalVolume<0.3) // only fiber in voxel - // { - // w = (m_VoxelVolume*0.3)/intraAxonalVolume; - // for (int i=0; iGetPixel(index); - // pix[g] *= w; - // m_CompartmentImages.at(i)->SetPixel(index, pix); - // } - - // m_VolumeFractions.at(0)->SetPixel(index, 1); - // } - - // simulate other compartments SimulateNonFiberSignal(index, intraAxonalVolumeImage->GetPixel(index)*fact, g); } ++it3; } // move fibers SimulateMotion(g); } break; } case (SignalGenerationParameters::MAIN_FIBER_DIRECTIONS): // use main fiber directions to determine voxel-wise diffusion directions { typedef itk::Image< itk::Vector< float, 3>, 3 > ItkDirectionImage3DType; typedef itk::VectorContainer< unsigned int, ItkDirectionImage3DType::Pointer > ItkDirectionImageContainerType; // calculate main fiber directions itk::TractsToVectorImageFilter::Pointer fOdfFilter = itk::TractsToVectorImageFilter::New(); fOdfFilter->SetFiberBundle(m_FiberBundleTransformed); fOdfFilter->SetMaskImage(m_MaskImage); fOdfFilter->SetAngularThreshold(cos(m_Parameters.m_SignalGen.m_FiberSeparationThreshold*M_PI/180.0)); fOdfFilter->SetNormalizeVectors(false); fOdfFilter->SetUseWorkingCopy(true); fOdfFilter->SetSizeThreshold(0); fOdfFilter->SetMaxNumDirections(3); fOdfFilter->Update(); ItkDirectionImageContainerType::Pointer directionImageContainer = fOdfFilter->GetDirectionImageContainer(); // allocate image storing intra-axonal volume fraction information ItkDoubleImgType::Pointer intraAxonalVolumeImage = ItkDoubleImgType::New(); intraAxonalVolumeImage->SetSpacing( m_UpsampledSpacing ); intraAxonalVolumeImage->SetOrigin( m_UpsampledOrigin ); intraAxonalVolumeImage->SetDirection( m_Parameters.m_SignalGen.m_ImageDirection ); intraAxonalVolumeImage->SetLargestPossibleRegion( m_UpsampledImageRegion ); intraAxonalVolumeImage->SetBufferedRegion( m_UpsampledImageRegion ); intraAxonalVolumeImage->SetRequestedRegion( m_UpsampledImageRegion ); intraAxonalVolumeImage->Allocate(); intraAxonalVolumeImage->FillBuffer(0); // determine intra-axonal volume fraction using the tract density itk::TractDensityImageFilter< ItkDoubleImgType >::Pointer tdiFilter = itk::TractDensityImageFilter< ItkDoubleImgType >::New(); tdiFilter->SetFiberBundle(m_FiberBundleTransformed); tdiFilter->SetBinaryOutput(false); tdiFilter->SetOutputAbsoluteValues(false); tdiFilter->SetInputImage(intraAxonalVolumeImage); tdiFilter->SetUseImageGeometry(true); tdiFilter->Update(); intraAxonalVolumeImage = tdiFilter->GetOutput(); m_StatusText += "0% 10 20 30 40 50 60 70 80 90 100%\n"; m_StatusText += "|----|----|----|----|----|----|----|----|----|----|\n*"; boost::progress_display disp(m_MaskImage->GetLargestPossibleRegion().GetNumberOfPixels()*m_Parameters.m_SignalGen.GetNumVolumes()); for (unsigned int g=0; gSetSeed(signalModelSeed); for (int i=0; iSetSeed(signalModelSeed); if (m_Parameters.m_SignalGen.m_DoAddMotion && g>0) // if fibers have moved we need a new TDI and new directions { fOdfFilter->SetFiberBundle(m_FiberBundleTransformed); fOdfFilter->SetMaskImage(m_MaskImage); fOdfFilter->Update(); directionImageContainer = fOdfFilter->GetDirectionImageContainer(); tdiFilter->SetFiberBundle(m_FiberBundleTransformed); tdiFilter->Update(); intraAxonalVolumeImage = tdiFilter->GetOutput(); } ImageRegionIterator< ItkUcharImgType > it(m_MaskImage, m_MaskImage->GetLargestPossibleRegion()); while(!it.IsAtEnd()) { ++disp; unsigned long newTick = 50*disp.count()/disp.expected_count(); for (unsigned int tick = 0; tick<(newTick-lastTick); tick++) m_StatusText += "*"; lastTick = newTick; if (this->GetAbortGenerateData()) { m_StatusText += "\n"+this->GetTime()+" > Simulation aborted\n"; return; } if (it.Get()>0) { // generate fiber signal for (int c=0; cGetPixel(it.GetIndex()); for (unsigned int i=0; iSize(); i++) { itk::Vector< double, 3> dir; dir.CastFrom(directionImageContainer->GetElement(i)->GetPixel(it.GetIndex())); double norm = dir.GetNorm(); if (norm>0.0001) { m_Parameters.m_FiberModelList.at(c)->SetFiberDirection(dir); pix[g] += m_Parameters.m_FiberModelList.at(c)->SimulateMeasurement(g)*norm; count++; } } if (count>0) pix[g] /= count; pix[g] *= intraAxonalVolumeImage->GetPixel(it.GetIndex())*m_VoxelVolume; m_CompartmentImages.at(c)->SetPixel(it.GetIndex(), pix); } // simulate other compartments SimulateNonFiberSignal(it.GetIndex(), intraAxonalVolumeImage->GetPixel(it.GetIndex())*m_VoxelVolume, g); } ++it; } SimulateMotion(g); } itk::ImageFileWriter< ItkUcharImgType >::Pointer wr = itk::ImageFileWriter< ItkUcharImgType >::New(); wr->SetInput(fOdfFilter->GetNumDirectionsImage()); wr->SetFileName(mitk::IOUtil::GetTempPath()+"/NumDirections_MainFiberDirections.nrrd"); wr->Update(); break; } case (SignalGenerationParameters::RANDOM_DIRECTIONS): { ItkUcharImgType::Pointer numDirectionsImage = ItkUcharImgType::New(); numDirectionsImage->SetSpacing( m_UpsampledSpacing ); numDirectionsImage->SetOrigin( m_UpsampledOrigin ); numDirectionsImage->SetDirection( m_Parameters.m_SignalGen.m_ImageDirection ); numDirectionsImage->SetLargestPossibleRegion( m_UpsampledImageRegion ); numDirectionsImage->SetBufferedRegion( m_UpsampledImageRegion ); numDirectionsImage->SetRequestedRegion( m_UpsampledImageRegion ); numDirectionsImage->Allocate(); numDirectionsImage->FillBuffer(0); double sepAngle = cos(m_Parameters.m_SignalGen.m_FiberSeparationThreshold*M_PI/180.0); m_StatusText += "0% 10 20 30 40 50 60 70 80 90 100%\n"; m_StatusText += "|----|----|----|----|----|----|----|----|----|----|\n*"; boost::progress_display disp(m_MaskImage->GetLargestPossibleRegion().GetNumberOfPixels()); ImageRegionIterator it(m_MaskImage, m_MaskImage->GetLargestPossibleRegion()); while(!it.IsAtEnd()) { ++disp; unsigned long newTick = 50*disp.count()/disp.expected_count(); for (unsigned int tick = 0; tick<(newTick-lastTick); tick++) m_StatusText += "*"; lastTick = newTick; if (this->GetAbortGenerateData()) { m_StatusText += "\n"+this->GetTime()+" > Simulation aborted\n"; return; } if (it.Get()>0) { int numFibs = m_RandGen->GetIntegerVariate(2)+1; DoubleDwiType::PixelType pix = m_CompartmentImages.at(0)->GetPixel(it.GetIndex()); double volume = m_RandGen->GetVariateWithClosedRange(0.3); // double sum = 0; std::vector< double > fractions; for (int i=0; iGetVariateWithClosedRange(0.5)); // sum += fractions.at(i); } // for (int i=0; i > directions; for (int i=0; iGetVariateWithClosedRange(2)-1.0; fib[1] = m_RandGen->GetVariateWithClosedRange(2)-1.0; fib[2] = m_RandGen->GetVariateWithClosedRange(2)-1.0; fib.Normalize(); double min = 0; for (unsigned int d=0; dmin) min = angle; } if (minSetFiberDirection(fib); pix += m_Parameters.m_FiberModelList.at(0)->SimulateMeasurement()*fractions[i]; directions.push_back(fib); } else i--; } pix *= (1-volume); m_CompartmentImages.at(0)->SetPixel(it.GetIndex(), pix); // CSF/GM { pix += volume*m_Parameters.m_NonFiberModelList.at(0)->SimulateMeasurement(); } numDirectionsImage->SetPixel(it.GetIndex(), numFibs); } ++it; } itk::ImageFileWriter< ItkUcharImgType >::Pointer wr = itk::ImageFileWriter< ItkUcharImgType >::New(); wr->SetInput(numDirectionsImage); wr->SetFileName(mitk::IOUtil::GetTempPath()+"/NumDirections_RandomDirections.nrrd"); wr->Update(); } } if (m_Logfile.is_open()) { m_Logfile << "DONE"; m_Logfile.close(); } m_StatusText += "\n\n"; if (this->GetAbortGenerateData()) { m_StatusText += "\n"+this->GetTime()+" > Simulation aborted\n"; return; } DoubleDwiType::Pointer doubleOutImage; if ( m_Parameters.m_SignalGen.m_SimulateKspaceAcquisition ) // do k-space stuff { m_StatusText += this->GetTime()+" > Adjusting complex signal\n"; MITK_INFO << "Adjusting complex signal:"; if (m_Parameters.m_SignalGen.m_DoSimulateRelaxation) m_StatusText += "Simulating signal relaxation\n"; if (m_Parameters.m_SignalGen.m_FrequencyMap.IsNotNull()) m_StatusText += "Simulating distortions\n"; if (m_Parameters.m_SignalGen.m_DoAddGibbsRinging) m_StatusText += "Simulating ringing artifacts\n"; if (m_Parameters.m_SignalGen.m_EddyStrength>0) m_StatusText += "Simulating eddy currents\n"; if (m_Parameters.m_SignalGen.m_Spikes>0) m_StatusText += "Simulating spikes\n"; if (m_Parameters.m_SignalGen.m_CroppingFactor<1.0) m_StatusText += "Simulating aliasing artifacts\n"; if (m_Parameters.m_SignalGen.m_KspaceLineOffset>0) m_StatusText += "Simulating ghosts\n"; doubleOutImage = DoKspaceStuff(m_CompartmentImages); m_Parameters.m_SignalGen.m_SignalScale = 1; // already scaled in DoKspaceStuff } else // don't do k-space stuff, just sum compartments { m_StatusText += this->GetTime()+" > Summing compartments\n"; MITK_INFO << "Summing compartments"; doubleOutImage = m_CompartmentImages.at(0); for (unsigned int i=1; i::Pointer adder = itk::AddImageFilter< DoubleDwiType, DoubleDwiType, DoubleDwiType>::New(); adder->SetInput1(doubleOutImage); adder->SetInput2(m_CompartmentImages.at(i)); adder->Update(); doubleOutImage = adder->GetOutput(); } } if (this->GetAbortGenerateData()) { m_StatusText += "\n"+this->GetTime()+" > Simulation aborted\n"; return; } m_StatusText += this->GetTime()+" > Finalizing image\n"; MITK_INFO << "Finalizing image"; if (m_Parameters.m_SignalGen.m_SignalScale>1) m_StatusText += " Scaling signal\n"; if (m_Parameters.m_NoiseModel!=NULL) m_StatusText += " Adding noise\n"; unsigned int window = 0; unsigned int min = itk::NumericTraits::max(); ImageRegionIterator it4 (outImage, outImage->GetLargestPossibleRegion()); DoubleDwiType::PixelType signal; signal.SetSize(m_Parameters.m_SignalGen.GetNumVolumes()); boost::progress_display disp2(outImage->GetLargestPossibleRegion().GetNumberOfPixels()); m_StatusText += "0% 10 20 30 40 50 60 70 80 90 100%\n"; m_StatusText += "|----|----|----|----|----|----|----|----|----|----|\n*"; lastTick = 0; while(!it4.IsAtEnd()) { if (this->GetAbortGenerateData()) { m_StatusText += "\n"+this->GetTime()+" > Simulation aborted\n"; return; } ++disp2; unsigned long newTick = 50*disp2.count()/disp2.expected_count(); for (unsigned long tick = 0; tick<(newTick-lastTick); tick++) m_StatusText += "*"; lastTick = newTick; typename OutputImageType::IndexType index = it4.GetIndex(); signal = doubleOutImage->GetPixel(index)*m_Parameters.m_SignalGen.m_SignalScale; if (m_Parameters.m_NoiseModel!=NULL) m_Parameters.m_NoiseModel->AddNoise(signal); for (unsigned int i=0; i0) signal[i] = floor(signal[i]+0.5); else signal[i] = ceil(signal[i]-0.5); if ( (!m_Parameters.m_SignalGen.IsBaselineIndex(i) || signal.Size()==1) && signal[i]>window) window = signal[i]; if ( (!m_Parameters.m_SignalGen.IsBaselineIndex(i) || signal.Size()==1) && signal[i]SetNthOutput(0, outImage); m_StatusText += "\n\n"; m_StatusText += "Finished simulation\n"; m_StatusText += "Simulation time: "+GetTime(); m_TimeProbe.Stop(); } template< class PixelType > void TractsToDWIImageFilter< PixelType >::SimulateMotion(int g) { if (m_Parameters.m_SignalGen.m_DoAddMotion && gGetDeepCopy(); m_Rotation[0] = m_RandGen->GetVariateWithClosedRange(m_Parameters.m_SignalGen.m_Rotation[0]*2)-m_Parameters.m_SignalGen.m_Rotation[0]; m_Rotation[1] = m_RandGen->GetVariateWithClosedRange(m_Parameters.m_SignalGen.m_Rotation[1]*2)-m_Parameters.m_SignalGen.m_Rotation[1]; m_Rotation[2] = m_RandGen->GetVariateWithClosedRange(m_Parameters.m_SignalGen.m_Rotation[2]*2)-m_Parameters.m_SignalGen.m_Rotation[2]; m_Translation[0] = m_RandGen->GetVariateWithClosedRange(m_Parameters.m_SignalGen.m_Translation[0]*2)-m_Parameters.m_SignalGen.m_Translation[0]; m_Translation[1] = m_RandGen->GetVariateWithClosedRange(m_Parameters.m_SignalGen.m_Translation[1]*2)-m_Parameters.m_SignalGen.m_Translation[1]; m_Translation[2] = m_RandGen->GetVariateWithClosedRange(m_Parameters.m_SignalGen.m_Translation[2]*2)-m_Parameters.m_SignalGen.m_Translation[2]; } // rotate mask image if (m_MaskImageSet) { ImageRegionIterator maskIt(m_UpsampledMaskImage, m_UpsampledMaskImage->GetLargestPossibleRegion()); m_MaskImage->FillBuffer(0); while(!maskIt.IsAtEnd()) { if (maskIt.Get()<=0) { ++maskIt; continue; } DoubleDwiType::IndexType index = maskIt.GetIndex(); itk::Point point; m_UpsampledMaskImage->TransformIndexToPhysicalPoint(index, point); if (m_Parameters.m_SignalGen.m_DoRandomizeMotion) point = m_FiberBundleWorkingCopy->TransformPoint(point.GetVnlVector(), m_Rotation[0],m_Rotation[1],m_Rotation[2],m_Translation[0],m_Translation[1],m_Translation[2]); else point = m_FiberBundleWorkingCopy->TransformPoint(point.GetVnlVector(), m_Rotation[0]*(g+1),m_Rotation[1]*(g+1),m_Rotation[2]*(g+1),m_Translation[0]*(g+1),m_Translation[1]*(g+1),m_Translation[2]*(g+1)); m_MaskImage->TransformPhysicalPointToIndex(point, index); if (m_MaskImage->GetLargestPossibleRegion().IsInside(index)) m_MaskImage->SetPixel(index,100); ++maskIt; } // itk::ImageFileWriter::Pointer wr = itk::ImageFileWriter::New(); // wr->SetInput(m_MaskImage); // wr->SetFileName("/local/MASK_transformed.nrrd"); // wr->Update(); } if (m_HelperTdiUpsampled.IsNotNull()) { ImageRegionIterator maskIt(m_HelperTdiUpsampled, m_HelperTdiUpsampled->GetLargestPossibleRegion()); m_HelperTdiTransformed->FillBuffer(0); m_HelperTdiCounter->FillBuffer(0); while(!maskIt.IsAtEnd()) { DoubleDwiType::IndexType index = maskIt.GetIndex(); itk::Point point; m_HelperTdiUpsampled->TransformIndexToPhysicalPoint(index, point); if (m_Parameters.m_SignalGen.m_DoRandomizeMotion) point = m_FiberBundleWorkingCopy->TransformPoint(point.GetVnlVector(), m_Rotation[0],m_Rotation[1],m_Rotation[2],m_Translation[0],m_Translation[1],m_Translation[2]); else point = m_FiberBundleWorkingCopy->TransformPoint(point.GetVnlVector(), m_Rotation[0]*(g+1),m_Rotation[1]*(g+1),m_Rotation[2]*(g+1),m_Translation[0]*(g+1),m_Translation[1]*(g+1),m_Translation[2]*(g+1)); m_HelperTdiTransformed->TransformPhysicalPointToIndex(point, index); if (m_HelperTdiTransformed->GetLargestPossibleRegion().IsInside(index) && m_MaskImage->GetPixel(index)>0) { m_HelperTdiTransformed->SetPixel(index, m_HelperTdiTransformed->GetPixel(index)+maskIt.Get()); m_HelperTdiCounter->SetPixel(index, m_HelperTdiCounter->GetPixel(index)+1); } ++maskIt; } ImageRegionIterator maskIt2(m_HelperTdiTransformed, m_HelperTdiTransformed->GetLargestPossibleRegion()); while(!maskIt2.IsAtEnd()) { DoubleDwiType::IndexType index = maskIt2.GetIndex(); if (m_HelperTdiCounter->GetPixel(index)>0) { m_HelperTdiTransformed->SetPixel(index, maskIt2.Get()/m_HelperTdiCounter->GetPixel(index)); } ++maskIt2; } -// itk::ImageFileWriter::Pointer wr = itk::ImageFileWriter::New(); -// wr->SetInput(m_HelperTdiTransformed); -// wr->SetFileName("/local/TDI_transformed.nrrd"); -// wr->Update(); + itk::ImageFileWriter::Pointer wr = itk::ImageFileWriter::New(); + wr->SetInput(m_HelperTdiTransformed); + wr->SetFileName("/local/TDI_transformed.nrrd"); + wr->Update(); } // rotate fibers if (m_Logfile.is_open()) { m_Logfile << g+1 << " rotation: " << m_Rotation[0] << "," << m_Rotation[1] << "," << m_Rotation[2] << ";"; m_Logfile << " translation: " << m_Translation[0] << "," << m_Translation[1] << "," << m_Translation[2] << "\n"; } m_FiberBundleTransformed->TransformFibers(m_Rotation[0],m_Rotation[1],m_Rotation[2],m_Translation[0],m_Translation[1],m_Translation[2]); } } template< class PixelType > void TractsToDWIImageFilter< PixelType >::SimulateNonFiberSignal(ItkUcharImgType::IndexType index, double intraAxonalVolume, int g) { int numFiberCompartments = m_Parameters.m_FiberModelList.size(); int numNonFiberCompartments = m_Parameters.m_NonFiberModelList.size(); if (intraAxonalVolume>0.0001 && m_Parameters.m_SignalGen.m_DoDisablePartialVolume) // only fiber in voxel { DoubleDwiType::PixelType pix = m_CompartmentImages.at(0)->GetPixel(index); if (g>=0) pix[g] *= m_VoxelVolume/intraAxonalVolume; else pix *= m_VoxelVolume/intraAxonalVolume; m_CompartmentImages.at(0)->SetPixel(index, pix); m_VolumeFractions.at(0)->SetPixel(index, 1); for (int i=1; iGetPixel(index); if (g>=0) pix[g] = 0.0; else pix.Fill(0.0); m_CompartmentImages.at(i)->SetPixel(index, pix); } } else { m_VolumeFractions.at(0)->SetPixel(index, intraAxonalVolume/m_VoxelVolume); itk::Point point; m_MaskImage->TransformIndexToPhysicalPoint(index, point); if (m_Parameters.m_SignalGen.m_DoAddMotion) { if (m_Parameters.m_SignalGen.m_DoRandomizeMotion && g>0) point = m_FiberBundleWorkingCopy->TransformPoint(point.GetVnlVector(), -m_Rotation[0],-m_Rotation[1],-m_Rotation[2],-m_Translation[0],-m_Translation[1],-m_Translation[2]); else if (g>=0) point = m_FiberBundleWorkingCopy->TransformPoint(point.GetVnlVector(), -m_Rotation[0]*g,-m_Rotation[1]*g,-m_Rotation[2]*g,-m_Translation[0]*g,-m_Translation[1]*g,-m_Translation[2]*g); } if (m_Parameters.m_SignalGen.m_DoDisablePartialVolume) { int maxVolumeIndex = 0; double maxWeight = 0; for (int i=0; i1) { ItkUcharImgType::IndexType maskIndex; m_UpsampledMaskImage->TransformPhysicalPointToIndex(point, maskIndex); if (!m_UpsampledMaskImage->GetLargestPossibleRegion().IsInside(maskIndex) || m_UpsampledMaskImage->GetPixel(maskIndex)==0) continue; DoubleDwiType::IndexType newIndex; m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->TransformPhysicalPointToIndex(point, newIndex); if (!m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetLargestPossibleRegion().IsInside(newIndex)) continue; weight = m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetPixel(newIndex); } if (weight>maxWeight) { maxWeight = weight; maxVolumeIndex = i; } } DoubleDwiType::Pointer doubleDwi = m_CompartmentImages.at(maxVolumeIndex+numFiberCompartments); DoubleDwiType::PixelType pix = doubleDwi->GetPixel(index); if (g>=0) pix[g] += m_Parameters.m_NonFiberModelList[maxVolumeIndex]->SimulateMeasurement(g); else pix += m_Parameters.m_NonFiberModelList[maxVolumeIndex]->SimulateMeasurement(); doubleDwi->SetPixel(index, pix); m_VolumeFractions.at(maxVolumeIndex+numFiberCompartments)->SetPixel(index, 1); } else { +// double extraAxonalVolume = m_VoxelVolume-intraAxonalVolume; // non-fiber volume +// if (extraAxonalVolume<0) +// extraAxonalVolume = 0; + +// double interAxonalVolume = 0; +// if (numFiberCompartments>1) +// interAxonalVolume = 0.5*intraAxonalVolume; // inter-axonal fraction of non fiber compartment scales linearly with f + +// double other = extraAxonalVolume - interAxonalVolume; // rest of compartment +// if (other<0) +// { +// other = 0; +// interAxonalVolume = extraAxonalVolume; +// } +// double singleinter = interAxonalVolume/(numFiberCompartments-1); + double extraAxonalVolume = m_VoxelVolume-intraAxonalVolume; // non-fiber volume + if (extraAxonalVolume<0) + extraAxonalVolume = 0; double interAxonalVolume = 0; if (numFiberCompartments>1) interAxonalVolume = extraAxonalVolume * intraAxonalVolume/m_VoxelVolume; // inter-axonal fraction of non fiber compartment scales linearly with f double other = extraAxonalVolume - interAxonalVolume; // rest of compartment + if (other<0) + other = 0; double singleinter = interAxonalVolume/(numFiberCompartments-1); // adjust non-fiber and intra-axonal signal for (int i=1; iGetPixel(index); if (intraAxonalVolume>0) // remove scaling by intra-axonal volume from inter-axonal compartment { if (g>=0) pix[g] /= intraAxonalVolume; else pix /= intraAxonalVolume; } if (g>=0) pix[g] *= singleinter; else pix *= singleinter; m_CompartmentImages.at(i)->SetPixel(index, pix); m_VolumeFractions.at(i)->SetPixel(index, singleinter/m_VoxelVolume); } for (int i=0; i1) { ItkUcharImgType::IndexType maskIndex; m_UpsampledMaskImage->TransformPhysicalPointToIndex(point, maskIndex); if (!m_UpsampledMaskImage->GetLargestPossibleRegion().IsInside(maskIndex) || m_UpsampledMaskImage->GetPixel(maskIndex)==0) continue; DoubleDwiType::IndexType newIndex; m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->TransformPhysicalPointToIndex(point, newIndex); if (!m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetLargestPossibleRegion().IsInside(newIndex)) continue; weight = m_Parameters.m_NonFiberModelList[i]->GetVolumeFractionImage()->GetPixel(newIndex); } DoubleDwiType::Pointer doubleDwi = m_CompartmentImages.at(i+numFiberCompartments); DoubleDwiType::PixelType pix = doubleDwi->GetPixel(index); if (g>=0) pix[g] += m_Parameters.m_NonFiberModelList[i]->SimulateMeasurement(g)*other*weight; else pix += m_Parameters.m_NonFiberModelList[i]->SimulateMeasurement()*other*weight; doubleDwi->SetPixel(index, pix); m_VolumeFractions.at(i+numFiberCompartments)->SetPixel(index, other/m_VoxelVolume*weight); } } } } template< class PixelType > itk::Point TractsToDWIImageFilter< PixelType >::GetItkPoint(double point[3]) { itk::Point itkPoint; itkPoint[0] = point[0]; itkPoint[1] = point[1]; itkPoint[2] = point[2]; return itkPoint; } template< class PixelType > itk::Vector TractsToDWIImageFilter< PixelType >::GetItkVector(double point[3]) { itk::Vector itkVector; itkVector[0] = point[0]; itkVector[1] = point[1]; itkVector[2] = point[2]; return itkVector; } template< class PixelType > vnl_vector_fixed TractsToDWIImageFilter< PixelType >::GetVnlVector(double point[3]) { vnl_vector_fixed vnlVector; vnlVector[0] = point[0]; vnlVector[1] = point[1]; vnlVector[2] = point[2]; return vnlVector; } template< class PixelType > vnl_vector_fixed TractsToDWIImageFilter< PixelType >::GetVnlVector(Vector& vector) { vnl_vector_fixed vnlVector; vnlVector[0] = vector[0]; vnlVector[1] = vector[1]; vnlVector[2] = vector[2]; return vnlVector; } template< class PixelType > double TractsToDWIImageFilter< PixelType >::RoundToNearest(double num) { return (num > 0.0) ? floor(num + 0.5) : ceil(num - 0.5); } template< class PixelType > std::string TractsToDWIImageFilter< PixelType >::GetTime() { m_TimeProbe.Stop(); unsigned long total = RoundToNearest(m_TimeProbe.GetTotal()); unsigned long hours = total/3600; unsigned long minutes = (total%3600)/60; unsigned long seconds = total%60; std::string out = ""; out.append(boost::lexical_cast(hours)); out.append(":"); out.append(boost::lexical_cast(minutes)); out.append(":"); out.append(boost::lexical_cast(seconds)); m_TimeProbe.Start(); return out; } } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.cpp index 621a4dab8c..cb3ed05a02 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.cpp @@ -1,1035 +1,1020 @@ /*=================================================================== 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 "QmitkControlVisualizationPropertiesView.h" #include "mitkNodePredicateDataType.h" #include "mitkDataNodeObject.h" #include "mitkOdfNormalizationMethodProperty.h" #include "mitkOdfScaleByProperty.h" #include "mitkResliceMethodProperty.h" #include "mitkRenderingManager.h" #include "mitkTbssImage.h" #include "mitkPlanarFigure.h" #include "mitkFiberBundleX.h" #include "QmitkDataStorageComboBox.h" #include "QmitkStdMultiWidget.h" #include "mitkFiberBundleInteractor.h" #include "mitkPlanarFigureInteractor.h" #include #include #include #include #include #include "mitkGlobalInteraction.h" #include "usModuleRegistry.h" #include "mitkPlaneGeometry.h" #include "berryIWorkbenchWindow.h" #include "berryIWorkbenchPage.h" #include "berryISelectionService.h" #include "berryConstants.h" #include "berryPlatformUI.h" #include "itkRGBAPixel.h" #include #include "qwidgetaction.h" #include "qcolordialog.h" #include #include #define ROUND(a) ((a)>0 ? (int)((a)+0.5) : -(int)(0.5-(a))) const std::string QmitkControlVisualizationPropertiesView::VIEW_ID = "org.mitk.views.controlvisualizationpropertiesview"; using namespace berry; QmitkControlVisualizationPropertiesView::QmitkControlVisualizationPropertiesView() : QmitkFunctionality(), m_Controls(NULL), m_MultiWidget(NULL), m_NodeUsedForOdfVisualization(NULL), m_IconTexOFF(new QIcon(":/QmitkDiffusionImaging/texIntOFFIcon.png")), m_IconTexON(new QIcon(":/QmitkDiffusionImaging/texIntONIcon.png")), m_IconGlyOFF_T(new QIcon(":/QmitkDiffusionImaging/glyphsoff_T.png")), m_IconGlyON_T(new QIcon(":/QmitkDiffusionImaging/glyphson_T.png")), m_IconGlyOFF_C(new QIcon(":/QmitkDiffusionImaging/glyphsoff_C.png")), m_IconGlyON_C(new QIcon(":/QmitkDiffusionImaging/glyphson_C.png")), m_IconGlyOFF_S(new QIcon(":/QmitkDiffusionImaging/glyphsoff_S.png")), m_IconGlyON_S(new QIcon(":/QmitkDiffusionImaging/glyphson_S.png")), m_CurrentSelection(0), m_CurrentPickingNode(0), m_GlyIsOn_S(false), m_GlyIsOn_C(false), m_GlyIsOn_T(false), m_FiberBundleObserverTag(0), m_FiberBundleObserveOpacityTag(0), m_Color(NULL) { currentThickSlicesMode = 1; m_MyMenu = NULL; int numThread = itk::MultiThreader::GetGlobalMaximumNumberOfThreads(); if (numThread > 12) numThread = 12; itk::MultiThreader::SetGlobalDefaultNumberOfThreads(numThread); } QmitkControlVisualizationPropertiesView::QmitkControlVisualizationPropertiesView(const QmitkControlVisualizationPropertiesView& other) { Q_UNUSED(other) throw std::runtime_error("Copy constructor not implemented"); } QmitkControlVisualizationPropertiesView::~QmitkControlVisualizationPropertiesView() { if(m_SlicesRotationObserverTag1 ) { mitk::SlicesCoordinator::Pointer coordinator = m_MultiWidget->GetSlicesRotator(); if( coordinator.IsNotNull() ) coordinator->RemoveObserver(m_SlicesRotationObserverTag1); } if( m_SlicesRotationObserverTag2) { mitk::SlicesCoordinator::Pointer coordinator = m_MultiWidget->GetSlicesRotator(); if( coordinator.IsNotNull() ) coordinator->RemoveObserver(m_SlicesRotationObserverTag1); } this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->RemovePostSelectionListener(/*"org.mitk.views.datamanager",*/ m_SelListener); } void QmitkControlVisualizationPropertiesView::OnThickSlicesModeSelected( QAction* action ) { currentThickSlicesMode = action->data().toInt(); switch(currentThickSlicesMode) { default: case 1: this->m_Controls->m_TSMenu->setText("MIP"); break; case 2: this->m_Controls->m_TSMenu->setText("SUM"); break; case 3: this->m_Controls->m_TSMenu->setText("WEIGH"); break; } mitk::DataNode* n; n = this->m_MultiWidget->GetWidgetPlane1(); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); n = this->m_MultiWidget->GetWidgetPlane2(); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); n = this->m_MultiWidget->GetWidgetPlane3(); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); mitk::BaseRenderer::Pointer renderer = this->GetActiveStdMultiWidget()->GetRenderWindow1()->GetRenderer(); if(renderer.IsNotNull()) { renderer->SendUpdateSlice(); } renderer = this->GetActiveStdMultiWidget()->GetRenderWindow2()->GetRenderer(); if(renderer.IsNotNull()) { renderer->SendUpdateSlice(); } renderer = this->GetActiveStdMultiWidget()->GetRenderWindow3()->GetRenderer(); if(renderer.IsNotNull()) { renderer->SendUpdateSlice(); } renderer->GetRenderingManager()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::OnTSNumChanged(int num) { if(num==0) { mitk::DataNode* n; n = this->m_MultiWidget->GetWidgetPlane1(); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( 0 ) ); if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( false ) ); n = this->m_MultiWidget->GetWidgetPlane2(); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( 0 ) ); if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( false ) ); n = this->m_MultiWidget->GetWidgetPlane3(); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( 0 ) ); if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( false ) ); } else { mitk::DataNode* n; n = this->m_MultiWidget->GetWidgetPlane1(); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( (num>0) ) ); n = this->m_MultiWidget->GetWidgetPlane2(); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( (num>0) ) ); n = this->m_MultiWidget->GetWidgetPlane3(); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) ); if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) ); if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( (num>0) ) ); } m_TSLabel->setText(QString::number(num*2+1)); mitk::BaseRenderer::Pointer renderer = this->GetActiveStdMultiWidget()->GetRenderWindow1()->GetRenderer(); if(renderer.IsNotNull()) renderer->SendUpdateSlice(); renderer = this->GetActiveStdMultiWidget()->GetRenderWindow2()->GetRenderer(); if(renderer.IsNotNull()) renderer->SendUpdateSlice(); renderer = this->GetActiveStdMultiWidget()->GetRenderWindow3()->GetRenderer(); if(renderer.IsNotNull()) renderer->SendUpdateSlice(); renderer->GetRenderingManager()->RequestUpdateAll(mitk::RenderingManager::REQUEST_UPDATE_2DWINDOWS); } void QmitkControlVisualizationPropertiesView::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkControlVisualizationPropertiesViewControls; m_Controls->setupUi(parent); this->CreateConnections(); // hide warning (ODFs in rotated planes) m_Controls->m_lblRotatedPlanesWarning->hide(); m_MyMenu = new QMenu(parent); m_Controls->m_TSMenu->setMenu( m_MyMenu ); QIcon iconFiberFade(":/QmitkDiffusionImaging/MapperEfx2D.png"); m_Controls->m_FiberFading2D->setIcon(iconFiberFade); #ifndef DIFFUSION_IMAGING_EXTENDED int size = m_Controls->m_AdditionalScaling->count(); for(int t=0; tm_AdditionalScaling->itemText(t).toStdString() == "Scale by ASR") { m_Controls->m_AdditionalScaling->removeItem(t); } } #endif m_Controls->m_ScalingFrame->setVisible(false); m_Controls->m_NormalizationFrame->setVisible(false); } } void QmitkControlVisualizationPropertiesView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; if (m_MultiWidget) { mitk::SlicesCoordinator* coordinator = m_MultiWidget->GetSlicesRotator(); if (coordinator) { itk::ReceptorMemberCommand::Pointer command2 = itk::ReceptorMemberCommand::New(); command2->SetCallbackFunction( this, &QmitkControlVisualizationPropertiesView::SliceRotation ); m_SlicesRotationObserverTag1 = coordinator->AddObserver( mitk::SliceRotationEvent(), command2 ); } coordinator = m_MultiWidget->GetSlicesSwiveller(); if (coordinator) { itk::ReceptorMemberCommand::Pointer command2 = itk::ReceptorMemberCommand::New(); command2->SetCallbackFunction( this, &QmitkControlVisualizationPropertiesView::SliceRotation ); m_SlicesRotationObserverTag2 = coordinator->AddObserver( mitk::SliceRotationEvent(), command2 ); } } } void QmitkControlVisualizationPropertiesView::SliceRotation(const itk::EventObject&) { // test if plane rotated if( m_GlyIsOn_T || m_GlyIsOn_C || m_GlyIsOn_S ) { if( this->IsPlaneRotated() ) { // show label m_Controls->m_lblRotatedPlanesWarning->show(); } else { //hide label m_Controls->m_lblRotatedPlanesWarning->hide(); } } } void QmitkControlVisualizationPropertiesView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } void QmitkControlVisualizationPropertiesView::NodeRemoved(const mitk::DataNode* node) { } #include void QmitkControlVisualizationPropertiesView::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->m_VisibleOdfsON_T), SIGNAL(clicked()), this, SLOT(VisibleOdfsON_T()) ); connect( (QObject*)(m_Controls->m_VisibleOdfsON_S), SIGNAL(clicked()), this, SLOT(VisibleOdfsON_S()) ); connect( (QObject*)(m_Controls->m_VisibleOdfsON_C), SIGNAL(clicked()), this, SLOT(VisibleOdfsON_C()) ); connect( (QObject*)(m_Controls->m_ShowMaxNumber), SIGNAL(editingFinished()), this, SLOT(ShowMaxNumberChanged()) ); connect( (QObject*)(m_Controls->m_NormalizationDropdown), SIGNAL(currentIndexChanged(int)), this, SLOT(NormalizationDropdownChanged(int)) ); connect( (QObject*)(m_Controls->m_ScalingFactor), SIGNAL(valueChanged(double)), this, SLOT(ScalingFactorChanged(double)) ); connect( (QObject*)(m_Controls->m_AdditionalScaling), SIGNAL(currentIndexChanged(int)), this, SLOT(AdditionalScaling(int)) ); connect( (QObject*)(m_Controls->m_ScalingCheckbox), SIGNAL(clicked()), this, SLOT(ScalingCheckbox()) ); connect((QObject*) m_Controls->m_ResetColoring, SIGNAL(clicked()), (QObject*) this, SLOT(BundleRepresentationResetColoring())); connect((QObject*) m_Controls->m_FiberFading2D, SIGNAL(clicked()), (QObject*) this, SLOT( Fiber2DfadingEFX() ) ); connect((QObject*) m_Controls->m_FiberThicknessSlider, SIGNAL(sliderReleased()), (QObject*) this, SLOT( FiberSlicingThickness2D() ) ); connect((QObject*) m_Controls->m_FiberThicknessSlider, SIGNAL(valueChanged(int)), (QObject*) this, SLOT( FiberSlicingUpdateLabel(int) )); connect((QObject*) m_Controls->m_Crosshair, SIGNAL(clicked()), (QObject*) this, SLOT(SetInteractor())); connect((QObject*) m_Controls->m_LineWidth, SIGNAL(editingFinished()), (QObject*) this, SLOT(LineWidthChanged())); - connect((QObject*) m_Controls->m_TubeWidth, SIGNAL(editingFinished()), (QObject*) this, SLOT(TubeRadiusChanged())); } } void QmitkControlVisualizationPropertiesView::Activated() { } void QmitkControlVisualizationPropertiesView::Deactivated() { } // set diffusion image channel to b0 volume void QmitkControlVisualizationPropertiesView::NodeAdded(const mitk::DataNode *node) { mitk::DataNode* notConst = const_cast(node); bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast(node->GetData())) ); if (isDiffusionImage) { mitk::Image::Pointer dimg = dynamic_cast(notConst->GetData()); // if there is no b0 image in the dataset, the GetB0Indices() returns a vector of size 0 // and hence we cannot set the Property directly to .front() int displayChannelPropertyValue = 0; mitk::BValueMapProperty* bmapproperty = static_cast(dimg->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() ); mitk::DiffusionPropertyHelper::BValueMapType map = bmapproperty->GetBValueMap(); if( map[0].size() > 0) displayChannelPropertyValue = map[0].front(); notConst->SetIntProperty("DisplayChannel", displayChannelPropertyValue ); } } /* OnSelectionChanged is registered to SelectionService, therefore no need to implement SelectionService Listener explicitly */ void QmitkControlVisualizationPropertiesView::OnSelectionChanged( std::vector nodes ) { m_Controls->m_BundleControlsFrame->setVisible(false); m_Controls->m_ImageControlsFrame->setVisible(false); if (nodes.size()>1) // only do stuff if one node is selected return; m_Controls->m_NumberGlyphsFrame->setVisible(false); m_Controls->m_GlyphFrame->setVisible(false); m_Controls->m_TSMenu->setVisible(false); m_SelectedNode = NULL; int numOdfImages = 0; for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { mitk::DataNode::Pointer node = *it; if(node.IsNull()) continue; mitk::BaseData* nodeData = node->GetData(); if(nodeData == NULL) continue; m_SelectedNode = node; if (dynamic_cast(nodeData)) { // handle fiber bundle property observers if (m_Color.IsNotNull()) m_Color->RemoveObserver(m_FiberBundleObserverTag); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkControlVisualizationPropertiesView::SetFiberBundleCustomColor ); m_Color = dynamic_cast(node->GetProperty("color", NULL)); if (m_Color.IsNotNull()) m_FiberBundleObserverTag = m_Color->AddObserver( itk::ModifiedEvent(), command ); if (m_Opacity.IsNotNull()) m_Opacity->RemoveObserver(m_FiberBundleObserveOpacityTag); itk::ReceptorMemberCommand::Pointer command2 = itk::ReceptorMemberCommand::New(); command2->SetCallbackFunction( this, &QmitkControlVisualizationPropertiesView::SetFiberBundleOpacity ); m_Opacity = dynamic_cast(node->GetProperty("opacity", NULL)); if (m_Opacity.IsNotNull()) m_FiberBundleObserveOpacityTag = m_Opacity->AddObserver( itk::ModifiedEvent(), command2 ); m_Controls->m_BundleControlsFrame->setVisible(true); // ??? if(m_CurrentPickingNode != 0 && node.GetPointer() != m_CurrentPickingNode) m_Controls->m_Crosshair->setEnabled(false); else m_Controls->m_Crosshair->setEnabled(true); int width; node->GetIntProperty("LineWidth", width); m_Controls->m_LineWidth->setValue(width); - float radius; - node->GetFloatProperty("TubeRadius", radius); - m_Controls->m_TubeWidth->setValue(radius); - float range; node->GetFloatProperty("Fiber2DSliceThickness",range); mitk::FiberBundleX::Pointer fib = dynamic_cast(node->GetData()); mitk::BaseGeometry::Pointer geo = fib->GetGeometry(); mitk::ScalarType max = geo->GetExtentInMM(0); max = std::max(max, geo->GetExtentInMM(1)); max = std::max(max, geo->GetExtentInMM(2)); m_Controls->m_FiberThicknessSlider->setMaximum(max * 10); m_Controls->m_FiberThicknessSlider->setValue(range * 10); } else if(dynamic_cast(nodeData) || dynamic_cast(nodeData)) { m_Controls->m_ImageControlsFrame->setVisible(true); m_Controls->m_NumberGlyphsFrame->setVisible(true); m_Controls->m_GlyphFrame->setVisible(true); if(m_NodeUsedForOdfVisualization.IsNotNull()) { m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_S", false); m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_C", false); m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_T", false); } m_NodeUsedForOdfVisualization = node; m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_S", m_GlyIsOn_S); m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_C", m_GlyIsOn_C); m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_T", m_GlyIsOn_T); int val; node->GetIntProperty("ShowMaxNumber", val); m_Controls->m_ShowMaxNumber->setValue(val); m_Controls->m_NormalizationDropdown->setCurrentIndex(dynamic_cast(node->GetProperty("Normalization"))->GetValueAsId()); float fval; node->GetFloatProperty("Scaling",fval); m_Controls->m_ScalingFactor->setValue(fval); m_Controls->m_AdditionalScaling->setCurrentIndex(dynamic_cast(node->GetProperty("ScaleBy"))->GetValueAsId()); numOdfImages++; } else if(dynamic_cast(nodeData)) { PlanarFigureFocus(); } else if( dynamic_cast(nodeData) ) { m_Controls->m_ImageControlsFrame->setVisible(true); m_Controls->m_TSMenu->setVisible(true); } } if( nodes.empty() ) return; mitk::DataNode::Pointer node = nodes.at(0); if( node.IsNull() ) return; QMenu *myMenu = m_MyMenu; myMenu->clear(); QActionGroup* thickSlicesActionGroup = new QActionGroup(myMenu); thickSlicesActionGroup->setExclusive(true); int currentTSMode = 0; { mitk::ResliceMethodProperty::Pointer m = dynamic_cast(node->GetProperty( "reslice.thickslices" )); if( m.IsNotNull() ) currentTSMode = m->GetValueAsId(); } int maxTS = 30; for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { mitk::Image* image = dynamic_cast((*it)->GetData()); if (image) { int size = std::max(image->GetDimension(0), std::max(image->GetDimension(1), image->GetDimension(2))); if (size>maxTS) maxTS=size; } } maxTS /= 2; int currentNum = 0; { mitk::IntProperty::Pointer m = dynamic_cast(node->GetProperty( "reslice.thickslices.num" )); if( m.IsNotNull() ) { currentNum = m->GetValue(); if(currentNum < 0) currentNum = 0; if(currentNum > maxTS) currentNum = maxTS; } } if(currentTSMode==0) currentNum=0; QSlider *m_TSSlider = new QSlider(myMenu); m_TSSlider->setMinimum(0); m_TSSlider->setMaximum(maxTS-1); m_TSSlider->setValue(currentNum); m_TSSlider->setOrientation(Qt::Horizontal); connect( m_TSSlider, SIGNAL( valueChanged(int) ), this, SLOT( OnTSNumChanged(int) ) ); QHBoxLayout* _TSLayout = new QHBoxLayout; _TSLayout->setContentsMargins(4,4,4,4); _TSLayout->addWidget(m_TSSlider); _TSLayout->addWidget(m_TSLabel=new QLabel(QString::number(currentNum*2+1),myMenu)); QWidget* _TSWidget = new QWidget; _TSWidget->setLayout(_TSLayout); QActionGroup* thickSliceModeActionGroup = new QActionGroup(myMenu); thickSliceModeActionGroup->setExclusive(true); QWidgetAction *m_TSSliderAction = new QWidgetAction(myMenu); m_TSSliderAction->setDefaultWidget(_TSWidget); myMenu->addAction(m_TSSliderAction); QAction* mipThickSlicesAction = new QAction(myMenu); mipThickSlicesAction->setActionGroup(thickSliceModeActionGroup); mipThickSlicesAction->setText("MIP (max. intensity proj.)"); mipThickSlicesAction->setCheckable(true); mipThickSlicesAction->setChecked(currentThickSlicesMode==1); mipThickSlicesAction->setData(1); myMenu->addAction( mipThickSlicesAction ); QAction* sumThickSlicesAction = new QAction(myMenu); sumThickSlicesAction->setActionGroup(thickSliceModeActionGroup); sumThickSlicesAction->setText("SUM (sum intensity proj.)"); sumThickSlicesAction->setCheckable(true); sumThickSlicesAction->setChecked(currentThickSlicesMode==2); sumThickSlicesAction->setData(2); myMenu->addAction( sumThickSlicesAction ); QAction* weightedThickSlicesAction = new QAction(myMenu); weightedThickSlicesAction->setActionGroup(thickSliceModeActionGroup); weightedThickSlicesAction->setText("WEIGHTED (gaussian proj.)"); weightedThickSlicesAction->setCheckable(true); weightedThickSlicesAction->setChecked(currentThickSlicesMode==3); weightedThickSlicesAction->setData(3); myMenu->addAction( weightedThickSlicesAction ); connect( thickSliceModeActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(OnThickSlicesModeSelected(QAction*)) ); } void QmitkControlVisualizationPropertiesView::VisibleOdfsON_S() { m_GlyIsOn_S = m_Controls->m_VisibleOdfsON_S->isChecked(); if (m_NodeUsedForOdfVisualization.IsNull()) { MITK_WARN << "ODF visualization activated but m_NodeUsedForOdfVisualization is NULL"; return; } m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_S", m_GlyIsOn_S); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::VisibleOdfsON_T() { m_GlyIsOn_T = m_Controls->m_VisibleOdfsON_T->isChecked(); if (m_NodeUsedForOdfVisualization.IsNull()) { MITK_WARN << "ODF visualization activated but m_NodeUsedForOdfVisualization is NULL"; return; } m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_T", m_GlyIsOn_T); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::VisibleOdfsON_C() { m_GlyIsOn_C = m_Controls->m_VisibleOdfsON_C->isChecked(); if (m_NodeUsedForOdfVisualization.IsNull()) { MITK_WARN << "ODF visualization activated but m_NodeUsedForOdfVisualization is NULL"; return; } m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_C", m_GlyIsOn_C); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } bool QmitkControlVisualizationPropertiesView::IsPlaneRotated() { mitk::Image* currentImage = dynamic_cast( m_NodeUsedForOdfVisualization->GetData() ); if( currentImage == NULL ) { MITK_ERROR << " Casting problems. Returning false"; return false; } mitk::Vector3D imageNormal0 = currentImage->GetSlicedGeometry()->GetAxisVector(0); mitk::Vector3D imageNormal1 = currentImage->GetSlicedGeometry()->GetAxisVector(1); mitk::Vector3D imageNormal2 = currentImage->GetSlicedGeometry()->GetAxisVector(2); imageNormal0.Normalize(); imageNormal1.Normalize(); imageNormal2.Normalize(); double eps = 0.000001; // for all 2D renderwindows of m_MultiWidget check alignment { mitk::PlaneGeometry::ConstPointer displayPlane = dynamic_cast( m_MultiWidget->GetRenderWindow1()->GetRenderer()->GetCurrentWorldGeometry2D() ); if (displayPlane.IsNull()) return false; mitk::Vector3D normal = displayPlane->GetNormal(); normal.Normalize(); int test = 0; if( fabs(fabs(dot_product(normal.GetVnlVector(),imageNormal0.GetVnlVector()))-1) > eps ) test++; if( fabs(fabs(dot_product(normal.GetVnlVector(),imageNormal1.GetVnlVector()))-1) > eps ) test++; if( fabs(fabs(dot_product(normal.GetVnlVector(),imageNormal2.GetVnlVector()))-1) > eps ) test++; if (test==3) return true; } { mitk::PlaneGeometry::ConstPointer displayPlane = dynamic_cast( m_MultiWidget->GetRenderWindow2()->GetRenderer()->GetCurrentWorldGeometry2D() ); if (displayPlane.IsNull()) return false; mitk::Vector3D normal = displayPlane->GetNormal(); normal.Normalize(); int test = 0; if( fabs(fabs(dot_product(normal.GetVnlVector(),imageNormal0.GetVnlVector()))-1) > eps ) test++; if( fabs(fabs(dot_product(normal.GetVnlVector(),imageNormal1.GetVnlVector()))-1) > eps ) test++; if( fabs(fabs(dot_product(normal.GetVnlVector(),imageNormal2.GetVnlVector()))-1) > eps ) test++; if (test==3) return true; } { mitk::PlaneGeometry::ConstPointer displayPlane = dynamic_cast( m_MultiWidget->GetRenderWindow3()->GetRenderer()->GetCurrentWorldGeometry2D() ); if (displayPlane.IsNull()) return false; mitk::Vector3D normal = displayPlane->GetNormal(); normal.Normalize(); int test = 0; if( fabs(fabs(dot_product(normal.GetVnlVector(),imageNormal0.GetVnlVector()))-1) > eps ) test++; if( fabs(fabs(dot_product(normal.GetVnlVector(),imageNormal1.GetVnlVector()))-1) > eps ) test++; if( fabs(fabs(dot_product(normal.GetVnlVector(),imageNormal2.GetVnlVector()))-1) > eps ) test++; if (test==3) return true; } return false; } void QmitkControlVisualizationPropertiesView::ShowMaxNumberChanged() { int maxNr = m_Controls->m_ShowMaxNumber->value(); if ( maxNr < 1 ) { m_Controls->m_ShowMaxNumber->setValue( 1 ); maxNr = 1; } if (dynamic_cast(m_SelectedNode->GetData()) || dynamic_cast(m_SelectedNode->GetData())) m_SelectedNode->SetIntProperty("ShowMaxNumber", maxNr); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::NormalizationDropdownChanged(int normDropdown) { typedef mitk::OdfNormalizationMethodProperty PropType; PropType::Pointer normMeth = PropType::New(); switch(normDropdown) { case 0: normMeth->SetNormalizationToMinMax(); break; case 1: normMeth->SetNormalizationToMax(); break; case 2: normMeth->SetNormalizationToNone(); break; case 3: normMeth->SetNormalizationToGlobalMax(); break; default: normMeth->SetNormalizationToMinMax(); } if (dynamic_cast(m_SelectedNode->GetData()) || dynamic_cast(m_SelectedNode->GetData())) m_SelectedNode->SetProperty("Normalization", normMeth.GetPointer()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::ScalingFactorChanged(double scalingFactor) { if (dynamic_cast(m_SelectedNode->GetData()) || dynamic_cast(m_SelectedNode->GetData())) m_SelectedNode->SetFloatProperty("Scaling", scalingFactor); if(m_MultiWidget) m_MultiWidget->RequestUpdate(); } void QmitkControlVisualizationPropertiesView::AdditionalScaling(int additionalScaling) { typedef mitk::OdfScaleByProperty PropType; PropType::Pointer scaleBy = PropType::New(); switch(additionalScaling) { case 0: scaleBy->SetScaleByNothing(); break; case 1: scaleBy->SetScaleByGFA(); //m_Controls->params_frame->setVisible(true); break; #ifdef DIFFUSION_IMAGING_EXTENDED case 2: scaleBy->SetScaleByPrincipalCurvature(); // commented in for SPIE paper, Principle curvature scaling //m_Controls->params_frame->setVisible(true); break; #endif default: scaleBy->SetScaleByNothing(); } if (dynamic_cast(m_SelectedNode->GetData()) || dynamic_cast(m_SelectedNode->GetData())) m_SelectedNode->SetProperty("Normalization", scaleBy.GetPointer()); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkControlVisualizationPropertiesView::ScalingCheckbox() { m_Controls->m_ScalingFrame->setVisible( m_Controls->m_ScalingCheckbox->isChecked()); if(!m_Controls->m_ScalingCheckbox->isChecked()) { m_Controls->m_AdditionalScaling->setCurrentIndex(0); m_Controls->m_ScalingFactor->setValue(1.0); } } void QmitkControlVisualizationPropertiesView::Fiber2DfadingEFX() { if (m_SelectedNode && dynamic_cast(m_SelectedNode->GetData()) ) { bool currentMode; m_SelectedNode->GetBoolProperty("Fiber2DfadeEFX", currentMode); m_SelectedNode->SetProperty("Fiber2DfadeEFX", mitk::BoolProperty::New(!currentMode)); dynamic_cast(m_SelectedNode->GetData())->RequestUpdate2D(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkControlVisualizationPropertiesView::FiberSlicingThickness2D() { if (m_SelectedNode && dynamic_cast(m_SelectedNode->GetData())) { float fibThickness = m_Controls->m_FiberThicknessSlider->value() * 0.1; float currentThickness = 0; m_SelectedNode->GetFloatProperty("Fiber2DSliceThickness", currentThickness); if (fabs(fibThickness-currentThickness)<0.001) return; m_SelectedNode->SetProperty("Fiber2DSliceThickness", mitk::FloatProperty::New(fibThickness)); dynamic_cast(m_SelectedNode->GetData())->RequestUpdate2D(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkControlVisualizationPropertiesView::FiberSlicingUpdateLabel(int value) { QString label = "Range %1 mm"; label = label.arg(value * 0.1); m_Controls->label_range->setText(label); FiberSlicingThickness2D(); } void QmitkControlVisualizationPropertiesView::SetFiberBundleOpacity(const itk::EventObject& /*e*/) { if(m_SelectedNode) { mitk::FiberBundleX::Pointer fib = dynamic_cast(m_SelectedNode->GetData()); fib->RequestUpdate(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkControlVisualizationPropertiesView::SetFiberBundleCustomColor(const itk::EventObject& /*e*/) { if(m_SelectedNode && dynamic_cast(m_SelectedNode->GetData())) { float color[3]; m_SelectedNode->GetColor(color); mitk::FiberBundleX::Pointer fib = dynamic_cast(m_SelectedNode->GetData()); fib->SetFiberColors(color[0]*255, color[1]*255, color[2]*255); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkControlVisualizationPropertiesView::BundleRepresentationResetColoring() { if(m_SelectedNode && dynamic_cast(m_SelectedNode->GetData())) { mitk::FiberBundleX::Pointer fib = dynamic_cast(m_SelectedNode->GetData()); fib->DoColorCodingOrientationBased(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkControlVisualizationPropertiesView::PlanarFigureFocus() { if(m_SelectedNode) { mitk::PlanarFigure* _PlanarFigure = 0; _PlanarFigure = dynamic_cast (m_SelectedNode->GetData()); if (_PlanarFigure && _PlanarFigure->GetPlaneGeometry()) { QmitkRenderWindow* selectedRenderWindow = 0; bool PlanarFigureInitializedWindow = false; QmitkRenderWindow* RenderWindow1 = this->GetActiveStdMultiWidget()->GetRenderWindow1(); if (m_SelectedNode->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow1->GetRenderer())) { selectedRenderWindow = RenderWindow1; } QmitkRenderWindow* RenderWindow2 = this->GetActiveStdMultiWidget()->GetRenderWindow2(); if (!selectedRenderWindow && m_SelectedNode->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow2->GetRenderer())) { selectedRenderWindow = RenderWindow2; } QmitkRenderWindow* RenderWindow3 = this->GetActiveStdMultiWidget()->GetRenderWindow3(); if (!selectedRenderWindow && m_SelectedNode->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow3->GetRenderer())) { selectedRenderWindow = RenderWindow3; } QmitkRenderWindow* RenderWindow4 = this->GetActiveStdMultiWidget()->GetRenderWindow4(); if (!selectedRenderWindow && m_SelectedNode->GetBoolProperty( "PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow4->GetRenderer())) { selectedRenderWindow = RenderWindow4; } const mitk::PlaneGeometry* _PlaneGeometry = _PlanarFigure->GetPlaneGeometry(); mitk::VnlVector normal = _PlaneGeometry->GetNormalVnl(); mitk::Geometry2D::ConstPointer worldGeometry1 = RenderWindow1->GetRenderer()->GetCurrentWorldGeometry2D(); mitk::PlaneGeometry::ConstPointer _Plane1 = dynamic_cast( worldGeometry1.GetPointer() ); mitk::VnlVector normal1 = _Plane1->GetNormalVnl(); mitk::Geometry2D::ConstPointer worldGeometry2 = RenderWindow2->GetRenderer()->GetCurrentWorldGeometry2D(); mitk::PlaneGeometry::ConstPointer _Plane2 = dynamic_cast( worldGeometry2.GetPointer() ); mitk::VnlVector normal2 = _Plane2->GetNormalVnl(); mitk::Geometry2D::ConstPointer worldGeometry3 = RenderWindow3->GetRenderer()->GetCurrentWorldGeometry2D(); mitk::PlaneGeometry::ConstPointer _Plane3 = dynamic_cast( worldGeometry3.GetPointer() ); mitk::VnlVector normal3 = _Plane3->GetNormalVnl(); normal[0] = fabs(normal[0]); normal[1] = fabs(normal[1]); normal[2] = fabs(normal[2]); normal1[0] = fabs(normal1[0]); normal1[1] = fabs(normal1[1]); normal1[2] = fabs(normal1[2]); normal2[0] = fabs(normal2[0]); normal2[1] = fabs(normal2[1]); normal2[2] = fabs(normal2[2]); normal3[0] = fabs(normal3[0]); normal3[1] = fabs(normal3[1]); normal3[2] = fabs(normal3[2]); double ang1 = angle(normal, normal1); double ang2 = angle(normal, normal2); double ang3 = angle(normal, normal3); if(ang1 < ang2 && ang1 < ang3) { selectedRenderWindow = RenderWindow1; } else { if(ang2 < ang3) { selectedRenderWindow = RenderWindow2; } else { selectedRenderWindow = RenderWindow3; } } // make node visible if (selectedRenderWindow) { const mitk::Point3D& centerP = _PlaneGeometry->GetOrigin(); selectedRenderWindow->GetSliceNavigationController()->ReorientSlices( centerP, _PlaneGeometry->GetNormal()); } } // set interactor for new node (if not already set) mitk::PlanarFigureInteractor::Pointer figureInteractor = dynamic_cast(m_SelectedNode->GetDataInteractor().GetPointer()); if(figureInteractor.IsNull()) { figureInteractor = mitk::PlanarFigureInteractor::New(); us::Module* planarFigureModule = us::ModuleRegistry::GetModule( "MitkPlanarFigure" ); figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule ); figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule ); figureInteractor->SetDataNode( m_SelectedNode ); } m_SelectedNode->SetProperty("planarfigure.iseditable",mitk::BoolProperty::New(true)); } } void QmitkControlVisualizationPropertiesView::SetInteractor() { typedef std::vector Container; Container _NodeSet = this->GetDataManagerSelection(); mitk::DataNode* node = 0; mitk::FiberBundleX* bundle = 0; mitk::FiberBundleInteractor::Pointer bundleInteractor = 0; // finally add all nodes to the model for(Container::const_iterator it=_NodeSet.begin(); it!=_NodeSet.end() ; it++) { node = const_cast(*it); bundle = dynamic_cast(node->GetData()); if(bundle) { bundleInteractor = dynamic_cast(node->GetInteractor()); if(bundleInteractor.IsNotNull()) mitk::GlobalInteraction::GetInstance()->RemoveInteractor(bundleInteractor); if(!m_Controls->m_Crosshair->isChecked()) { m_Controls->m_Crosshair->setChecked(false); this->GetActiveStdMultiWidget()->GetRenderWindow4()->setCursor(Qt::ArrowCursor); m_CurrentPickingNode = 0; } else { m_Controls->m_Crosshair->setChecked(true); bundleInteractor = mitk::FiberBundleInteractor::New("FiberBundleInteractor", node); mitk::GlobalInteraction::GetInstance()->AddInteractor(bundleInteractor); this->GetActiveStdMultiWidget()->GetRenderWindow4()->setCursor(Qt::CrossCursor); m_CurrentPickingNode = node; } } } } -void QmitkControlVisualizationPropertiesView::TubeRadiusChanged() -{ - if(m_SelectedNode && dynamic_cast(m_SelectedNode->GetData())) - { - float newRadius = m_Controls->m_TubeWidth->value(); - m_SelectedNode->SetFloatProperty("TubeRadius", newRadius); - mitk::RenderingManager::GetInstance()->RequestUpdateAll(); - } -} - void QmitkControlVisualizationPropertiesView::LineWidthChanged() { if(m_SelectedNode && dynamic_cast(m_SelectedNode->GetData())) { int newWidth = m_Controls->m_LineWidth->value(); int currentWidth = 0; m_SelectedNode->GetIntProperty("LineWidth", currentWidth); if (currentWidth==newWidth) return; m_SelectedNode->SetIntProperty("LineWidth", newWidth); dynamic_cast(m_SelectedNode->GetData())->RequestUpdate(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkControlVisualizationPropertiesView::Welcome() { berry::PlatformUI::GetWorkbench()->GetIntroManager()->ShowIntro( GetSite()->GetWorkbenchWindow(), false); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.h b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.h index 1b890d9d1c..9c42cd9d08 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.h +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.h @@ -1,154 +1,153 @@ /*=================================================================== 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 _QMITKControlVisualizationPropertiesView_H_INCLUDED #define _QMITKControlVisualizationPropertiesView_H_INCLUDED #include #include #include "berryISelectionListener.h" #include "berryIStructuredSelection.h" #include "berryISizeProvider.h" #include "ui_QmitkControlVisualizationPropertiesViewControls.h" #include "mitkEnumerationProperty.h" /*! * \ingroup org_mitk_gui_qt_diffusionquantification_internal * * \brief QmitkControlVisualizationPropertiesView * * Document your class here. * * \sa QmitkFunctionality */ class QmitkControlVisualizationPropertiesView : public QmitkFunctionality//, public berry::ISizeProvider { friend struct CvpSelListener; // this is needed for all Qt objects that should have a MOC object (everything that derives from QObject) Q_OBJECT public: static const std::string VIEW_ID; QmitkControlVisualizationPropertiesView(); QmitkControlVisualizationPropertiesView(const QmitkControlVisualizationPropertiesView& other); virtual ~QmitkControlVisualizationPropertiesView(); virtual void CreateQtPartControl(QWidget *parent); /// \brief Creation of the connections of main and control widget virtual void CreateConnections(); /// \brief Called when the functionality is activated virtual void Activated(); virtual void Deactivated(); virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget); virtual void StdMultiWidgetNotAvailable(); protected slots: void VisibleOdfsON_S(); void VisibleOdfsON_T(); void VisibleOdfsON_C(); void ShowMaxNumberChanged(); void NormalizationDropdownChanged(int); void ScalingFactorChanged(double); void AdditionalScaling(int); void ScalingCheckbox(); void OnThickSlicesModeSelected( QAction* action ); void OnTSNumChanged(int num); void BundleRepresentationResetColoring(); void PlanarFigureFocus(); void Fiber2DfadingEFX(); void FiberSlicingThickness2D(); void FiberSlicingUpdateLabel(int); void LineWidthChanged(); - void TubeRadiusChanged(); void SetInteractor(); void Welcome(); protected: virtual void NodeRemoved(const mitk::DataNode* node); /// \brief called by QmitkFunctionality when DataManager's selection has changed virtual void OnSelectionChanged( std::vector nodes ); virtual void NodeAdded(const mitk::DataNode *node); void SetFiberBundleCustomColor(const itk::EventObject& /*e*/); void SetFiberBundleOpacity(const itk::EventObject& /*e*/); bool IsPlaneRotated(); void SliceRotation(const itk::EventObject&); Ui::QmitkControlVisualizationPropertiesViewControls* m_Controls; QmitkStdMultiWidget* m_MultiWidget; berry::ISelectionListener::Pointer m_SelListener; berry::IStructuredSelection::ConstPointer m_CurrentSelection; mitk::DataNode::Pointer m_NodeUsedForOdfVisualization; QIcon* m_IconTexOFF; QIcon* m_IconTexON; QIcon* m_IconGlyOFF_T; QIcon* m_IconGlyON_T; QIcon* m_IconGlyOFF_C; QIcon* m_IconGlyON_C; QIcon* m_IconGlyOFF_S; QIcon* m_IconGlyON_S; bool m_TexIsOn; bool m_GlyIsOn_T; bool m_GlyIsOn_C; bool m_GlyIsOn_S; int currentThickSlicesMode; QLabel* m_TSLabel; QMenu* m_MyMenu; // for planarfigure and bundle handling: mitk::DataNode::Pointer m_SelectedNode; mitk::DataNode* m_CurrentPickingNode; unsigned long m_SlicesRotationObserverTag1; unsigned long m_SlicesRotationObserverTag2; unsigned long m_FiberBundleObserverTag; unsigned long m_FiberBundleObserveOpacityTag; mitk::ColorProperty::Pointer m_Color; mitk::FloatProperty::Pointer m_Opacity; }; #endif // _QMITKControlVisualizationPropertiesView_H_INCLUDED diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesViewControls.ui index 30c0704d5d..a15afb9ea1 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesViewControls.ui +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesViewControls.ui @@ -1,722 +1,702 @@ QmitkControlVisualizationPropertiesViewControls 0 0 567 619 0 100 0 0 QmitkTemplate 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 Multislice Projection MIP QToolButton::MenuButtonPopup Qt::NoArrow QFrame::NoFrame QFrame::Plain 0 0 0 0 Toggle visibility of ODF glyphs (axial) :/QmitkDiffusionImaging/glyphsoff_T.png :/QmitkDiffusionImaging/glyphson_T.png:/QmitkDiffusionImaging/glyphsoff_T.png true false Toggle visibility of ODF glyphs (sagittal) :/QmitkDiffusionImaging/glyphsoff_S.png :/QmitkDiffusionImaging/glyphson_S.png:/QmitkDiffusionImaging/glyphsoff_S.png true false Toggle visibility of ODF glyphs (coronal) :/QmitkDiffusionImaging/glyphsoff_C.png :/QmitkDiffusionImaging/glyphson_C.png:/QmitkDiffusionImaging/glyphsoff_C.png true false #Glyphs 9999 Qt::Horizontal 20 20 QFrame::NoFrame QFrame::Raised 0 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 6 0 QFrame::NoFrame QFrame::Plain 0 0 0 0 false None By GFA By ASR * Additional scaling factor 3 999999999.000000000000000 0.100000000000000 1.000000000000000 Scaling QFrame::NoFrame QFrame::Plain 0 0 0 0 0 ODF normalization false Min-Max Max None QFrame::NoFrame QFrame::Raised 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 Reset to Default Coloring :/QmitkDiffusionImaging/reset.png:/QmitkDiffusionImaging/reset.png Position Crosshair by 3D-Click :/QmitkDiffusionImaging/crosshair.png:/QmitkDiffusionImaging/crosshair.png true false 2D Fiberfading on/off Qt::Horizontal 40 20 QFrame::NoFrame QFrame::Raised 0 0 0 0 2D Clipping 100 10 10 10 Qt::Horizontal 90 0 10000 16777215 Range QFrame::NoFrame QFrame::Raised 0 0 0 0 - - - - Tube Width - - - - - - - Line Width - - - 1 10 - - - - Fiber tube radius in mm. If > 0, fibers are rendered as tubes in 3D. - - - 4 - - - 0.100000000000000 + + + + Line Width 50 false false <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> <p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" color:#ff0000;">One or more slices are rotated. ODF Visualisation is not possible in rotated planes. Use 'Reinit' on the image node to reset. </span></p></body></html> Qt::AutoText true Qt::Vertical 20 40 QmitkDataStorageComboBox.h diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxViewControls.ui index 160817ca4d..82fed1491d 100755 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxViewControls.ui +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxViewControls.ui @@ -1,3108 +1,3117 @@ QmitkFiberfoxViewControls 0 0 479 2397 Form Load Parameters :/QmitkDiffusionImaging/general_icons/upload.ico:/QmitkDiffusionImaging/general_icons/upload.ico 0 Fiber Definition Qt::Vertical 20 40 color: rgb(255, 0, 0); Please select an image or an existing fiber bundle to draw the fiber fiducials. If you can't provide a suitable image, generate one using the "Signal Generation" tab. Qt::AutoText Qt::AlignJustify|Qt::AlignVCenter true Fiducial Options All fiducials are treated as circles with the same radius as the first fiducial. Use Constant Fiducial Radius false false Align selected fiducials with voxel grid. Shifts selected fiducials to nearest voxel center. Align With Grid :/QmitkDiffusionImaging/general_icons/right.ico:/QmitkDiffusionImaging/general_icons/right.ico Operations false Join Bundles :/QmitkDiffusionImaging/general_icons/plus.ico:/QmitkDiffusionImaging/general_icons/plus.ico QFrame::NoFrame QFrame::Raised 0 0 0 0 Y false Rotation angle (in degree) around x-axis. -360.000000000000000 360.000000000000000 0.100000000000000 Axis: false Rotation angle (in degree) around y-axis. -360.000000000000000 360.000000000000000 0.100000000000000 Translation: false Translation (in mm) in direction of the z-axis. -1000.000000000000000 1000.000000000000000 0.100000000000000 Translation (in mm) in direction of the y-axis. -1000.000000000000000 1000.000000000000000 0.100000000000000 X false Rotation: false Z false Rotation angle (in degree) around z-axis. -360.000000000000000 360.000000000000000 0.100000000000000 Translation (in mm) in direction of the x-axis. -1000.000000000000000 1000.000000000000000 0.100000000000000 Scaling: false Scaling factor for selected fiber bundle along the x-axis. 0.010000000000000 10.000000000000000 0.010000000000000 1.000000000000000 Scaling factor for selected fiber bundle along the y-axis. 0.010000000000000 10.000000000000000 0.010000000000000 1.000000000000000 Scaling factor for selected fiber bundle along the z-axis. 0.010000000000000 10.000000000000000 0.010000000000000 1.000000000000000 false Copy Bundles :/QmitkDiffusionImaging/general_icons/copy2.ico:/QmitkDiffusionImaging/general_icons/copy2.ico false Transform Selection :/QmitkDiffusionImaging/general_icons/refresh.ico:/QmitkDiffusionImaging/general_icons/refresh.ico If checked, the fiducials belonging to the modified bundle are also modified. Include Fiducials true Fiber Options QFrame::NoFrame QFrame::Raised 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 Tension: false Fiber Sampling: false 3 -1.000000000000000 1.000000000000000 0.100000000000000 0.000000000000000 3 -1.000000000000000 1.000000000000000 0.100000000000000 0.000000000000000 Bias: false Continuity: false 3 -1.000000000000000 1.000000000000000 0.100000000000000 0.000000000000000 Distance of fiber sampling points (in mm) 1 0.100000000000000 0.100000000000000 1.000000000000000 QFrame::NoFrame QFrame::Raised 0 0 0 0 6 #Fibers: false Specify number of fibers to generate for the selected bundle. 1 1000000 100 100 false Generate Fibers :/QmitkDiffusionImaging/general_icons/right.ico:/QmitkDiffusionImaging/general_icons/right.ico QFrame::NoFrame QFrame::Raised 0 0 0 0 Select fiber distribution inside of the fiducials. Uniform Gaussian Fiber Distribution: false Variance of the gaussian 3 0.001000000000000 10.000000000000000 0.010000000000000 0.100000000000000 QFrame::NoFrame QFrame::Raised 0 0 0 0 Disable to only generate fibers if "Generate Fibers" button is pressed. Real Time Fibers true Disable to only generate fibers if "Generate Fibers" button is pressed. Advanced Options false QFrame::NoFrame QFrame::Raised 0 0 0 0 false 30 30 Draw elliptical fiducial. :/QmitkDiffusionImaging/circle.png:/QmitkDiffusionImaging/circle.png 32 32 false true false 30 30 Flip fiber waypoints of selcted fiducial around one axis. :/QmitkDiffusionImaging/refresh.xpm:/QmitkDiffusionImaging/refresh.xpm 32 32 false true Qt::Horizontal 40 20 Signal Generation Extra-axonal Compartments QFrame::NoFrame QFrame::Raised 0 0 0 0 Volume Fraction: Select signal model for extra-axonal compartment. Ball Model Astrosticks Model Dot Model Prototype Signal Qt::Horizontal Select signal model for extra-axonal compartment. -- Ball Model Astrosticks Model Dot Model Prototype Signal Qt::Vertical 20 40 Image Settings Advanced Options QFrame::NoFrame QFrame::Raised 0 0 0 0 6 Gradient Directions: Number of gradient directions distributed over the half sphere. 0 10000 1 30 <html><head/><body><p>b-Value<span style=" font-style:italic;"> [s/mm</span><span style=" font-style:italic; vertical-align:super;">2</span><span style=" font-style:italic;">]</span>:</p></body></html> false b-value in s/mm² 0 10000 100 1000 color: rgb(255, 0, 0); Using geometry of selected image! color: rgb(255, 0, 0); Using gradients of selected DWI! QFrame::NoFrame QFrame::Raised 0 0 0 0 6 TE in milliseconds 1 10000 1 100 <html><head/><body><p>Echo Time <span style=" font-style:italic;">TE</span>: </p></body></html> false T2* relaxation time (in milliseconds). 100.000000000000000 0.100000000000000 1.000000000000000 Output one image per compartment containing the corresponding volume fractions per voxel. Output Volume Fractions false Fiber tangent Main fiber directions Random <html><head/><body><p><span style=" font-style:italic;">TE</span>, <span style=" font-style:italic;">T</span><span style=" font-style:italic; vertical-align:sub;">inhom</span> and <span style=" font-style:italic;">T2</span> will have no effect if unchecked.</p></body></html> Simulate Signal Relaxation true Fiber Radius: Line Readout Time: false <html><head/><body><p><span style=" font-style:italic;">T</span><span style=" font-style:italic; vertical-align:sub;">inhom</span> Relaxation: </p></body></html> false Diffusion Direction: Relaxation time due to magnetic field inhomogeneities (T2', in milliseconds). 1 10000 1 50 TE in milliseconds 1 10000 1 100 Signal Scale: Fiber radius used to calculate volume fractions (in µm). Set to 0 for automatic radius estimation. 0 1000 0 Separation Angle: Disable partial volume. Treat voxel content as fiber-only if at least one fiber is present. Disable Partial Volume Effects false 1 90.000000000000000 45.000000000000000 QFrame::NoFrame QFrame::Raised 0 0 0 0 3 0.100000000000000 50.000000000000000 0.100000000000000 2.000000000000000 Image Spacing: 3 0.100000000000000 50.000000000000000 0.100000000000000 2.000000000000000 3 0.100000000000000 50.000000000000000 0.100000000000000 2.000000000000000 Image Dimensions: Fiber sampling factor which determines the accuracy of the calculated fiber and non-fiber volume fractions. 1 1000 1 11 Fiber sampling factor which determines the accuracy of the calculated fiber and non-fiber volume fractions. 1 1000 1 11 Fiber sampling factor which determines the accuracy of the calculated fiber and non-fiber volume fractions. 1 1000 1 3 Inter-axonal Compartment Select signal model for intra-axonal compartment. -- Stick Model Zeppelin Model Tensor Model true Stop current simulation. Abort Simulation :/QmitkDiffusionImaging/general_icons/abort.ico:/QmitkDiffusionImaging/general_icons/abort.ico Data QFrame::NoFrame QFrame::Raised 0 0 0 0 0 - ... <html><head/><body><p>Select a binary image to define the area of signal generation. Outside of the mask image only noise will be actively generated.</p></body></html> + + QComboBox::AdjustToMinimumContentsLength + Fiber Bundle: false Save path: false Tissue Mask: false <html><head/><body><p>Select a fiber bundle to generate the white matter signal from. You can either use the fiber definition tab to manually define an input fiber bundle or you can also use any existing bundle, e.g. yielded by a tractography algorithm.</p></body></html> + + QComboBox::AdjustToMinimumContentsLength + Template Image: false <html><head/><body><p>The parameters for the simulation (e.g. spacing, size, diffuison-weighted gradients, b-value) are adopted from this image.</p></body></html> + + QComboBox::AdjustToMinimumContentsLength + 8 true Noise and other Artifacts Qt::Horizontal Add Noise false Add ringing artifacts occuring at strong edges in the image. Add Gibbs Ringing false true QFrame::NoFrame QFrame::Raised 6 0 0 0 0 Shrink FOV (%): false Shrink FOV by this percentage. 1 0.000000000000000 90.000000000000000 0.100000000000000 25.000000000000000 Qt::Horizontal QFrame::NoFrame QFrame::Raised 0 0 0 0 Num. Spikes: The number of randomly occurring signal spikes. 1 Spike amplitude relative to the largest signal amplitude of the corresponding k-space slice. 0.100000000000000 0.100000000000000 Scale: !!!EXPERIMENTAL!!! Add Eddy Current Effects false Add Spikes false QFrame::NoFrame QFrame::Raised 0 0 0 0 Variance: Variance of selected noise distribution. 4 0.000000000000000 999999999.000000000000000 0.001000000000000 50.000000000000000 Distribution: Noise distribution Rician Chi-squared Add N/2 Ghosts false true QFrame::NoFrame QFrame::Raised 6 0 0 0 0 Frequency Map: false Select image specifying the frequency inhomogeneities (in Hz). Qt::Horizontal Qt::Horizontal Qt::Horizontal true QFrame::NoFrame QFrame::Raised QFormLayout::AllNonFixedFieldsGrow 6 0 6 0 0 Toggle between random movement and linear movement. Randomize motion true Rotation 0 9 0 0 Degree: false x false Axis: false Maximum rotation around x-axis. 1 360.000000000000000 1.000000000000000 0.000000000000000 Maximum rotation around z-axis. 1 360.000000000000000 1.000000000000000 15.000000000000000 y false z false Maximum rotation around y-axis. 1 360.000000000000000 1.000000000000000 0.000000000000000 Translation 0 0 0 Distance: false x false y false Axis: false z false Maximum translation along x-axis. 1 1000.000000000000000 1.000000000000000 0.000000000000000 Maximum translation along y-axis. 1 1000.000000000000000 1.000000000000000 0.000000000000000 Maximum translation along z-axis. 1 1000.000000000000000 1.000000000000000 0.000000000000000 Add Motion Artifacts false Add Distortions false Add Aliasing false true QFrame::NoFrame QFrame::Raised 6 0 0 0 0 K-Space Line Offset: false A larger offset increases the inensity of the ghost image. 3 1.000000000000000 0.010000000000000 0.250000000000000 true QFrame::NoFrame QFrame::Raised QFormLayout::AllNonFixedFieldsGrow 6 0 0 0 0 Magnitude: false Maximum magnitude of eddy current induced magnetic field inhomogeneities (in mT). 5 1000.000000000000000 0.001000000000000 0.005000000000000 color: rgb(255, 0, 0); Experimental! Qt::Horizontal Qt::Horizontal true <html><head/><body><p>Start DWI generation from selected fiber bundle.</p><p>If no fiber bundle but an existing diffusion weighted image is selected, the enabled artifacts are added to this image.</p><p>If neither a fiber bundle nor a diffusion weighted image is selected, a grayscale image containing a simple gradient is generated.</p></body></html> Start Simulation :/QmitkDiffusionImaging/general_icons/right.ico:/QmitkDiffusionImaging/general_icons/right.ico Intra-axonal Compartment Select signal model for intra-axonal compartment. Stick Model Zeppelin Model Tensor Model Prototype Signal Save Parameters :/QmitkDiffusionImaging/general_icons/download.ico:/QmitkDiffusionImaging/general_icons/download.ico QmitkDataStorageComboBox QComboBox
QmitkDataStorageComboBox.h
QmitkTensorModelParametersWidget QWidget
QmitkTensorModelParametersWidget.h
1
QmitkStickModelParametersWidget QWidget
QmitkStickModelParametersWidget.h
1
QmitkZeppelinModelParametersWidget QWidget
QmitkZeppelinModelParametersWidget.h
1
QmitkBallModelParametersWidget QWidget
QmitkBallModelParametersWidget.h
1
QmitkAstrosticksModelParametersWidget QWidget
QmitkAstrosticksModelParametersWidget.h
1
QmitkDotModelParametersWidget QWidget
QmitkDotModelParametersWidget.h
1
QmitkPrototypeSignalParametersWidget QWidget
QmitkPrototypeSignalParametersWidget.h
1
QmitkDataStorageComboBoxWithSelectNone QComboBox
QmitkDataStorageComboBoxWithSelectNone.h
m_CircleButton m_FlipButton m_RealTimeFibers m_AdvancedOptionsBox m_DistributionBox m_VarianceBox m_FiberDensityBox m_FiberSamplingBox m_TensionBox m_ContinuityBox m_BiasBox m_GenerateFibersButton m_ConstantRadiusBox m_AlignOnGrid m_XrotBox m_YrotBox m_ZrotBox m_XtransBox m_YtransBox m_ZtransBox m_XscaleBox m_YscaleBox m_ZscaleBox m_TransformBundlesButton m_CopyBundlesButton m_JoinBundlesButton m_IncludeFiducials m_GenerateImageButton m_SizeX m_SizeY m_SizeZ m_SpacingX m_SpacingY m_SpacingZ m_NumGradientsBox m_BvalueBox m_AdvancedOptionsBox_2 m_SignalScaleBox m_TEbox m_LineReadoutTimeBox m_T2starBox m_FiberRadius m_RelaxationBox m_EnforcePureFiberVoxelsBox m_VolumeFractionsBox m_Compartment1Box m_Compartment2Box m_Compartment3Box m_Compartment4Box m_AddNoise m_NoiseLevel m_AddSpikes m_SpikeNumBox m_SpikeScaleBox m_AddGhosts m_kOffsetBox m_AddAliasing m_WrapBox m_AddDistortions m_FrequencyMapBox m_AddMotion m_RandomMotion m_MaxRotationBoxX m_MaxRotationBoxY m_MaxRotationBoxZ m_MaxTranslationBoxX m_MaxTranslationBoxY m_MaxTranslationBoxZ m_AddEddy m_EddyGradientStrength m_AddGibbsRinging m_SaveParametersButton m_LoadParametersButton tabWidget
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingViewControls.ui index 782479312c..a08598a6ac 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingViewControls.ui +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingViewControls.ui @@ -1,431 +1,434 @@ QmitkStreamlineTrackingViewControls 0 0 382 538 0 0 QmitkTemplate 3 3 0 Qt::Vertical QSizePolicy::Expanding 20 220 false Start Tractography Parameters Weighting factor between input vector (g=0) and tensor deflection (g=1 equals TEND tracking) 0 100 0 Qt::Horizontal Stepsize in mm (auto = 0.1*minimal spacing) 0 100 0 Qt::Horizontal Minimally allowed curcature radius (in mm, interpolated auto = 0.5 minimal spacing, noninterpolated auto = 0.5 * minimal spacing) -1 50 -1 Qt::Horizontal Min. Tract Length: 20mm FA Threshold: 0.2 g: 0 Qt::Horizontal QSizePolicy::Fixed 200 0 Seeds per Voxel: 1 Number of tracts started in each voxel of the seed ROI. 1 100 Qt::Horizontal Step Size: auto Weighting factor between first eigenvector (f=1 equals FACT tracking) and input vector dependent direction (f=0). 0 100 100 Qt::Horizontal Minimum tract length in mm. 0 500 20 Qt::Horizontal Default is nearest neighbor interpolation. Enable Trilinear Interpolation true f: 1 Min. Curvature Radius: auto Resample fibers using the specified error constraint. Compress Fibers false Qt::StrongFocus Maximum error in mm. 3 10.000000000000000 0.010000000000000 0.100000000000000 5 1.000000000000000 0.100000000000000 0.200000000000000 Please Select Input Data <html><head/><body><p><span style=" color:#969696;">optional</span></p></body></html> true + + QComboBox::AdjustToMinimumContentsLength + - <html><head/><body><p><span style=" color:#969696;">optional</span></p></body></html> true Only track insida mask area. Mask Image: Binary seed ROI. If not specified, the whole image area is seeded. Seed ROI: <html><head/><body><p><span style=" color:#ff0000;">mandatory</span></p></body></html> true Input DTI Tensor Image: Check to use selected FA image instead of internally calculated one. Recommended for multi-tensor tractography. FA image false QmitkDataStorageComboBox QComboBox
QmitkDataStorageComboBox.h