diff --git a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractDensityImageFilter.cpp b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractDensityImageFilter.cpp index 13df693a5d..7b6aaf59f0 100644 --- a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractDensityImageFilter.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractDensityImageFilter.cpp @@ -1,248 +1,211 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Coindex[1]right (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 "itkTractDensityImageFilter.h" // VTK #include #include #include #include // misc #include #include namespace itk{ template< class OutputImageType > TractDensityImageFilter< OutputImageType >::TractDensityImageFilter() : m_InvertImage(false) , m_FiberBundle(NULL) , m_UpsamplingFactor(1) , m_InputImage(NULL) , m_BinaryOutput(false) , m_UseImageGeometry(false) , m_OutputAbsoluteValues(false) , m_UseTrilinearInterpolation(false) , m_DoFiberResampling(true) { } template< class OutputImageType > TractDensityImageFilter< OutputImageType >::~TractDensityImageFilter() { } template< class OutputImageType > itk::Point TractDensityImageFilter< OutputImageType >::GetItkPoint(double point[3]) { itk::Point itkPoint; itkPoint[0] = point[0]; itkPoint[1] = point[1]; itkPoint[2] = point[2]; return itkPoint; } template< class OutputImageType > void TractDensityImageFilter< OutputImageType >::GenerateData() { // generate upsampled image - mitk::BaseGeometry::Pointer geometry = m_FiberBundle->GetGeometry(); typename OutputImageType::Pointer outImage = this->GetOutput(); + if (fibs.empty() && m_FiberBundle.IsNotNull()) + fibs.push_back(m_FiberBundle); // calculate new image parameters itk::Vector newSpacing; mitk::Point3D newOrigin; itk::Matrix newDirection; ImageRegion<3> upsampledRegion; if (m_UseImageGeometry && !m_InputImage.IsNull()) { MITK_INFO << "TractDensityImageFilter: using image geometry"; newSpacing = m_InputImage->GetSpacing()/m_UpsamplingFactor; upsampledRegion = m_InputImage->GetLargestPossibleRegion(); newOrigin = m_InputImage->GetOrigin(); typename OutputImageType::RegionType::SizeType size = upsampledRegion.GetSize(); size[0] *= m_UpsamplingFactor; size[1] *= m_UpsamplingFactor; size[2] *= m_UpsamplingFactor; upsampledRegion.SetSize(size); newDirection = m_InputImage->GetDirection(); } else { MITK_INFO << "TractDensityImageFilter: using fiber bundle geometry"; + mitk::BaseGeometry::Pointer geometry = m_FiberBundle->GetGeometry(); newSpacing = geometry->GetSpacing()/m_UpsamplingFactor; newOrigin = geometry->GetOrigin(); mitk::Geometry3D::BoundsArrayType bounds = geometry->GetBounds(); newOrigin[0] += bounds.GetElement(0); newOrigin[1] += bounds.GetElement(2); newOrigin[2] += bounds.GetElement(4); for (int i=0; i<3; i++) for (int j=0; j<3; j++) newDirection[j][i] = geometry->GetMatrixColumn(i)[j]; upsampledRegion.SetSize(0, geometry->GetExtent(0)*m_UpsamplingFactor); upsampledRegion.SetSize(1, geometry->GetExtent(1)*m_UpsamplingFactor); upsampledRegion.SetSize(2, geometry->GetExtent(2)*m_UpsamplingFactor); } typename OutputImageType::RegionType::SizeType upsampledSize = upsampledRegion.GetSize(); // apply new image parameters outImage->SetSpacing( newSpacing ); outImage->SetOrigin( newOrigin ); outImage->SetDirection( newDirection ); outImage->SetLargestPossibleRegion( upsampledRegion ); outImage->SetBufferedRegion( upsampledRegion ); outImage->SetRequestedRegion( upsampledRegion ); outImage->Allocate(); outImage->FillBuffer(0.0); int w = upsampledSize[0]; int h = upsampledSize[1]; int d = upsampledSize[2]; // set/initialize output OutPixelType* outImageBufferPointer = (OutPixelType*)outImage->GetBufferPointer(); // resample fiber bundle float minSpacing = 1; if(newSpacing[0]GetDeepCopy(); - m_FiberBundle->ResampleSpline(minSpacing/10); - } + typename OutputImageType::Pointer workingImage = OutputImageType::New(); + workingImage->SetSpacing( newSpacing ); + workingImage->SetOrigin( newOrigin ); + workingImage->SetDirection( newDirection ); + workingImage->SetLargestPossibleRegion( upsampledRegion ); + workingImage->SetBufferedRegion( upsampledRegion ); + workingImage->SetRequestedRegion( upsampledRegion ); + workingImage->Allocate(); + workingImage->FillBuffer(0.0); + + m_FiberBundle = fibs.at(f); + MITK_INFO << "TractDensityImageFilter: resampling fibers to ensure sufficient voxel coverage"; + if (m_DoFiberResampling) + { + m_FiberBundle = m_FiberBundle->GetDeepCopy(); + m_FiberBundle->ResampleSpline(minSpacing/10); + } - MITK_INFO << "TractDensityImageFilter: starting image generation"; + MITK_INFO << "TractDensityImageFilter: starting image generation"; - vtkSmartPointer fiberPolyData = m_FiberBundle->GetFiberPolyData(); - vtkSmartPointer vLines = fiberPolyData->GetLines(); - vLines->InitTraversal(); - int numFibers = m_FiberBundle->GetNumFibers(); - boost::progress_display disp(numFibers); - for( int i=0; iGetNextCell ( numPoints, points ); - float weight = m_FiberBundle->GetFiberWeight(i); - - // fill output image - for( int j=0; j fiberPolyData = m_FiberBundle->GetFiberPolyData(); + vtkSmartPointer vLines = fiberPolyData->GetLines(); + vLines->InitTraversal(); + int numFibers = m_FiberBundle->GetNumFibers(); + boost::progress_display disp(numFibers); + for( int i=0; i vertex = GetItkPoint(fiberPolyData->GetPoint(points[j])); - itk::Index<3> index; - itk::ContinuousIndex contIndex; - outImage->TransformPhysicalPointToIndex(vertex, index); - outImage->TransformPhysicalPointToContinuousIndex(vertex, contIndex); - - if (!m_UseTrilinearInterpolation && outImage->GetLargestPossibleRegion().IsInside(index)) + ++disp; + vtkIdType numPoints(0); + vtkIdType* points(NULL); + vLines->GetNextCell ( numPoints, points ); + float weight = m_FiberBundle->GetFiberWeight(i); + + // fill output image + for( int j=0; j vertex = GetItkPoint(fiberPolyData->GetPoint(points[j])); + itk::Index<3> index; + itk::ContinuousIndex contIndex; + workingImage->TransformPhysicalPointToIndex(vertex, index); + workingImage->TransformPhysicalPointToContinuousIndex(vertex, contIndex); + if (m_BinaryOutput) - outImage->SetPixel(index, 1); + workingImage->SetPixel(index, 1); else - outImage->SetPixel(index, outImage->GetPixel(index)+0.01*weight); - continue; - } - - float frac_x = contIndex[0] - index[0]; - float frac_y = contIndex[1] - index[1]; - float frac_z = contIndex[2] - index[2]; - - if (frac_x<0) - { - index[0] -= 1; - frac_x += 1; - } - if (frac_y<0) - { - index[1] -= 1; - frac_y += 1; - } - if (frac_z<0) - { - index[2] -= 1; - frac_z += 1; + workingImage->SetPixel(index, workingImage->GetPixel(index)+0.01*weight); } + } - frac_x = 1-frac_x; - frac_y = 1-frac_y; - frac_z = 1-frac_z; - - // int coordinates inside image? - if (index[0] < 0 || index[0] >= w-1) - continue; - if (index[1] < 0 || index[1] >= h-1) - continue; - if (index[2] < 0 || index[2] >= d-1) - continue; + OutPixelType* wipImageBufferPointer = (OutPixelType*)workingImage->GetBufferPointer(); + for (int i=0; i outImageBufferPointer[i]) + outImageBufferPointer[i] = wipImageBufferPointer[i]; - if (m_BinaryOutput) - { - outImageBufferPointer[( index[0] + w*(index[1] + h*index[2] ))] = 1; - outImageBufferPointer[( index[0] + w*(index[1]+1+ h*index[2] ))] = 1; - outImageBufferPointer[( index[0] + w*(index[1] + h*index[2]+h))] = 1; - outImageBufferPointer[( index[0] + w*(index[1]+1+ h*index[2]+h))] = 1; - outImageBufferPointer[( index[0]+1 + w*(index[1] + h*index[2] ))] = 1; - outImageBufferPointer[( index[0]+1 + w*(index[1] + h*index[2]+h))] = 1; - outImageBufferPointer[( index[0]+1 + w*(index[1]+1+ h*index[2] ))] = 1; - outImageBufferPointer[( index[0]+1 + w*(index[1]+1+ h*index[2]+h))] = 1; - } - else - { - outImageBufferPointer[( index[0] + w*(index[1] + h*index[2] ))] += ( frac_x)*( frac_y)*( frac_z); - outImageBufferPointer[( index[0] + w*(index[1]+1+ h*index[2] ))] += ( frac_x)*(1-frac_y)*( frac_z); - outImageBufferPointer[( index[0] + w*(index[1] + h*index[2]+h))] += ( frac_x)*( frac_y)*(1-frac_z); - outImageBufferPointer[( index[0] + w*(index[1]+1+ h*index[2]+h))] += ( frac_x)*(1-frac_y)*(1-frac_z); - outImageBufferPointer[( index[0]+1 + w*(index[1] + h*index[2] ))] += (1-frac_x)*( frac_y)*( frac_z); - outImageBufferPointer[( index[0]+1 + w*(index[1] + h*index[2]+h))] += (1-frac_x)*( frac_y)*(1-frac_z); - outImageBufferPointer[( index[0]+1 + w*(index[1]+1+ h*index[2] ))] += (1-frac_x)*(1-frac_y)*( frac_z); - outImageBufferPointer[( index[0]+1 + w*(index[1]+1+ h*index[2]+h))] += (1-frac_x)*(1-frac_y)*(1-frac_z); - } - } } if (!m_OutputAbsoluteValues && !m_BinaryOutput) { MITK_INFO << "TractDensityImageFilter: max-normalizing output image"; OutPixelType max = 0; for (int i=0; i0) for (int i=0; i #include #include #include #include namespace itk{ /** * \brief Generates tract density images from input fiberbundles (Calamante 2010). */ template< class OutputImageType > class TractDensityImageFilter : public ImageSource< OutputImageType > { public: typedef TractDensityImageFilter Self; typedef ProcessObject Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; typedef typename OutputImageType::PixelType OutPixelType; itkFactorylessNewMacro(Self) itkCloneMacro(Self) itkTypeMacro( TractDensityImageFilter, ImageSource ) itkSetMacro( UpsamplingFactor, float) ///< use higher resolution for ouput image itkGetMacro( UpsamplingFactor, float) ///< use higher resolution for ouput image itkSetMacro( InvertImage, bool) ///< voxelvalue = 1-voxelvalue itkGetMacro( InvertImage, bool) ///< voxelvalue = 1-voxelvalue itkSetMacro( BinaryOutput, bool) ///< generate binary fiber envelope itkGetMacro( BinaryOutput, bool) ///< generate binary fiber envelope itkSetMacro( OutputAbsoluteValues, bool) ///< output absolute values of the number of fibers per voxel itkGetMacro( OutputAbsoluteValues, bool) ///< output absolute values of the number of fibers per voxel itkSetMacro( UseImageGeometry, bool) ///< use input image geometry to initialize output image itkGetMacro( UseImageGeometry, bool) ///< use input image geometry to initialize output image itkSetMacro( FiberBundle, mitk::FiberBundleX::Pointer) ///< input fiber bundle itkSetMacro( InputImage, typename OutputImageType::Pointer) ///< use input image geometry to initialize output image itkSetMacro( UseTrilinearInterpolation, bool ) itkSetMacro( DoFiberResampling, bool ) void GenerateData(); + std::vector< mitk::FiberBundleX::Pointer > fibs; + protected: itk::Point GetItkPoint(double point[3]); TractDensityImageFilter(); virtual ~TractDensityImageFilter(); typename OutputImageType::Pointer m_InputImage; ///< use input image geometry to initialize output image mitk::FiberBundleX::Pointer m_FiberBundle; ///< input fiber bundle float m_UpsamplingFactor; ///< use higher resolution for ouput image bool m_InvertImage; ///< voxelvalue = 1-voxelvalue bool m_BinaryOutput; ///< generate binary fiber envelope bool m_UseImageGeometry; ///< use input image geometry to initialize output image bool m_OutputAbsoluteValues; ///< do not normalize image values to 0-1 bool m_UseTrilinearInterpolation; bool m_DoFiberResampling; }; } #ifndef ITK_MANUAL_INSTANTIATION #include "itkTractDensityImageFilter.cpp" #endif #endif // __itkTractDensityImageFilter_h__ diff --git a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.cpp b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.cpp index 4a0071773b..c29d1cb8be 100755 --- a/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.cpp +++ b/Modules/DiffusionImaging/FiberTracking/Algorithms/itkTractsToDWIImageFilter.cpp @@ -1,1437 +1,1438 @@ /*=================================================================== 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()) { + MITK_INFO << "ERROR"; 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::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.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); } } // 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(); } // 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.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.cpp b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.cpp index 60d3d933e7..b70b8c4a51 100644 --- a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.cpp +++ b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.cpp @@ -1,1355 +1,1388 @@ /*=================================================================== 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 "QmitkBasicImageProcessingView.h" // QT includes (GUI) #include #include #include #include #include #include #include // Berry includes (selection service) #include #include // MITK includes (GUI) #include "QmitkStdMultiWidget.h" #include "QmitkDataNodeSelectionProvider.h" #include "mitkDataNodeObject.h" // MITK includes (general) #include "mitkNodePredicateDataType.h" #include "mitkNodePredicateDimension.h" #include "mitkNodePredicateAnd.h" #include "mitkImageTimeSelector.h" #include "mitkVectorImageMapper2D.h" #include "mitkProperties.h" // Includes for image casting between ITK and MITK #include "mitkImageCast.h" #include "mitkITKImageImport.h" // ITK includes (general) #include #include // Morphological Operations #include #include #include #include #include // Smoothing #include #include #include // Threshold #include // Inversion #include // Derivatives #include #include #include // Resampling #include #include #include #include // Image Arithmetics #include #include #include #include // Boolean operations #include #include #include // Flip Image #include #include +#include // Convenient Definitions typedef itk::Image ImageType; typedef itk::Image SegmentationImageType; -typedef itk::Image FloatImageType; +typedef itk::Image DoubleImageType; typedef itk::Image, 3> VectorImageType; typedef itk::BinaryBallStructuringElement BallType; typedef itk::GrayscaleDilateImageFilter DilationFilterType; typedef itk::GrayscaleErodeImageFilter ErosionFilterType; typedef itk::GrayscaleMorphologicalOpeningImageFilter OpeningFilterType; typedef itk::GrayscaleMorphologicalClosingImageFilter ClosingFilterType; typedef itk::MedianImageFilter< ImageType, ImageType > MedianFilterType; typedef itk::DiscreteGaussianImageFilter< ImageType, ImageType> GaussianFilterType; -typedef itk::TotalVariationDenoisingImageFilter TotalVariationFilterType; +typedef itk::TotalVariationDenoisingImageFilter TotalVariationFilterType; typedef itk::TotalVariationDenoisingImageFilter VectorTotalVariationFilterType; typedef itk::BinaryThresholdImageFilter< ImageType, ImageType > ThresholdFilterType; typedef itk::InvertIntensityImageFilter< ImageType, ImageType > InversionFilterType; typedef itk::GradientMagnitudeRecursiveGaussianImageFilter< ImageType, ImageType > GradientFilterType; -typedef itk::LaplacianImageFilter< FloatImageType, FloatImageType > LaplacianFilterType; -typedef itk::SobelEdgeDetectionImageFilter< FloatImageType, FloatImageType > SobelFilterType; +typedef itk::LaplacianImageFilter< DoubleImageType, DoubleImageType > LaplacianFilterType; +typedef itk::SobelEdgeDetectionImageFilter< DoubleImageType, DoubleImageType > SobelFilterType; typedef itk::ResampleImageFilter< ImageType, ImageType > ResampleImageFilterType; typedef itk::ResampleImageFilter< ImageType, ImageType > ResampleImageFilterType2; -typedef itk::CastImageFilter< ImageType, FloatImageType > ImagePTypeToFloatPTypeCasterType; +typedef itk::CastImageFilter< ImageType, DoubleImageType > ImagePTypeToFloatPTypeCasterType; typedef itk::AddImageFilter< ImageType, ImageType, ImageType > AddFilterType; typedef itk::SubtractImageFilter< ImageType, ImageType, ImageType > SubtractFilterType; typedef itk::MultiplyImageFilter< ImageType, ImageType, ImageType > MultiplyFilterType; -typedef itk::DivideImageFilter< ImageType, ImageType, FloatImageType > DivideFilterType; +typedef itk::DivideImageFilter< ImageType, ImageType, DoubleImageType > DivideFilterType; typedef itk::OrImageFilter< ImageType, ImageType > OrImageFilterType; typedef itk::AndImageFilter< ImageType, ImageType > AndImageFilterType; typedef itk::XorImageFilter< ImageType, ImageType > XorImageFilterType; typedef itk::FlipImageFilter< ImageType > FlipImageFilterType; typedef itk::LinearInterpolateImageFunction< ImageType, double > LinearInterpolatorType; typedef itk::NearestNeighborInterpolateImageFunction< ImageType, double > NearestInterpolatorType; QmitkBasicImageProcessing::QmitkBasicImageProcessing() : QmitkFunctionality(), m_Controls(NULL), m_SelectedImageNode(NULL), m_TimeStepperAdapter(NULL), m_SelectionListener(NULL) { } QmitkBasicImageProcessing::~QmitkBasicImageProcessing() { //berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService(); //if(s) // s->RemoveSelectionListener(m_SelectionListener); } void QmitkBasicImageProcessing::CreateQtPartControl(QWidget *parent) { if (m_Controls == NULL) { m_Controls = new Ui::QmitkBasicImageProcessingViewControls; m_Controls->setupUi(parent); this->CreateConnections(); //setup predictaes for combobox mitk::NodePredicateDimension::Pointer dimensionPredicate = mitk::NodePredicateDimension::New(3); mitk::NodePredicateDataType::Pointer imagePredicate = mitk::NodePredicateDataType::New("Image"); m_Controls->m_ImageSelector2->SetDataStorage(this->GetDefaultDataStorage()); m_Controls->m_ImageSelector2->SetPredicate(mitk::NodePredicateAnd::New(dimensionPredicate, imagePredicate)); } m_Controls->gbTwoImageOps->hide(); m_SelectedImageNode = mitk::DataStorageSelection::New(this->GetDefaultDataStorage(), false); } void QmitkBasicImageProcessing::CreateConnections() { if ( m_Controls ) { connect( (QObject*)(m_Controls->cbWhat1), SIGNAL( activated(int) ), this, SLOT( SelectAction(int) ) ); connect( (QObject*)(m_Controls->btnDoIt), SIGNAL(clicked()),(QObject*) this, SLOT(StartButtonClicked())); - connect( (QObject*)(m_Controls->cbWhat2), SIGNAL( activated(int) ), this, SLOT( SelectAction2(int) ) ); connect( (QObject*)(m_Controls->btnDoIt2), SIGNAL(clicked()),(QObject*) this, SLOT(StartButton2Clicked())); - connect( (QObject*)(m_Controls->rBOneImOp), SIGNAL( clicked() ), this, SLOT( ChangeGUI() ) ); connect( (QObject*)(m_Controls->rBTwoImOp), SIGNAL( clicked() ), this, SLOT( ChangeGUI() ) ); - connect( (QObject*)(m_Controls->cbParam4), SIGNAL( activated(int) ), this, SLOT( SelectInterpolator(int) ) ); } m_TimeStepperAdapter = new QmitkStepperAdapter((QObject*) m_Controls->sliceNavigatorTime, GetActiveStdMultiWidget()->GetTimeNavigationController()->GetTime(), "sliceNavigatorTimeFromBIP"); } void QmitkBasicImageProcessing::Activated() { QmitkFunctionality::Activated(); this->m_Controls->cbWhat1->clear(); this->m_Controls->cbWhat1->insertItem( NOACTIONSELECTED, "Please select operation"); this->m_Controls->cbWhat1->insertItem( CATEGORY_DENOISING, "--- Denoising ---"); this->m_Controls->cbWhat1->insertItem( GAUSSIAN, "Gaussian"); this->m_Controls->cbWhat1->insertItem( MEDIAN, "Median"); this->m_Controls->cbWhat1->insertItem( TOTALVARIATION, "Total Variation"); this->m_Controls->cbWhat1->insertItem( CATEGORY_MORPHOLOGICAL, "--- Morphological ---"); this->m_Controls->cbWhat1->insertItem( DILATION, "Dilation"); this->m_Controls->cbWhat1->insertItem( EROSION, "Erosion"); this->m_Controls->cbWhat1->insertItem( OPENING, "Opening"); this->m_Controls->cbWhat1->insertItem( CLOSING, "Closing"); this->m_Controls->cbWhat1->insertItem( CATEGORY_EDGE_DETECTION, "--- Edge Detection ---"); this->m_Controls->cbWhat1->insertItem( GRADIENT, "Gradient"); this->m_Controls->cbWhat1->insertItem( LAPLACIAN, "Laplacian (2nd Derivative)"); this->m_Controls->cbWhat1->insertItem( SOBEL, "Sobel Operator"); this->m_Controls->cbWhat1->insertItem( CATEGORY_MISC, "--- Misc ---"); this->m_Controls->cbWhat1->insertItem( THRESHOLD, "Threshold"); this->m_Controls->cbWhat1->insertItem( INVERSION, "Image Inversion"); this->m_Controls->cbWhat1->insertItem( DOWNSAMPLING, "Downsampling"); this->m_Controls->cbWhat1->insertItem( FLIPPING, "Flipping"); this->m_Controls->cbWhat1->insertItem( RESAMPLING, "Resample to"); - this->m_Controls->cbWhat1->insertItem( RESCALE, "Rescale image values"); + this->m_Controls->cbWhat1->insertItem( RESCALE, "Rescale values to interval"); + this->m_Controls->cbWhat1->insertItem( RESCALE2, "Rescale values by scalar"); this->m_Controls->cbWhat2->clear(); this->m_Controls->cbWhat2->insertItem( TWOIMAGESNOACTIONSELECTED, "Please select on operation" ); this->m_Controls->cbWhat2->insertItem( CATEGORY_ARITHMETIC, "--- Arithmetric operations ---" ); this->m_Controls->cbWhat2->insertItem( ADD, "Add to Image 1:" ); this->m_Controls->cbWhat2->insertItem( SUBTRACT, "Subtract from Image 1:" ); this->m_Controls->cbWhat2->insertItem( MULTIPLY, "Multiply with Image 1:" ); this->m_Controls->cbWhat2->insertItem( RESAMPLE_TO, "Resample Image 1 to fit geometry:" ); this->m_Controls->cbWhat2->insertItem( DIVIDE, "Divide Image 1 by:" ); this->m_Controls->cbWhat2->insertItem( CATEGORY_BOOLEAN, "--- Boolean operations ---" ); this->m_Controls->cbWhat2->insertItem( AND, "AND" ); this->m_Controls->cbWhat2->insertItem( OR, "OR" ); this->m_Controls->cbWhat2->insertItem( XOR, "XOR" ); this->m_Controls->cbParam4->clear(); this->m_Controls->cbParam4->insertItem( LINEAR, "Linear" ); this->m_Controls->cbParam4->insertItem( NEAREST, "Nearest neighbor" ); m_Controls->dsbParam1->hide(); m_Controls->dsbParam2->hide(); m_Controls->dsbParam3->hide(); m_Controls->tlParam3->hide(); m_Controls->tlParam4->hide(); m_Controls->cbParam4->hide(); } //datamanager selection changed void QmitkBasicImageProcessing::OnSelectionChanged(std::vector nodes) { //any nodes there? if (!nodes.empty()) { // reset GUI // this->ResetOneImageOpPanel(); m_Controls->sliceNavigatorTime->setEnabled(false); m_Controls->leImage1->setText("Select an Image in Data Manager"); m_Controls->tlWhat1->setEnabled(false); m_Controls->cbWhat1->setEnabled(false); m_Controls->tlWhat2->setEnabled(false); m_Controls->cbWhat2->setEnabled(false); m_SelectedImageNode->RemoveAllNodes(); //get the selected Node mitk::DataNode* _DataNode = nodes.front(); *m_SelectedImageNode = _DataNode; //try to cast to image mitk::Image::Pointer tempImage = dynamic_cast(m_SelectedImageNode->GetNode()->GetData()); //no image if( tempImage.IsNull() || (tempImage->IsInitialized() == false) ) { m_Controls->leImage1->setText("Not an image."); return; } //2D image if( tempImage->GetDimension() < 3) { m_Controls->leImage1->setText("2D images are not supported."); return; } //image m_Controls->leImage1->setText(QString(m_SelectedImageNode->GetNode()->GetName().c_str())); // button coding if ( tempImage->GetDimension() > 3 ) { m_Controls->sliceNavigatorTime->setEnabled(true); m_Controls->tlTime->setEnabled(true); } m_Controls->tlWhat1->setEnabled(true); m_Controls->cbWhat1->setEnabled(true); m_Controls->tlWhat2->setEnabled(true); m_Controls->cbWhat2->setEnabled(true); } } void QmitkBasicImageProcessing::ChangeGUI() { if(m_Controls->rBOneImOp->isChecked()) { m_Controls->gbTwoImageOps->hide(); m_Controls->gbOneImageOps->show(); } else if(m_Controls->rBTwoImOp->isChecked()) { m_Controls->gbOneImageOps->hide(); m_Controls->gbTwoImageOps->show(); } } void QmitkBasicImageProcessing::ResetOneImageOpPanel() { m_Controls->tlParam1->setText("Param1"); m_Controls->tlParam2->setText("Param2"); m_Controls->cbWhat1->setCurrentIndex(0); m_Controls->tlTime->setEnabled(false); this->ResetParameterPanel(); m_Controls->btnDoIt->setEnabled(false); m_Controls->cbHideOrig->setEnabled(false); } void QmitkBasicImageProcessing::ResetParameterPanel() { m_Controls->tlParam->setEnabled(false); m_Controls->tlParam1->setEnabled(false); m_Controls->tlParam2->setEnabled(false); m_Controls->tlParam3->setEnabled(false); m_Controls->tlParam4->setEnabled(false); m_Controls->sbParam1->setEnabled(false); m_Controls->sbParam2->setEnabled(false); m_Controls->dsbParam1->setEnabled(false); m_Controls->dsbParam2->setEnabled(false); m_Controls->dsbParam3->setEnabled(false); m_Controls->cbParam4->setEnabled(false); m_Controls->sbParam1->setValue(0); m_Controls->sbParam2->setValue(0); m_Controls->dsbParam1->setValue(0); m_Controls->dsbParam2->setValue(0); m_Controls->dsbParam3->setValue(0); m_Controls->sbParam1->show(); m_Controls->sbParam2->show(); m_Controls->dsbParam1->hide(); m_Controls->dsbParam2->hide(); m_Controls->dsbParam3->hide(); m_Controls->cbParam4->hide(); m_Controls->tlParam3->hide(); m_Controls->tlParam4->hide(); } void QmitkBasicImageProcessing::ResetTwoImageOpPanel() { m_Controls->cbWhat2->setCurrentIndex(0); m_Controls->tlImage2->setEnabled(false); m_Controls->m_ImageSelector2->setEnabled(false); m_Controls->btnDoIt2->setEnabled(false); } void QmitkBasicImageProcessing::SelectAction(int action) { if ( ! m_SelectedImageNode->GetNode() ) return; // Prepare GUI this->ResetParameterPanel(); m_Controls->btnDoIt->setEnabled(false); m_Controls->cbHideOrig->setEnabled(false); QString text1 = "No Parameters"; QString text2 = "No Parameters"; QString text3 = "No Parameters"; QString text4 = "No Parameters"; if (action != 19) { m_Controls->dsbParam1->hide(); m_Controls->dsbParam2->hide(); m_Controls->dsbParam3->hide(); m_Controls->tlParam3->hide(); m_Controls->tlParam4->hide(); m_Controls->sbParam1->show(); m_Controls->sbParam2->show(); m_Controls->cbParam4->hide(); } // check which operation the user has selected and set parameters and GUI accordingly switch (action) { case 2: { m_SelectedAction = GAUSSIAN; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = "&Variance:"; m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 200 ); m_Controls->sbParam1->setValue( 2 ); break; } case 3: { m_SelectedAction = MEDIAN; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = "&Radius:"; m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 200 ); m_Controls->sbParam1->setValue( 3 ); break; } case 4: { m_SelectedAction = TOTALVARIATION; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); m_Controls->tlParam2->setEnabled(true); m_Controls->sbParam2->setEnabled(true); text1 = "Number Iterations:"; text2 = "Regularization\n(Lambda/1000):"; m_Controls->sbParam1->setMinimum( 1 ); m_Controls->sbParam1->setMaximum( 1000 ); m_Controls->sbParam1->setValue( 40 ); m_Controls->sbParam2->setMinimum( 0 ); m_Controls->sbParam2->setMaximum( 100000 ); m_Controls->sbParam2->setValue( 1 ); break; } case 6: { m_SelectedAction = DILATION; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = "&Radius:"; m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 200 ); m_Controls->sbParam1->setValue( 3 ); break; } case 7: { m_SelectedAction = EROSION; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = "&Radius:"; m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 200 ); m_Controls->sbParam1->setValue( 3 ); break; } case 8: { m_SelectedAction = OPENING; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = "&Radius:"; m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 200 ); m_Controls->sbParam1->setValue( 3 ); break; } case 9: { m_SelectedAction = CLOSING; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = "&Radius:"; m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 200 ); m_Controls->sbParam1->setValue( 3 ); break; } case 11: { m_SelectedAction = GRADIENT; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = "Sigma of Gaussian Kernel:\n(in Image Spacing Units)"; m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 200 ); m_Controls->sbParam1->setValue( 2 ); break; } case 12: { m_SelectedAction = LAPLACIAN; break; } case 13: { m_SelectedAction = SOBEL; break; } case 15: { m_SelectedAction = THRESHOLD; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); m_Controls->tlParam2->setEnabled(true); m_Controls->sbParam2->setEnabled(true); text1 = "Lower threshold:"; text2 = "Upper threshold:"; m_Controls->sbParam1->setMinimum( -100000 ); m_Controls->sbParam1->setMaximum( 100000 ); m_Controls->sbParam1->setValue( 0 ); m_Controls->sbParam2->setMinimum( -100000 ); m_Controls->sbParam2->setMaximum( 100000 ); m_Controls->sbParam2->setValue( 300 ); break; } case 16: { m_SelectedAction = INVERSION; break; } case 17: { m_SelectedAction = DOWNSAMPLING; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = "Downsampling by Factor:"; m_Controls->sbParam1->setMinimum( 1 ); m_Controls->sbParam1->setMaximum( 100 ); m_Controls->sbParam1->setValue( 2 ); break; } case 18: { m_SelectedAction = FLIPPING; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(true); text1 = "Flip across axis:"; m_Controls->sbParam1->setMinimum( 0 ); m_Controls->sbParam1->setMaximum( 2 ); m_Controls->sbParam1->setValue( 1 ); break; } case 19: { m_SelectedAction = RESAMPLING; m_Controls->tlParam1->setEnabled(true); m_Controls->sbParam1->setEnabled(false); m_Controls->sbParam1->hide(); m_Controls->dsbParam1->show(); m_Controls->dsbParam1->setEnabled(true); m_Controls->tlParam2->setEnabled(true); m_Controls->sbParam2->setEnabled(false); m_Controls->sbParam2->hide(); m_Controls->dsbParam2->show(); m_Controls->dsbParam2->setEnabled(true); m_Controls->tlParam3->show(); m_Controls->tlParam3->setEnabled(true); m_Controls->dsbParam3->show(); m_Controls->dsbParam3->setEnabled(true); m_Controls->tlParam4->show(); m_Controls->tlParam4->setEnabled(true); m_Controls->cbParam4->show(); m_Controls->cbParam4->setEnabled(true); m_Controls->dsbParam1->setMinimum(0.01); m_Controls->dsbParam1->setMaximum(10.0); m_Controls->dsbParam1->setSingleStep(0.1); m_Controls->dsbParam1->setValue(0.3); m_Controls->dsbParam2->setMinimum(0.01); m_Controls->dsbParam2->setMaximum(10.0); m_Controls->dsbParam2->setSingleStep(0.1); m_Controls->dsbParam2->setValue(0.3); m_Controls->dsbParam3->setMinimum(0.01); m_Controls->dsbParam3->setMaximum(10.0); m_Controls->dsbParam3->setSingleStep(0.1); m_Controls->dsbParam3->setValue(1.5); text1 = "x-spacing:"; text2 = "y-spacing:"; text3 = "z-spacing:"; text4 = "Interplation:"; break; } case 20: { m_SelectedAction = RESCALE; m_Controls->dsbParam1->show(); m_Controls->tlParam1->show(); m_Controls->dsbParam1->setEnabled(true); m_Controls->tlParam1->setEnabled(true); m_Controls->dsbParam2->show(); m_Controls->tlParam2->show(); m_Controls->dsbParam2->setEnabled(true); m_Controls->tlParam2->setEnabled(true); text1 = "Output minimum:"; text2 = "Output maximum:"; break; } + case 21: + { + m_SelectedAction = RESCALE2; + m_Controls->dsbParam1->show(); + m_Controls->tlParam1->show(); + m_Controls->dsbParam1->setEnabled(true); + m_Controls->tlParam1->setEnabled(true); + text1 = "Scaling value:"; + break; + } default: return; } m_Controls->tlParam->setEnabled(true); m_Controls->tlParam1->setText(text1); m_Controls->tlParam2->setText(text2); m_Controls->tlParam3->setText(text3); m_Controls->tlParam4->setText(text4); m_Controls->btnDoIt->setEnabled(true); m_Controls->cbHideOrig->setEnabled(true); } void QmitkBasicImageProcessing::StartButtonClicked() { if(!m_SelectedImageNode->GetNode()) return; this->BusyCursorOn(); mitk::Image::Pointer newImage; try { newImage = dynamic_cast(m_SelectedImageNode->GetNode()->GetData()); } catch ( std::exception &e ) { QString exceptionString = "An error occured during image loading:\n"; exceptionString.append( e.what() ); QMessageBox::warning( NULL, "Basic Image Processing", exceptionString , QMessageBox::Ok, QMessageBox::NoButton ); this->BusyCursorOff(); return; } // check if input image is valid, casting does not throw exception when casting from 'NULL-Object' if ( (! newImage) || (newImage->IsInitialized() == false) ) { this->BusyCursorOff(); QMessageBox::warning( NULL, "Basic Image Processing", "Input image is broken or not initialized. Returning.", QMessageBox::Ok, QMessageBox::NoButton ); return; } // check if operation is done on 4D a image time step if(newImage->GetDimension() > 3) { mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput(newImage); timeSelector->SetTimeNr( ((QmitkSliderNavigatorWidget*)m_Controls->sliceNavigatorTime)->GetPos() ); timeSelector->Update(); newImage = timeSelector->GetOutput(); } // check if image or vector image ImageType::Pointer itkImage = ImageType::New(); VectorImageType::Pointer itkVecImage = VectorImageType::New(); int isVectorImage = newImage->GetPixelType().GetNumberOfComponents(); if(isVectorImage > 1) { CastToItkImage( newImage, itkVecImage ); } else { CastToItkImage( newImage, itkImage ); } std::stringstream nameAddition(""); int param1 = m_Controls->sbParam1->value(); int param2 = m_Controls->sbParam2->value(); double dparam1 = m_Controls->dsbParam1->value(); double dparam2 = m_Controls->dsbParam2->value(); double dparam3 = m_Controls->dsbParam3->value(); try{ switch (m_SelectedAction) { case GAUSSIAN: { GaussianFilterType::Pointer gaussianFilter = GaussianFilterType::New(); gaussianFilter->SetInput( itkImage ); gaussianFilter->SetVariance( param1 ); gaussianFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(gaussianFilter->GetOutput())->Clone(); nameAddition << "_Gaussian_var_" << param1; std::cout << "Gaussian filtering successful." << std::endl; break; } case MEDIAN: { MedianFilterType::Pointer medianFilter = MedianFilterType::New(); MedianFilterType::InputSizeType size; size.Fill(param1); medianFilter->SetRadius( size ); medianFilter->SetInput(itkImage); medianFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(medianFilter->GetOutput())->Clone(); nameAddition << "_Median_radius_" << param1; std::cout << "Median Filtering successful." << std::endl; break; } case TOTALVARIATION: { if(isVectorImage > 1) { VectorTotalVariationFilterType::Pointer TVFilter = VectorTotalVariationFilterType::New(); TVFilter->SetInput( itkVecImage.GetPointer() ); TVFilter->SetNumberIterations(param1); TVFilter->SetLambda(double(param2)/1000.); TVFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(TVFilter->GetOutput())->Clone(); } else { ImagePTypeToFloatPTypeCasterType::Pointer floatCaster = ImagePTypeToFloatPTypeCasterType::New(); floatCaster->SetInput( itkImage ); floatCaster->Update(); - FloatImageType::Pointer fImage = floatCaster->GetOutput(); + DoubleImageType::Pointer fImage = floatCaster->GetOutput(); TotalVariationFilterType::Pointer TVFilter = TotalVariationFilterType::New(); TVFilter->SetInput( fImage.GetPointer() ); TVFilter->SetNumberIterations(param1); TVFilter->SetLambda(double(param2)/1000.); TVFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(TVFilter->GetOutput())->Clone(); } nameAddition << "_TV_Iter_" << param1 << "_L_" << param2; std::cout << "Total Variation Filtering successful." << std::endl; break; } case DILATION: { BallType binaryBall; binaryBall.SetRadius( param1 ); binaryBall.CreateStructuringElement(); DilationFilterType::Pointer dilationFilter = DilationFilterType::New(); dilationFilter->SetInput( itkImage ); dilationFilter->SetKernel( binaryBall ); dilationFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(dilationFilter->GetOutput())->Clone(); nameAddition << "_Dilated_by_" << param1; std::cout << "Dilation successful." << std::endl; break; } case EROSION: { BallType binaryBall; binaryBall.SetRadius( param1 ); binaryBall.CreateStructuringElement(); ErosionFilterType::Pointer erosionFilter = ErosionFilterType::New(); erosionFilter->SetInput( itkImage ); erosionFilter->SetKernel( binaryBall ); erosionFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(erosionFilter->GetOutput())->Clone(); nameAddition << "_Eroded_by_" << param1; std::cout << "Erosion successful." << std::endl; break; } case OPENING: { BallType binaryBall; binaryBall.SetRadius( param1 ); binaryBall.CreateStructuringElement(); OpeningFilterType::Pointer openFilter = OpeningFilterType::New(); openFilter->SetInput( itkImage ); openFilter->SetKernel( binaryBall ); openFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(openFilter->GetOutput())->Clone(); nameAddition << "_Opened_by_" << param1; std::cout << "Opening successful." << std::endl; break; } case CLOSING: { BallType binaryBall; binaryBall.SetRadius( param1 ); binaryBall.CreateStructuringElement(); ClosingFilterType::Pointer closeFilter = ClosingFilterType::New(); closeFilter->SetInput( itkImage ); closeFilter->SetKernel( binaryBall ); closeFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(closeFilter->GetOutput())->Clone(); nameAddition << "_Closed_by_" << param1; std::cout << "Closing successful." << std::endl; break; } case GRADIENT: { GradientFilterType::Pointer gradientFilter = GradientFilterType::New(); gradientFilter->SetInput( itkImage ); gradientFilter->SetSigma( param1 ); gradientFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(gradientFilter->GetOutput())->Clone(); nameAddition << "_Gradient_sigma_" << param1; std::cout << "Gradient calculation successful." << std::endl; break; } case LAPLACIAN: { // the laplace filter requires a float type image as input, we need to cast the itkImage // to correct type ImagePTypeToFloatPTypeCasterType::Pointer caster = ImagePTypeToFloatPTypeCasterType::New(); caster->SetInput( itkImage ); caster->Update(); - FloatImageType::Pointer fImage = caster->GetOutput(); + DoubleImageType::Pointer fImage = caster->GetOutput(); LaplacianFilterType::Pointer laplacianFilter = LaplacianFilterType::New(); laplacianFilter->SetInput( fImage ); laplacianFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(laplacianFilter->GetOutput())->Clone(); nameAddition << "_Second_Derivative"; std::cout << "Laplacian filtering successful." << std::endl; break; } case SOBEL: { // the sobel filter requires a float type image as input, we need to cast the itkImage // to correct type ImagePTypeToFloatPTypeCasterType::Pointer caster = ImagePTypeToFloatPTypeCasterType::New(); caster->SetInput( itkImage ); caster->Update(); - FloatImageType::Pointer fImage = caster->GetOutput(); + DoubleImageType::Pointer fImage = caster->GetOutput(); SobelFilterType::Pointer sobelFilter = SobelFilterType::New(); sobelFilter->SetInput( fImage ); sobelFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(sobelFilter->GetOutput())->Clone(); nameAddition << "_Sobel"; std::cout << "Edge Detection successful." << std::endl; break; } case THRESHOLD: { ThresholdFilterType::Pointer thFilter = ThresholdFilterType::New(); thFilter->SetLowerThreshold(param1 < param2 ? param1 : param2); thFilter->SetUpperThreshold(param2 > param1 ? param2 : param1); thFilter->SetInsideValue(1); thFilter->SetOutsideValue(0); thFilter->SetInput(itkImage); thFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(thFilter->GetOutput())->Clone(); nameAddition << "_Threshold"; std::cout << "Thresholding successful." << std::endl; break; } case INVERSION: { InversionFilterType::Pointer invFilter = InversionFilterType::New(); mitk::ScalarType min = newImage->GetScalarValueMin(); mitk::ScalarType max = newImage->GetScalarValueMax(); invFilter->SetMaximum( max + min ); invFilter->SetInput(itkImage); invFilter->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(invFilter->GetOutput())->Clone(); nameAddition << "_Inverted"; std::cout << "Image inversion successful." << std::endl; break; } case DOWNSAMPLING: { ResampleImageFilterType::Pointer downsampler = ResampleImageFilterType::New(); downsampler->SetInput( itkImage ); NearestInterpolatorType::Pointer interpolator = NearestInterpolatorType::New(); downsampler->SetInterpolator( interpolator ); downsampler->SetDefaultPixelValue( 0 ); ResampleImageFilterType::SpacingType spacing = itkImage->GetSpacing(); spacing *= (double) param1; downsampler->SetOutputSpacing( spacing ); downsampler->SetOutputOrigin( itkImage->GetOrigin() ); downsampler->SetOutputDirection( itkImage->GetDirection() ); ResampleImageFilterType::SizeType size = itkImage->GetLargestPossibleRegion().GetSize(); for ( int i = 0; i < 3; ++i ) { size[i] /= param1; } downsampler->SetSize( size ); downsampler->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(downsampler->GetOutput())->Clone(); nameAddition << "_Downsampled_by_" << param1; std::cout << "Downsampling successful." << std::endl; break; } case FLIPPING: { FlipImageFilterType::Pointer flipper = FlipImageFilterType::New(); flipper->SetInput( itkImage ); itk::FixedArray flipAxes; for(int i=0; i<3; ++i) { if(i == param1) { flipAxes[i] = true; } else { flipAxes[i] = false; } } flipper->SetFlipAxes(flipAxes); flipper->UpdateLargestPossibleRegion(); newImage = mitk::ImportItkImage(flipper->GetOutput())->Clone(); std::cout << "Image flipping successful." << std::endl; break; } case RESAMPLING: { std::string selectedInterpolator; ResampleImageFilterType::Pointer resampler = ResampleImageFilterType::New(); switch (m_SelectedInterpolation) { case LINEAR: { LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New(); resampler->SetInterpolator(interpolator); selectedInterpolator = "Linear"; break; } case NEAREST: { NearestInterpolatorType::Pointer interpolator = NearestInterpolatorType::New(); resampler->SetInterpolator(interpolator); selectedInterpolator = "Nearest"; break; } default: { LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New(); resampler->SetInterpolator(interpolator); selectedInterpolator = "Linear"; break; } } resampler->SetInput( itkImage ); resampler->SetOutputOrigin( itkImage->GetOrigin() ); ImageType::SizeType input_size = itkImage->GetLargestPossibleRegion().GetSize(); ImageType::SpacingType input_spacing = itkImage->GetSpacing(); ImageType::SizeType output_size; ImageType::SpacingType output_spacing; output_size[0] = input_size[0] * (input_spacing[0] / dparam1); output_size[1] = input_size[1] * (input_spacing[1] / dparam2); output_size[2] = input_size[2] * (input_spacing[2] / dparam3); output_spacing [0] = dparam1; output_spacing [1] = dparam2; output_spacing [2] = dparam3; resampler->SetSize( output_size ); resampler->SetOutputSpacing( output_spacing ); resampler->SetOutputDirection( itkImage->GetDirection() ); resampler->UpdateLargestPossibleRegion(); ImageType::Pointer resampledImage = resampler->GetOutput(); newImage = mitk::ImportItkImage( resampledImage ); nameAddition << "_Resampled_" << selectedInterpolator; std::cout << "Resampling successful." << std::endl; break; } case RESCALE: { - FloatImageType::Pointer floatImage = FloatImageType::New(); + DoubleImageType::Pointer floatImage = DoubleImageType::New(); CastToItkImage( newImage, floatImage ); - itk::RescaleIntensityImageFilter::Pointer filter = itk::RescaleIntensityImageFilter::New(); + itk::RescaleIntensityImageFilter::Pointer filter = itk::RescaleIntensityImageFilter::New(); filter->SetInput(0, floatImage); filter->SetOutputMinimum(dparam1); filter->SetOutputMaximum(dparam2); filter->Update(); floatImage = filter->GetOutput(); newImage = mitk::Image::New(); newImage->InitializeByItk(floatImage.GetPointer()); newImage->SetVolume(floatImage->GetBufferPointer()); nameAddition << "_Rescaled"; std::cout << "Rescaling successful." << std::endl; break; } + case RESCALE2: + { + DoubleImageType::Pointer floatImage = DoubleImageType::New(); + CastToItkImage( newImage, floatImage ); + itk::ShiftScaleImageFilter::Pointer filter = itk::ShiftScaleImageFilter::New(); + filter->SetInput(0, floatImage); + filter->SetScale(dparam1); + + filter->Update(); + floatImage = filter->GetOutput(); + + newImage = mitk::Image::New(); + newImage->InitializeByItk(floatImage.GetPointer()); + newImage->SetVolume(floatImage->GetBufferPointer()); + nameAddition << "_Rescaled"; + std::cout << "Rescaling successful." << std::endl; + break; + } default: this->BusyCursorOff(); return; } } catch (...) { this->BusyCursorOff(); QMessageBox::warning(NULL, "Warning", "Problem when applying filter operation. Check your input..."); return; } newImage->DisconnectPipeline(); // adjust level/window to new image mitk::LevelWindow levelwindow; levelwindow.SetAuto( newImage ); mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New(); levWinProp->SetLevelWindow( levelwindow ); // compose new image name std::string name = m_SelectedImageNode->GetNode()->GetName(); if (name.find(".pic.gz") == name.size() -7 ) { name = name.substr(0,name.size() -7); } name.append( nameAddition.str() ); // create final result MITK data storage node mitk::DataNode::Pointer result = mitk::DataNode::New(); result->SetProperty( "levelwindow", levWinProp ); result->SetProperty( "name", mitk::StringProperty::New( name.c_str() ) ); result->SetData( newImage ); // for vector images, a different mapper is needed if(isVectorImage > 1) { mitk::VectorImageMapper2D::Pointer mapper = mitk::VectorImageMapper2D::New(); result->SetMapper(1,mapper); } // reset GUI to ease further processing // this->ResetOneImageOpPanel(); // add new image to data storage and set as active to ease further processing GetDefaultDataStorage()->Add( result, m_SelectedImageNode->GetNode() ); if ( m_Controls->cbHideOrig->isChecked() == true ) m_SelectedImageNode->GetNode()->SetProperty( "visible", mitk::BoolProperty::New(false) ); // TODO!! m_Controls->m_ImageSelector1->SetSelectedNode(result); // show the results mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->BusyCursorOff(); } void QmitkBasicImageProcessing::SelectAction2(int operation) { // check which operation the user has selected and set parameters and GUI accordingly switch (operation) { case 2: m_SelectedOperation = ADD; break; case 3: m_SelectedOperation = SUBTRACT; break; case 4: m_SelectedOperation = MULTIPLY; break; case 5: m_SelectedOperation = DIVIDE; break; case 6: m_SelectedOperation = RESAMPLE_TO; break; case 8: m_SelectedOperation = AND; break; case 9: m_SelectedOperation = OR; break; case 10: m_SelectedOperation = XOR; break; default: // this->ResetTwoImageOpPanel(); return; } m_Controls->tlImage2->setEnabled(true); m_Controls->m_ImageSelector2->setEnabled(true); m_Controls->btnDoIt2->setEnabled(true); } void QmitkBasicImageProcessing::StartButton2Clicked() { mitk::Image::Pointer newImage1 = dynamic_cast (m_SelectedImageNode->GetNode()->GetData()); mitk::Image::Pointer newImage2 = dynamic_cast (m_Controls->m_ImageSelector2->GetSelectedNode()->GetData()); // check if images are valid if( (!newImage1) || (!newImage2) || (newImage1->IsInitialized() == false) || (newImage2->IsInitialized() == false) ) { itkGenericExceptionMacro(<< "At least one of the input images are broken or not initialized. Returning"); return; } this->BusyCursorOn(); // this->ResetTwoImageOpPanel(); // check if 4D image and use filter on correct time step int time = ((QmitkSliderNavigatorWidget*)m_Controls->sliceNavigatorTime)->GetPos(); if(newImage1->GetDimension() > 3) { mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput(newImage1); timeSelector->SetTimeNr( time ); timeSelector->UpdateLargestPossibleRegion(); newImage1 = timeSelector->GetOutput(); newImage1->DisconnectPipeline(); timeSelector->SetInput(newImage2); timeSelector->SetTimeNr( time ); timeSelector->UpdateLargestPossibleRegion(); newImage2 = timeSelector->GetOutput(); newImage2->DisconnectPipeline(); } // reset GUI for better usability // this->ResetTwoImageOpPanel(); ImageType::Pointer itkImage1 = ImageType::New(); ImageType::Pointer itkImage2 = ImageType::New(); CastToItkImage( newImage1, itkImage1 ); CastToItkImage( newImage2, itkImage2 ); // Remove temp image - newImage2 = NULL; +// newImage2 = NULL; std::string nameAddition = ""; try { switch (m_SelectedOperation) { case ADD: { AddFilterType::Pointer addFilter = AddFilterType::New(); addFilter->SetInput1( itkImage1 ); addFilter->SetInput2( itkImage2 ); addFilter->UpdateLargestPossibleRegion(); newImage1 = mitk::ImportItkImage(addFilter->GetOutput())->Clone(); nameAddition = "_Added"; } break; case SUBTRACT: { SubtractFilterType::Pointer subFilter = SubtractFilterType::New(); subFilter->SetInput1( itkImage1 ); subFilter->SetInput2( itkImage2 ); subFilter->UpdateLargestPossibleRegion(); newImage1 = mitk::ImportItkImage(subFilter->GetOutput())->Clone(); nameAddition = "_Subtracted"; } break; case MULTIPLY: { MultiplyFilterType::Pointer multFilter = MultiplyFilterType::New(); multFilter->SetInput1( itkImage1 ); multFilter->SetInput2( itkImage2 ); multFilter->UpdateLargestPossibleRegion(); newImage1 = mitk::ImportItkImage(multFilter->GetOutput())->Clone(); nameAddition = "_Multiplied"; } break; case DIVIDE: { DivideFilterType::Pointer divFilter = DivideFilterType::New(); divFilter->SetInput1( itkImage1 ); divFilter->SetInput2( itkImage2 ); divFilter->UpdateLargestPossibleRegion(); - newImage1 = mitk::ImportItkImage(divFilter->GetOutput())->Clone(); + newImage1 = mitk::ImportItkImage(divFilter->GetOutput())->Clone(); nameAddition = "_Divided"; } break; case AND: { AndImageFilterType::Pointer andFilter = AndImageFilterType::New(); andFilter->SetInput1( itkImage1 ); andFilter->SetInput2( itkImage2 ); andFilter->UpdateLargestPossibleRegion(); newImage1 = mitk::ImportItkImage(andFilter->GetOutput())->Clone(); nameAddition = "_AND"; break; } case OR: { OrImageFilterType::Pointer orFilter = OrImageFilterType::New(); orFilter->SetInput1( itkImage1 ); orFilter->SetInput2( itkImage2 ); orFilter->UpdateLargestPossibleRegion(); newImage1 = mitk::ImportItkImage(orFilter->GetOutput())->Clone(); nameAddition = "_OR"; break; } case XOR: { XorImageFilterType::Pointer xorFilter = XorImageFilterType::New(); xorFilter->SetInput1( itkImage1 ); xorFilter->SetInput2( itkImage2 ); xorFilter->UpdateLargestPossibleRegion(); newImage1 = mitk::ImportItkImage(xorFilter->GetOutput())->Clone(); nameAddition = "_XOR"; break; } case RESAMPLE_TO: { - itk::NearestNeighborInterpolateImageFunction::Pointer nn_interpolator - = itk::NearestNeighborInterpolateImageFunction::New(); + itk::LinearInterpolateImageFunction::Pointer nn_interpolator + = itk::LinearInterpolateImageFunction::New(); + + DoubleImageType::Pointer itkImage1 = DoubleImageType::New(); + DoubleImageType::Pointer itkImage2 = DoubleImageType::New(); + + CastToItkImage( newImage1, itkImage1 ); + CastToItkImage( newImage2, itkImage2 ); - ResampleImageFilterType2::Pointer resampleFilter = ResampleImageFilterType2::New(); + itk::ResampleImageFilter< DoubleImageType, DoubleImageType >::Pointer resampleFilter = itk::ResampleImageFilter< DoubleImageType, DoubleImageType >::New(); resampleFilter->SetInput( itkImage1 ); resampleFilter->SetReferenceImage( itkImage2 ); resampleFilter->SetUseReferenceImage( true ); resampleFilter->SetInterpolator( nn_interpolator ); resampleFilter->SetDefaultPixelValue( 0 ); try { resampleFilter->UpdateLargestPossibleRegion(); } catch( const itk::ExceptionObject &e) { MITK_WARN << "Updating resampling filter failed. "; MITK_WARN << "REASON: " << e.what(); } - ImageType::Pointer resampledImage = resampleFilter->GetOutput(); + DoubleImageType::Pointer resampledImage = resampleFilter->GetOutput(); newImage1 = mitk::ImportItkImage( resampledImage )->Clone(); nameAddition = "_Resampled"; break; } default: std::cout << "Something went wrong..." << std::endl; this->BusyCursorOff(); return; } } catch (const itk::ExceptionObject& e ) { this->BusyCursorOff(); QMessageBox::warning(NULL, "ITK Exception", e.what() ); QMessageBox::warning(NULL, "Warning", "Problem when applying arithmetic operation to two images. Check dimensions of input images."); return; } // disconnect pipeline; images will not be reused newImage1->DisconnectPipeline(); itkImage1 = NULL; itkImage2 = NULL; // adjust level/window to new image and compose new image name mitk::LevelWindow levelwindow; levelwindow.SetAuto( newImage1 ); mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New(); levWinProp->SetLevelWindow( levelwindow ); std::string name = m_SelectedImageNode->GetNode()->GetName(); if (name.find(".pic.gz") == name.size() -7 ) { name = name.substr(0,name.size() -7); } // create final result MITK data storage node mitk::DataNode::Pointer result = mitk::DataNode::New(); result->SetProperty( "levelwindow", levWinProp ); result->SetProperty( "name", mitk::StringProperty::New( (name + nameAddition ).c_str() )); result->SetData( newImage1 ); GetDefaultDataStorage()->Add( result, m_SelectedImageNode->GetNode() ); // show only the newly created image m_SelectedImageNode->GetNode()->SetProperty( "visible", mitk::BoolProperty::New(false) ); m_Controls->m_ImageSelector2->GetSelectedNode()->SetProperty( "visible", mitk::BoolProperty::New(false) ); // show the newly created image mitk::RenderingManager::GetInstance()->RequestUpdateAll(); this->BusyCursorOff(); } void QmitkBasicImageProcessing::SelectInterpolator(int interpolator) { switch (interpolator) { case 0: { m_SelectedInterpolation = LINEAR; break; } case 1: { m_SelectedInterpolation = NEAREST; break; } } } diff --git a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.h b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.h index e727fb698b..7dbae6cf4b 100644 --- a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.h +++ b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.h @@ -1,189 +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. ===================================================================*/ #if !defined(QmitkBasicImageProcessingView_H__INCLUDED) #define QmitkBasicImageProcessingView_H__INCLUDED #include "QmitkFunctionality.h" #include #include "ui_QmitkBasicImageProcessingViewControls.h" #include "QmitkStepperAdapter.h" #include #include /*! \brief This module allows to use some basic image processing filters for preprocessing, image enhancement and testing purposes Several basic ITK image processing filters, like denoising, morphological and edge detection are encapsulated in this module and can be selected via a list and an intuitive parameter input. The selected filter will be applied on the image, and a new image showing the output is displayed as result. Also, some image arithmetic operations are available. Images can be 3D or 4D. In the 4D case, the filters work on the 3D image selected via the time slider. The result is also a 3D image. \sa QmitkFunctionality, QObject \class QmitkBasicImageProcessing \author Tobias Schwarz \version 1.0 (3M3) \date 2009-05-10 \ingroup Bundles */ class BASICIMAGEPROCESSING_EXPORT QmitkBasicImageProcessing : public QmitkFunctionality { Q_OBJECT public: /*! \brief default constructor */ QmitkBasicImageProcessing(); /*! \brief default destructor */ virtual ~QmitkBasicImageProcessing(); /*! \brief method for creating the widget containing the application controls, like sliders, buttons etc. */ virtual void CreateQtPartControl(QWidget *parent); /*! \brief method for creating the connections of main and control widget */ virtual void CreateConnections(); virtual void Activated(); /*! \brief Invoked when the DataManager selection changed */ virtual void OnSelectionChanged(std::vector nodes); protected slots: /* * When an action is selected in the "one image ops" list box */ void SelectAction(int action); /* * When an action is selected in the "two image ops" list box */ void SelectAction2(int operation); /* * The "Execute" button in the "one image ops" box was triggered */ void StartButtonClicked(); /* * The "Execute" button in the "two image ops" box was triggered */ void StartButton2Clicked(); /* * Switch between the one and the two image operations GUI */ void ChangeGUI(); void SelectInterpolator(int interpolator); private: /* * After a one image operation, reset the "one image ops" panel */ void ResetOneImageOpPanel(); /* * Helper method to reset the parameter set panel */ void ResetParameterPanel(); /* * After a two image operation, reset the "two image ops" panel */ void ResetTwoImageOpPanel(); /*! * controls containing sliders for scrolling through the slices */ Ui::QmitkBasicImageProcessingViewControls *m_Controls; //mitk::DataNode* m_SelectedImageNode; mitk::DataStorageSelection::Pointer m_SelectedImageNode; QmitkStepperAdapter* m_TimeStepperAdapter; berry::ISelectionListener::Pointer m_SelectionListener; enum ActionType { NOACTIONSELECTED, CATEGORY_DENOISING, GAUSSIAN, MEDIAN, TOTALVARIATION, CATEGORY_MORPHOLOGICAL, DILATION, EROSION, OPENING, CLOSING, CATEGORY_EDGE_DETECTION, GRADIENT, LAPLACIAN, SOBEL, CATEGORY_MISC, THRESHOLD, INVERSION, DOWNSAMPLING, FLIPPING, RESAMPLING, - RESCALE + RESCALE, + RESCALE2 } m_SelectedAction; enum OperationType{ TWOIMAGESNOACTIONSELECTED, CATEGORY_ARITHMETIC, ADD, SUBTRACT, MULTIPLY, DIVIDE, RESAMPLE_TO, CATEGORY_BOOLEAN, AND, OR, XOR } m_SelectedOperation; enum InterpolationType{ LINEAR, NEAREST } m_SelectedInterpolation; }; #endif // !defined(QmitkBasicImageProcessing_H__INCLUDED) diff --git a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingViewControls.ui b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingViewControls.ui index 04e8dbc142..179daf05a9 100644 --- a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingViewControls.ui +++ b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingViewControls.ui @@ -1,452 +1,473 @@ QmitkBasicImageProcessingViewControls 0 0 - 379 + 448 980 Form true 0 6 0 6 Filters (One Image) true Arithmetic (Two Images) Select an Image in Data Manager true false Output image will be 3D Choose time step if 4D (Slider for both images) false false Output image will be 3D true true false false 0 6 0 0 false Select second image: false m_ImageSelector2 false false E&xecute false Select an operation: false cbWhat2 false Qt::Vertical 254 403 true 0 6 0 0 false Select an operation: false cbWhat1 false false ... and parameters: false false Parameter 1: false sbParam1 false Parameter 2: false sbParam2 false &Execute false Hide Original Image true false Parameter 3: false Parameter 4: false 0 0 false 0 0 Qt::LeftToRight Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + 4 + + + -999999999.000000000000000 + 999999999.000000000000000 false 0 0 + + 4 + + + -999999999.000000000000000 + 999999999.000000000000000 false 0 0 - 2 + 4 + + + -999999999.000000000000000 999999999.000000000000000 false 0 0 + + -999999999 + 999999999 false 0 0 + + -999999999 + 999999999 QmitkDataStorageComboBox QComboBox
QmitkDataStorageComboBox.h
QmitkSliderNavigatorWidget QWidget
QmitkSliderNavigatorWidget.h
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberQuantificationView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberQuantificationView.cpp index e12f09e205..18f19cee9d 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberQuantificationView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberQuantificationView.cpp @@ -1,442 +1,455 @@ /*=================================================================== 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. ===================================================================*/ // Blueberry #include #include // Qmitk #include "QmitkFiberQuantificationView.h" #include // Qt #include // MITK #include #include #include #include #include #include #include #include #include #include #include // ITK #include #include #include #include #include #include #include #include #include #include const std::string QmitkFiberQuantificationView::VIEW_ID = "org.mitk.views.fiberquantification"; const std::string id_DataManager = "org.mitk.views.datamanager"; using namespace mitk; QmitkFiberQuantificationView::QmitkFiberQuantificationView() : QmitkFunctionality() , m_Controls( 0 ) , m_MultiWidget( NULL ) , m_UpsamplingFactor(5) { } // Destructor QmitkFiberQuantificationView::~QmitkFiberQuantificationView() { } void QmitkFiberQuantificationView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkFiberQuantificationViewControls; m_Controls->setupUi( parent ); connect( m_Controls->m_ProcessFiberBundleButton, SIGNAL(clicked()), this, SLOT(ProcessSelectedBundles()) ); connect( m_Controls->m_ExtractFiberPeaks, SIGNAL(clicked()), this, SLOT(CalculateFiberDirections()) ); } } void QmitkFiberQuantificationView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkFiberQuantificationView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } void QmitkFiberQuantificationView::CalculateFiberDirections() { typedef itk::Image ItkUcharImgType; typedef itk::Image< itk::Vector< float, 3>, 3 > ItkDirectionImage3DType; typedef itk::VectorContainer< unsigned int, ItkDirectionImage3DType::Pointer > ItkDirectionImageContainerType; // load fiber bundle mitk::FiberBundleX::Pointer inputTractogram = dynamic_cast(m_SelectedFB.back()->GetData()); itk::TractsToVectorImageFilter::Pointer fOdfFilter = itk::TractsToVectorImageFilter::New(); if (m_SelectedImage.IsNotNull()) { ItkUcharImgType::Pointer itkMaskImage = ItkUcharImgType::New(); mitk::CastToItkImage(m_SelectedImage, itkMaskImage); fOdfFilter->SetMaskImage(itkMaskImage); } // extract directions from fiber bundle fOdfFilter->SetFiberBundle(inputTractogram); fOdfFilter->SetAngularThreshold(cos(m_Controls->m_AngularThreshold->value()*M_PI/180)); fOdfFilter->SetNormalizeVectors(m_Controls->m_NormalizeDirectionsBox->isChecked()); fOdfFilter->SetUseWorkingCopy(true); fOdfFilter->SetCreateDirectionImages(m_Controls->m_DirectionImagesBox->isChecked()); fOdfFilter->SetSizeThreshold(m_Controls->m_PeakThreshold->value()); fOdfFilter->SetMaxNumDirections(m_Controls->m_MaxNumDirections->value()); fOdfFilter->Update(); QString name = m_SelectedFB.back()->GetName().c_str(); if (m_Controls->m_VectorFieldBox->isChecked()) { float minSpacing = 1; if (m_SelectedImage.IsNotNull()) { mitk::Vector3D outImageSpacing = m_SelectedImage->GetGeometry()->GetSpacing(); if(outImageSpacing[0]GetOutputFiberBundle(); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(directions); node->SetName((name+"_vectorfield").toStdString().c_str()); node->SetProperty("Fiber2DSliceThickness", mitk::FloatProperty::New(minSpacing)); node->SetProperty("Fiber2DfadeEFX", mitk::BoolProperty::New(false)); node->SetProperty("color", mitk::ColorProperty::New(1.0f, 1.0f, 1.0f)); GetDefaultDataStorage()->Add(node, m_SelectedFB.back()); } if (m_Controls->m_NumDirectionsBox->isChecked()) { mitk::Image::Pointer mitkImage = mitk::Image::New(); mitkImage->InitializeByItk( fOdfFilter->GetNumDirectionsImage().GetPointer() ); mitkImage->SetVolume( fOdfFilter->GetNumDirectionsImage()->GetBufferPointer() ); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(mitkImage); node->SetName((name+"_numdirections").toStdString().c_str()); GetDefaultDataStorage()->Add(node, m_SelectedFB.back()); } if (m_Controls->m_DirectionImagesBox->isChecked()) { ItkDirectionImageContainerType::Pointer directionImageContainer = fOdfFilter->GetDirectionImageContainer(); for (unsigned int i=0; iSize(); i++) { itk::TractsToVectorImageFilter::ItkDirectionImageType::Pointer itkImg = directionImageContainer->GetElement(i); if (itkImg.IsNull()) return; mitk::Image::Pointer mitkImage = mitk::Image::New(); mitkImage->InitializeByItk( itkImg.GetPointer() ); mitkImage->SetVolume( itkImg->GetBufferPointer() ); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(mitkImage); node->SetName( (name+"_direction_"+boost::lexical_cast(i).c_str()).toStdString().c_str()); node->SetVisibility(false); GetDefaultDataStorage()->Add(node, m_SelectedFB.back()); } } } void QmitkFiberQuantificationView::UpdateGui() { m_Controls->m_ProcessFiberBundleButton->setEnabled(!m_SelectedFB.empty()); m_Controls->m_ExtractFiberPeaks->setEnabled(!m_SelectedFB.empty()); } void QmitkFiberQuantificationView::OnSelectionChanged( std::vector nodes ) { //reset existing Vectors containing FiberBundles and PlanarFigures from a previous selection m_SelectedFB.clear(); m_SelectedSurfaces.clear(); m_SelectedImage = NULL; for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { mitk::DataNode::Pointer node = *it; if ( dynamic_cast(node->GetData()) ) { m_SelectedFB.push_back(node); } else if (dynamic_cast(node->GetData())) m_SelectedImage = dynamic_cast(node->GetData()); else if (dynamic_cast(node->GetData())) { m_SelectedSurfaces.push_back(dynamic_cast(node->GetData())); } } UpdateGui(); + + + if (!this->IsVisible()) + return; GenerateStats(); } void QmitkFiberQuantificationView::Activated() { } void QmitkFiberQuantificationView::GenerateStats() { if ( m_SelectedFB.empty() ) return; QString stats(""); for( int i=0; i(node->GetData())) { if (i>0) stats += "\n-----------------------------\n"; stats += QString(node->GetName().c_str()) + "\n"; mitk::FiberBundleX::Pointer fib = dynamic_cast(node->GetData()); stats += "Number of fibers: "+ QString::number(fib->GetNumFibers()) + "\n"; stats += "Number of points: "+ QString::number(fib->GetNumberOfPoints()) + "\n"; stats += "Min. length: "+ QString::number(fib->GetMinFiberLength(),'f',1) + " mm\n"; stats += "Max. length: "+ QString::number(fib->GetMaxFiberLength(),'f',1) + " mm\n"; stats += "Mean length: "+ QString::number(fib->GetMeanFiberLength(),'f',1) + " mm\n"; stats += "Median length: "+ QString::number(fib->GetMedianFiberLength(),'f',1) + " mm\n"; stats += "Standard deviation: "+ QString::number(fib->GetLengthStDev(),'f',1) + " mm\n"; } } this->m_Controls->m_StatsTextEdit->setText(stats); } void QmitkFiberQuantificationView::ProcessSelectedBundles() { if ( m_SelectedFB.empty() ){ QMessageBox::information( NULL, "Warning", "No fibe bundle selected!"); MITK_WARN("QmitkFiberQuantificationView") << "no fibe bundle selected"; return; } int generationMethod = m_Controls->m_GenerationBox->currentIndex(); for( int i=0; i(node->GetData())) { mitk::FiberBundleX::Pointer fib = dynamic_cast(node->GetData()); QString name(node->GetName().c_str()); DataNode::Pointer newNode = NULL; switch(generationMethod){ case 0: newNode = GenerateTractDensityImage(fib, false, true); name += "_TDI"; break; case 1: newNode = GenerateTractDensityImage(fib, false, false); name += "_TDI"; break; case 2: newNode = GenerateTractDensityImage(fib, true, false); name += "_envelope"; break; case 3: newNode = GenerateColorHeatmap(fib); break; case 4: newNode = GenerateFiberEndingsImage(fib); name += "_fiber_endings"; break; case 5: newNode = GenerateFiberEndingsPointSet(fib); name += "_fiber_endings"; break; } if (newNode.IsNotNull()) { newNode->SetName(name.toStdString()); GetDataStorage()->Add(newNode); } } + break; } } // generate pointset displaying the fiber endings mitk::DataNode::Pointer QmitkFiberQuantificationView::GenerateFiberEndingsPointSet(mitk::FiberBundleX::Pointer fib) { mitk::PointSet::Pointer pointSet = mitk::PointSet::New(); vtkSmartPointer fiberPolyData = fib->GetFiberPolyData(); vtkSmartPointer vLines = fiberPolyData->GetLines(); vLines->InitTraversal(); int count = 0; int numFibers = fib->GetNumFibers(); for( int i=0; iGetNextCell ( numPoints, points ); if (numPoints>0) { double* point = fiberPolyData->GetPoint(points[0]); itk::Point itkPoint; itkPoint[0] = point[0]; itkPoint[1] = point[1]; itkPoint[2] = point[2]; pointSet->InsertPoint(count, itkPoint); count++; } if (numPoints>2) { double* point = fiberPolyData->GetPoint(points[numPoints-1]); itk::Point itkPoint; itkPoint[0] = point[0]; itkPoint[1] = point[1]; itkPoint[2] = point[2]; pointSet->InsertPoint(count, itkPoint); count++; } } mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData( pointSet ); return node; } // generate image displaying the fiber endings mitk::DataNode::Pointer QmitkFiberQuantificationView::GenerateFiberEndingsImage(mitk::FiberBundleX::Pointer fib) { typedef unsigned char OutPixType; typedef itk::Image OutImageType; typedef itk::TractsToFiberEndingsImageFilter< OutImageType > ImageGeneratorType; ImageGeneratorType::Pointer generator = ImageGeneratorType::New(); generator->SetFiberBundle(fib); generator->SetUpsamplingFactor(m_Controls->m_UpsamplingSpinBox->value()); if (m_SelectedImage.IsNotNull()) { OutImageType::Pointer itkImage = OutImageType::New(); CastToItkImage(m_SelectedImage, itkImage); generator->SetInputImage(itkImage); generator->SetUseImageGeometry(true); } generator->Update(); // get output image OutImageType::Pointer outImg = generator->GetOutput(); mitk::Image::Pointer img = mitk::Image::New(); img->InitializeByItk(outImg.GetPointer()); img->SetVolume(outImg->GetBufferPointer()); // init data node mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(img); return node; } // generate rgba heatmap from fiber bundle mitk::DataNode::Pointer QmitkFiberQuantificationView::GenerateColorHeatmap(mitk::FiberBundleX::Pointer fib) { typedef itk::RGBAPixel OutPixType; typedef itk::Image OutImageType; typedef itk::TractsToRgbaImageFilter< OutImageType > ImageGeneratorType; ImageGeneratorType::Pointer generator = ImageGeneratorType::New(); generator->SetFiberBundle(fib); generator->SetUpsamplingFactor(m_Controls->m_UpsamplingSpinBox->value()); if (m_SelectedImage.IsNotNull()) { itk::Image::Pointer itkImage = itk::Image::New(); CastToItkImage(m_SelectedImage, itkImage); generator->SetInputImage(itkImage); generator->SetUseImageGeometry(true); } generator->Update(); // get output image typedef itk::Image OutType; OutType::Pointer outImg = generator->GetOutput(); mitk::Image::Pointer img = mitk::Image::New(); img->InitializeByItk(outImg.GetPointer()); img->SetVolume(outImg->GetBufferPointer()); // init data node mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(img); return node; } // generate tract density image from fiber bundle mitk::DataNode::Pointer QmitkFiberQuantificationView::GenerateTractDensityImage(mitk::FiberBundleX::Pointer fib, bool binary, bool absolute) { typedef float OutPixType; typedef itk::Image OutImageType; + std::vector< mitk::FiberBundleX::Pointer > fibs; + for (int i=0; i(m_SelectedFB.at(i)->GetData()); + fibs.push_back(fib); + } + itk::TractDensityImageFilter< OutImageType >::Pointer generator = itk::TractDensityImageFilter< OutImageType >::New(); - generator->SetFiberBundle(fib); + generator->fibs = fibs; +// generator->SetFiberBundle(fib); generator->SetBinaryOutput(binary); generator->SetOutputAbsoluteValues(absolute); generator->SetUpsamplingFactor(m_Controls->m_UpsamplingSpinBox->value()); if (m_SelectedImage.IsNotNull()) { OutImageType::Pointer itkImage = OutImageType::New(); CastToItkImage(m_SelectedImage, itkImage); generator->SetInputImage(itkImage); generator->SetUseImageGeometry(true); } generator->Update(); // get output image typedef itk::Image OutType; OutType::Pointer outImg = generator->GetOutput(); mitk::Image::Pointer img = mitk::Image::New(); img->InitializeByItk(outImg.GetPointer()); img->SetVolume(outImg->GetBufferPointer()); // init data node mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(img); return node; } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.cpp index d8dc877eaf..d7019ce8fa 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.cpp @@ -1,1872 +1,2020 @@ /*=================================================================== 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. ===================================================================*/ //#define MBILOG_ENABLE_DEBUG #include "QmitkPreprocessingView.h" #include "mitkDiffusionImagingConfigure.h" // qt includes #include // itk includes #include "itkTimeProbe.h" #include "itkB0ImageExtractionImageFilter.h" #include "itkB0ImageExtractionToSeparateImageFilter.h" #include "itkBrainMaskExtractionImageFilter.h" #include "itkCastImageFilter.h" #include "itkVectorContainer.h" #include #include #include #include // Multishell includes #include // Multishell Functors #include #include #include #include // mitk includes #include "QmitkDataStorageComboBox.h" #include "QmitkStdMultiWidget.h" #include "mitkProgressBar.h" #include "mitkStatusBar.h" #include "mitkNodePredicateDataType.h" #include "mitkProperties.h" #include "mitkVtkResliceInterpolationProperty.h" #include "mitkLookupTable.h" #include "mitkLookupTableProperty.h" #include "mitkTransferFunction.h" #include "mitkTransferFunctionProperty.h" #include "mitkDataNodeObject.h" #include "mitkOdfNormalizationMethodProperty.h" #include "mitkOdfScaleByProperty.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 const std::string QmitkPreprocessingView::VIEW_ID = "org.mitk.views.preprocessing"; #define DI_INFO MITK_INFO("DiffusionImaging") typedef float TTensorPixelType; QmitkPreprocessingView::QmitkPreprocessingView() : QmitkFunctionality(), m_Controls(NULL), m_MultiWidget(NULL) { } QmitkPreprocessingView::~QmitkPreprocessingView() { } void QmitkPreprocessingView::CreateQtPartControl(QWidget *parent) { if (!m_Controls) { // create GUI widgets m_Controls = new Ui::QmitkPreprocessingViewControls; m_Controls->setupUi(parent); this->CreateConnections(); #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) m_Controls->m_MeasurementFrameTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch); m_Controls->m_MeasurementFrameTable->verticalHeader()->setResizeMode(QHeaderView::Stretch); m_Controls->m_DirectionMatrixTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch); m_Controls->m_DirectionMatrixTable->verticalHeader()->setResizeMode(QHeaderView::Stretch); #else m_Controls->m_MeasurementFrameTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); m_Controls->m_MeasurementFrameTable->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch); m_Controls->m_DirectionMatrixTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); m_Controls->m_DirectionMatrixTable->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch); #endif } } void QmitkPreprocessingView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkPreprocessingView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } void QmitkPreprocessingView::CreateConnections() { if ( m_Controls ) { m_Controls->m_NormalizationMaskBox->SetDataStorage(this->GetDataStorage()); + m_Controls->m_SelctedImageComboBox->SetDataStorage(this->GetDataStorage()); + m_Controls->m_MergeDwiBox->SetDataStorage(this->GetDataStorage()); + mitk::TNodePredicateDataType::Pointer isMitkImage = mitk::TNodePredicateDataType::New(); mitk::NodePredicateDataType::Pointer isDwi = mitk::NodePredicateDataType::New("DiffusionImage"); mitk::NodePredicateDataType::Pointer isDti = mitk::NodePredicateDataType::New("TensorImage"); mitk::NodePredicateDataType::Pointer isQbi = mitk::NodePredicateDataType::New("QBallImage"); mitk::NodePredicateOr::Pointer isDiffusionImage = mitk::NodePredicateOr::New(isDwi, isDti); isDiffusionImage = mitk::NodePredicateOr::New(isDiffusionImage, isQbi); + mitk::NodePredicateNot::Pointer noDiffusionImage = mitk::NodePredicateNot::New(isDiffusionImage); mitk::NodePredicateAnd::Pointer finalPredicate = mitk::NodePredicateAnd::New(isMitkImage, noDiffusionImage); mitk::NodePredicateProperty::Pointer isBinaryPredicate = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); finalPredicate = mitk::NodePredicateAnd::New(finalPredicate, isBinaryPredicate); m_Controls->m_NormalizationMaskBox->SetPredicate(finalPredicate); + m_Controls->m_SelctedImageComboBox->SetPredicate(isMitkImage); + m_Controls->m_MergeDwiBox->SetPredicate(isMitkImage); m_Controls->m_ExtractBrainMask->setVisible(false); m_Controls->m_BrainMaskIterationsBox->setVisible(false); m_Controls->m_ResampleIntFrame->setVisible(false); connect( (QObject*)(m_Controls->m_ButtonAverageGradients), SIGNAL(clicked()), this, SLOT(AverageGradients()) ); connect( (QObject*)(m_Controls->m_ButtonExtractB0), SIGNAL(clicked()), this, SLOT(ExtractB0()) ); connect( (QObject*)(m_Controls->m_ModifyMeasurementFrame), SIGNAL(clicked()), this, SLOT(DoApplyMesurementFrame()) ); connect( (QObject*)(m_Controls->m_ReduceGradientsButton), SIGNAL(clicked()), this, SLOT(DoReduceGradientDirections()) ); connect( (QObject*)(m_Controls->m_ShowGradientsButton), SIGNAL(clicked()), this, SLOT(DoShowGradientDirections()) ); connect( (QObject*)(m_Controls->m_MirrorGradientToHalfSphereButton), SIGNAL(clicked()), this, SLOT(DoHalfSphereGradientDirections()) ); connect( (QObject*)(m_Controls->m_MergeDwisButton), SIGNAL(clicked()), this, SLOT(MergeDwis()) ); connect( (QObject*)(m_Controls->m_ProjectSignalButton), SIGNAL(clicked()), this, SLOT(DoProjectSignal()) ); connect( (QObject*)(m_Controls->m_B_ValueMap_Rounder_SpinBox), SIGNAL(valueChanged(int)), this, SLOT(UpdateDwiBValueMapRounder(int))); connect( (QObject*)(m_Controls->m_CreateLengthCorrectedDwi), SIGNAL(clicked()), this, SLOT(DoLengthCorrection()) ); connect( (QObject*)(m_Controls->m_CalcAdcButton), SIGNAL(clicked()), this, SLOT(DoAdcCalculation()) ); connect( (QObject*)(m_Controls->m_NormalizeImageValuesButton), SIGNAL(clicked()), this, SLOT(DoDwiNormalization()) ); connect( (QObject*)(m_Controls->m_ModifyDirection), SIGNAL(clicked()), this, SLOT(DoApplyDirectionMatrix()) ); connect( (QObject*)(m_Controls->m_ModifySpacingButton), SIGNAL(clicked()), this, SLOT(DoApplySpacing()) ); connect( (QObject*)(m_Controls->m_ModifyOriginButton), SIGNAL(clicked()), this, SLOT(DoApplyOrigin()) ); connect( (QObject*)(m_Controls->m_ResampleImageButton), SIGNAL(clicked()), this, SLOT(DoResampleImage()) ); connect( (QObject*)(m_Controls->m_ResampleTypeBox), SIGNAL(currentIndexChanged(int)), this, SLOT(DoUpdateInterpolationGui(int)) ); connect( (QObject*)(m_Controls->m_CropImageButton), SIGNAL(clicked()), this, SLOT(DoCropImage()) ); connect( (QObject*)(m_Controls->m_RemoveGradientButton), SIGNAL(clicked()), this, SLOT(DoRemoveGradient()) ); connect( (QObject*)(m_Controls->m_ExtractGradientButton), SIGNAL(clicked()), this, SLOT(DoExtractGradient()) ); - + connect( (QObject*)(m_Controls->m_FlipAxis), SIGNAL(clicked()), this, SLOT(DoFlipAxis()) ); + connect( (QObject*)(m_Controls->m_SelctedImageComboBox), SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnImageSelectionChanged()) ); // connect( (QObject*)(m_Controls->m_ExtractBrainMask), SIGNAL(clicked()), this, SLOT(DoExtractBrainMask()) ); } } +void QmitkPreprocessingView::DoFlipAxis() +{ + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); + + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(node) ); + + if (isDiffusionImage) + { + ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); + mitk::CastToItkImage(image, itkVectorImagePointer); + + itk::FixedArray flipAxes; + flipAxes[0] = m_Controls->m_FlipX->isChecked(); + flipAxes[1] = m_Controls->m_FlipY->isChecked(); + flipAxes[2] = m_Controls->m_FlipZ->isChecked(); + + itk::FlipImageFilter< ItkDwiType >::Pointer flipper = itk::FlipImageFilter< ItkDwiType >::New(); + flipper->SetInput(itkVectorImagePointer); + flipper->SetFlipAxes(flipAxes); + flipper->Update(); + + mitk::Image::Pointer newImage = mitk::GrabItkImageMemory( flipper->GetOutput() ); + newImage->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( static_cast( image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ) ); + newImage->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ) ); + newImage->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer() )->GetMeasurementFrame() ) ); + mitk::DiffusionPropertyHelper propertyHelper( newImage ); + propertyHelper.InitializeImage(); + newImage->GetGeometry()->SetOrigin(image->GetGeometry()->GetOrigin()); + + mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); + imageNode->SetData( newImage ); + QString name = node->GetName().c_str(); + + imageNode->SetName((name+"_flipped").toStdString().c_str()); + GetDefaultDataStorage()->Add(imageNode, node); + + mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + } + else + AccessFixedDimensionByItk(image, TemplatedFlipAxis,3); +} + + +template < typename TPixel, unsigned int VImageDimension > +void QmitkPreprocessingView::TemplatedFlipAxis(itk::Image* itkImage) +{ + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); + + itk::FixedArray flipAxes; + flipAxes[0] = m_Controls->m_FlipX->isChecked(); + flipAxes[1] = m_Controls->m_FlipY->isChecked(); + flipAxes[2] = m_Controls->m_FlipZ->isChecked(); + + typename itk::FlipImageFilter< itk::Image >::Pointer flipper = itk::FlipImageFilter< itk::Image >::New(); + flipper->SetInput(itkImage); + flipper->SetFlipAxes(flipAxes); + flipper->Update(); + + mitk::Image::Pointer newImage = mitk::GrabItkImageMemory( flipper->GetOutput() ); + newImage->GetGeometry()->SetOrigin(image->GetGeometry()->GetOrigin()); + + mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); + imageNode->SetData( newImage ); + QString name = node->GetName().c_str(); + + imageNode->SetName((name+"_flipped").toStdString().c_str()); + GetDefaultDataStorage()->Add(imageNode, node); + + mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); +} + void QmitkPreprocessingView::DoRemoveGradient() { - bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast(m_SelectedImageNode->GetData())) ); + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); + + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); if ( !isDiffusionImage ) { return; } std::vector< unsigned int > channelsToRemove; channelsToRemove.push_back(m_Controls->m_RemoveGradientBox->value()); ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); - mitk::CastToItkImage(m_SelectedImage, itkVectorImagePointer); + mitk::CastToItkImage(image, itkVectorImagePointer); itk::RemoveDwiChannelFilter< short >::Pointer filter = itk::RemoveDwiChannelFilter< short >::New(); filter->SetInput(itkVectorImagePointer); filter->SetChannelIndices(channelsToRemove); - filter->SetDirections( static_cast( m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ); + filter->SetDirections( static_cast( image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ); filter->Update(); - mitk::Image::Pointer image = mitk::GrabItkImageMemory( filter->GetOutput() ); - image->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( filter->GetNewDirections() ) ); - image->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ) ); - image->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer() )->GetMeasurementFrame() ) ); - mitk::DiffusionPropertyHelper propertyHelper( image ); + mitk::Image::Pointer newImage = mitk::GrabItkImageMemory( filter->GetOutput() ); + newImage->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( filter->GetNewDirections() ) ); + newImage->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ) ); + newImage->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer() )->GetMeasurementFrame() ) ); + mitk::DiffusionPropertyHelper propertyHelper( newImage ); propertyHelper.InitializeImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); - imageNode->SetData( image ); - QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); + imageNode->SetData( newImage ); + QString name = node->GetName().c_str(); imageNode->SetName((name+"_removedgradients").toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); + GetDefaultDataStorage()->Add(imageNode, node); mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkPreprocessingView::DoExtractGradient() { - bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast(m_SelectedImageNode->GetData())) ); + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); + + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); if ( !isDiffusionImage ) { return; } ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); - mitk::CastToItkImage(m_SelectedImage, itkVectorImagePointer); + mitk::CastToItkImage(image, itkVectorImagePointer); unsigned int channel = m_Controls->m_ExtractGradientBox->value(); itk::ExtractDwiChannelFilter< short >::Pointer filter = itk::ExtractDwiChannelFilter< short >::New(); filter->SetInput( itkVectorImagePointer); filter->SetChannelIndex(channel); filter->Update(); - mitk::Image::Pointer mitkImage = mitk::Image::New(); - mitkImage->InitializeByItk( filter->GetOutput() ); - mitkImage->SetImportChannel( filter->GetOutput()->GetBufferPointer() ); + mitk::Image::Pointer newImage = mitk::Image::New(); + newImage->InitializeByItk( filter->GetOutput() ); + newImage->SetImportChannel( filter->GetOutput()->GetBufferPointer() ); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); - imageNode->SetData( mitkImage ); - QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); + imageNode->SetData( newImage ); + QString name = node->GetName().c_str(); imageNode->SetName((name+"_direction-"+QString::number(channel)).toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); + GetDefaultDataStorage()->Add(imageNode, node); mitk::RenderingManager::GetInstance()->InitializeViews(imageNode->GetData()->GetTimeGeometry(),mitk::RenderingManager::REQUEST_UPDATE_ALL, true); } void QmitkPreprocessingView::DoCropImage() { - bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast(m_SelectedImageNode->GetData())) ); + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); + + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); if ( isDiffusionImage ) { ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); - mitk::CastToItkImage(m_SelectedImage, itkVectorImagePointer); + mitk::CastToItkImage(image, itkVectorImagePointer); ItkDwiType::SizeType lower; ItkDwiType::SizeType upper; lower[0] = m_Controls->m_XstartBox->value(); lower[1] = m_Controls->m_YstartBox->value(); lower[2] = m_Controls->m_ZstartBox->value(); upper[0] = m_Controls->m_XendBox->value(); upper[1] = m_Controls->m_YendBox->value(); upper[2] = m_Controls->m_ZendBox->value(); itk::CropImageFilter< ItkDwiType, ItkDwiType >::Pointer cropper = itk::CropImageFilter< ItkDwiType, ItkDwiType >::New(); cropper->SetLowerBoundaryCropSize(lower); cropper->SetUpperBoundaryCropSize(upper); cropper->SetInput( itkVectorImagePointer ); cropper->Update(); mitk::Image::Pointer image = mitk::GrabItkImageMemory( cropper->GetOutput() ); - image->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( static_cast( m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ) ); - image->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ) ); - image->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer() )->GetMeasurementFrame() ) ); + image->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( static_cast( image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ) ); + image->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ) ); + image->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer() )->GetMeasurementFrame() ) ); mitk::DiffusionPropertyHelper propertyHelper( image ); propertyHelper.InitializeImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); - QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); + QString name = node->GetName().c_str(); imageNode->SetName((name+"_cropped").toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); + GetDefaultDataStorage()->Add(imageNode, node); mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } - else if(m_SelectedImage.IsNotNull()) + else { - AccessFixedDimensionByItk(m_SelectedImage, TemplatedCropImage,3); + AccessFixedDimensionByItk(image, TemplatedCropImage,3); } } template < typename TPixel, unsigned int VImageDimension > void QmitkPreprocessingView::TemplatedCropImage( itk::Image* itkImage) { + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + ItkDwiType::SizeType lower; ItkDwiType::SizeType upper; lower[0] = m_Controls->m_XstartBox->value(); lower[1] = m_Controls->m_YstartBox->value(); lower[2] = m_Controls->m_ZstartBox->value(); upper[0] = m_Controls->m_XendBox->value(); upper[1] = m_Controls->m_YendBox->value(); upper[2] = m_Controls->m_ZendBox->value(); typedef itk::Image ImageType; typename itk::CropImageFilter< ImageType, ImageType >::Pointer cropper = itk::CropImageFilter< ImageType, ImageType >::New(); cropper->SetLowerBoundaryCropSize(lower); cropper->SetUpperBoundaryCropSize(upper); cropper->SetInput(itkImage); cropper->Update(); + typename ImageType::Pointer itkOutImage = cropper->GetOutput(); + itk::Point origin = itkOutImage->GetOrigin(); + origin[0] += lower[0]*itkOutImage->GetSpacing()[0]; + origin[1] += lower[1]*itkOutImage->GetSpacing()[1]; + origin[2] += lower[2]*itkOutImage->GetSpacing()[2]; + itkOutImage->SetOrigin(origin); mitk::Image::Pointer image = mitk::Image::New(); - image->InitializeByItk( cropper->GetOutput() ); - image->SetVolume( cropper->GetOutput()->GetBufferPointer() ); + image->InitializeByItk( itkOutImage.GetPointer() ); + image->SetVolume( itkOutImage->GetBufferPointer() ); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); - QString name = m_SelectedImageNode->GetName().c_str(); + QString name = node->GetName().c_str(); imageNode->SetName((name+"_cropped").toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode, m_SelectedImageNode); + GetDefaultDataStorage()->Add(imageNode, node); mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkPreprocessingView::DoApplySpacing() { - bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( m_SelectedImageNode) ); + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); + + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); if ( isDiffusionImage ) { mitk::Vector3D spacing; spacing[0] = m_Controls->m_HeaderSpacingX->value(); spacing[1] = m_Controls->m_HeaderSpacingY->value(); spacing[2] = m_Controls->m_HeaderSpacingZ->value(); - mitk::Image::Pointer image = m_SelectedImage->Clone(); - image->GetGeometry()->SetSpacing( spacing ); - mitk::DiffusionPropertyHelper propertyHelper( image ); + mitk::Image::Pointer newImage = image->Clone(); + newImage->GetGeometry()->SetSpacing( spacing ); + mitk::DiffusionPropertyHelper propertyHelper( newImage ); propertyHelper.InitializeImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); - imageNode->SetData( image ); - QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); + imageNode->SetData( newImage ); + QString name = node->GetName().c_str(); imageNode->SetName((name+"_newspacing").toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); + GetDefaultDataStorage()->Add(imageNode, node); mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } - else if(m_SelectedImage.IsNotNull()) + else { - AccessFixedDimensionByItk(m_SelectedImage, TemplatedSetImageSpacing,3); + AccessFixedDimensionByItk(image, TemplatedSetImageSpacing,3); } } template < typename TPixel, unsigned int VImageDimension > void QmitkPreprocessingView::TemplatedSetImageSpacing( itk::Image* itkImage) { + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Vector3D spacing; spacing[0] = m_Controls->m_HeaderSpacingX->value(); spacing[1] = m_Controls->m_HeaderSpacingY->value(); spacing[2] = m_Controls->m_HeaderSpacingZ->value(); typedef itk::ImageDuplicator< itk::Image > DuplicateFilterType; typename DuplicateFilterType::Pointer duplicator = DuplicateFilterType::New(); duplicator->SetInputImage( itkImage ); duplicator->Update(); typename itk::Image::Pointer newImage = duplicator->GetOutput(); newImage->SetSpacing(spacing); mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk( newImage.GetPointer() ); image->SetVolume( newImage->GetBufferPointer() ); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); - QString name = m_SelectedImageNode->GetName().c_str(); + QString name = node->GetName().c_str(); imageNode->SetName((name+"_newspacing").toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode, m_SelectedImageNode); + GetDefaultDataStorage()->Add(imageNode, node); mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkPreprocessingView::DoApplyOrigin() { - bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast(m_SelectedImageNode->GetData())) ); + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); + + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image)); if ( isDiffusionImage ) { mitk::Vector3D origin; origin[0] = m_Controls->m_HeaderOriginX->value(); origin[1] = m_Controls->m_HeaderOriginY->value(); origin[2] = m_Controls->m_HeaderOriginZ->value(); - mitk::Image::Pointer image = m_SelectedImage->Clone(); + mitk::Image::Pointer newImage = image->Clone(); - image->GetGeometry()->SetOrigin( origin ); - mitk::DiffusionPropertyHelper propertyHelper( image ); + newImage->GetGeometry()->SetOrigin( origin ); + mitk::DiffusionPropertyHelper propertyHelper( newImage ); propertyHelper.InitializeImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); - imageNode->SetData( image ); - QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); + imageNode->SetData( newImage ); + QString name = node->GetName().c_str(); imageNode->SetName((name+"_neworigin").toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); + GetDefaultDataStorage()->Add(imageNode, node); mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } - else if(m_SelectedImage.IsNotNull()) + else { - AccessFixedDimensionByItk(m_SelectedImage, TemplatedSetImageOrigin,3); + AccessFixedDimensionByItk(image, TemplatedSetImageOrigin,3); } } template < typename TPixel, unsigned int VImageDimension > void QmitkPreprocessingView::TemplatedSetImageOrigin( itk::Image* itkImage) { + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Vector3D origin; origin[0] = m_Controls->m_HeaderOriginX->value(); origin[1] = m_Controls->m_HeaderOriginY->value(); origin[2] = m_Controls->m_HeaderOriginZ->value(); typedef itk::ImageDuplicator< itk::Image > DuplicateFilterType; typename DuplicateFilterType::Pointer duplicator = DuplicateFilterType::New(); duplicator->SetInputImage( itkImage ); duplicator->Update(); typename itk::Image::Pointer newImage = duplicator->GetOutput(); newImage->SetOrigin(origin); mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk( newImage.GetPointer() ); image->SetVolume( newImage->GetBufferPointer() ); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); - QString name = m_SelectedImageNode->GetName().c_str(); + QString name = node->GetName().c_str(); imageNode->SetName((name+"_neworigin").toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode, m_SelectedImageNode); + GetDefaultDataStorage()->Add(imageNode, node); mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkPreprocessingView::DoUpdateInterpolationGui(int i) { + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); + switch (i) { case 0: { m_Controls->m_ResampleIntFrame->setVisible(false); m_Controls->m_ResampleDoubleFrame->setVisible(true); break; } case 1: { m_Controls->m_ResampleIntFrame->setVisible(false); m_Controls->m_ResampleDoubleFrame->setVisible(true); - if (m_SelectedImage.IsNotNull()) - { - mitk::BaseGeometry* geom = m_SelectedImage->GetGeometry(); - m_Controls->m_ResampleDoubleX->setValue(geom->GetSpacing()[0]); - m_Controls->m_ResampleDoubleY->setValue(geom->GetSpacing()[1]); - m_Controls->m_ResampleDoubleZ->setValue(geom->GetSpacing()[2]); - } + mitk::BaseGeometry* geom = image->GetGeometry(); + m_Controls->m_ResampleDoubleX->setValue(geom->GetSpacing()[0]); + m_Controls->m_ResampleDoubleY->setValue(geom->GetSpacing()[1]); + m_Controls->m_ResampleDoubleZ->setValue(geom->GetSpacing()[2]); break; } case 2: { m_Controls->m_ResampleIntFrame->setVisible(true); m_Controls->m_ResampleDoubleFrame->setVisible(false); - if (m_SelectedImage.IsNotNull()) - { - mitk::BaseGeometry* geom = m_SelectedImage->GetGeometry(); - m_Controls->m_ResampleIntX->setValue(geom->GetExtent(0)); - m_Controls->m_ResampleIntY->setValue(geom->GetExtent(1)); - m_Controls->m_ResampleIntZ->setValue(geom->GetExtent(2)); - } + mitk::BaseGeometry* geom = image->GetGeometry(); + m_Controls->m_ResampleIntX->setValue(geom->GetExtent(0)); + m_Controls->m_ResampleIntY->setValue(geom->GetExtent(1)); + m_Controls->m_ResampleIntZ->setValue(geom->GetExtent(2)); break; } default: { m_Controls->m_ResampleIntFrame->setVisible(false); m_Controls->m_ResampleDoubleFrame->setVisible(true); } } } void QmitkPreprocessingView::DoExtractBrainMask() { - // if (m_SelectedImage.IsNull()) + // if (image.IsNull()) // return; // typedef itk::Image ShortImageType; // ShortImageType::Pointer itkImage = ShortImageType::New(); - // mitk::CastToItkImage(m_SelectedImage, itkImage); + // mitk::CastToItkImage(image, itkImage); // typedef itk::BrainMaskExtractionImageFilter< unsigned char > FilterType; // FilterType::Pointer filter = FilterType::New(); // filter->SetInput(itkImage); // filter->SetMaxNumIterations(m_Controls->m_BrainMaskIterationsBox->value()); // filter->Update(); // mitk::Image::Pointer image = mitk::Image::New(); // image->InitializeByItk( filter->GetOutput() ); // image->SetVolume( filter->GetOutput()->GetBufferPointer() ); // mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); // imageNode->SetData( image ); // imageNode->SetName("BRAINMASK"); // GetDefaultDataStorage()->Add(imageNode); } void QmitkPreprocessingView::DoResampleImage() { - bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast(m_SelectedImageNode->GetData())) ); + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); + + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); if ( isDiffusionImage ) { ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); - mitk::CastToItkImage(m_SelectedImage, itkVectorImagePointer); + mitk::CastToItkImage(image, itkVectorImagePointer); typedef itk::ResampleDwiImageFilter< short > ResampleFilter; ResampleFilter::Pointer resampler = ResampleFilter::New(); resampler->SetInput( itkVectorImagePointer ); switch (m_Controls->m_ResampleTypeBox->currentIndex()) { case 0: { itk::Vector< double, 3 > samplingFactor; samplingFactor[0] = m_Controls->m_ResampleDoubleX->value(); samplingFactor[1] = m_Controls->m_ResampleDoubleY->value(); samplingFactor[2] = m_Controls->m_ResampleDoubleZ->value(); resampler->SetSamplingFactor(samplingFactor); break; } case 1: { itk::Vector< double, 3 > newSpacing; newSpacing[0] = m_Controls->m_ResampleDoubleX->value(); newSpacing[1] = m_Controls->m_ResampleDoubleY->value(); newSpacing[2] = m_Controls->m_ResampleDoubleZ->value(); resampler->SetNewSpacing(newSpacing); break; } case 2: { itk::ImageRegion<3> newRegion; newRegion.SetSize(0, m_Controls->m_ResampleIntX->value()); newRegion.SetSize(1, m_Controls->m_ResampleIntY->value()); newRegion.SetSize(2, m_Controls->m_ResampleIntZ->value()); resampler->SetNewImageSize(newRegion); break; } default: { MITK_WARN << "Unknown resampling parameters!"; return; } } QString outAdd; switch (m_Controls->m_InterpolatorBox->currentIndex()) { case 0: { resampler->SetInterpolation(ResampleFilter::Interpolate_NearestNeighbour); outAdd = "NearestNeighbour"; break; } case 1: { resampler->SetInterpolation(ResampleFilter::Interpolate_Linear); outAdd = "Linear"; break; } case 2: { resampler->SetInterpolation(ResampleFilter::Interpolate_BSpline); outAdd = "BSpline"; break; } case 3: { resampler->SetInterpolation(ResampleFilter::Interpolate_WindowedSinc); outAdd = "WindowedSinc"; break; } default: { resampler->SetInterpolation(ResampleFilter::Interpolate_NearestNeighbour); outAdd = "NearestNeighbour"; } } resampler->Update(); - mitk::Image::Pointer image = mitk::GrabItkImageMemory( resampler->GetOutput() ); - image->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( static_cast( m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ) ); - image->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ) ); - image->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer() )->GetMeasurementFrame() ) ); - mitk::DiffusionPropertyHelper propertyHelper( image ); + mitk::Image::Pointer newImage = mitk::GrabItkImageMemory( resampler->GetOutput() ); + newImage->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( static_cast( image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ) ); + newImage->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ) ); + newImage->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer() )->GetMeasurementFrame() ) ); + mitk::DiffusionPropertyHelper propertyHelper( newImage ); propertyHelper.InitializeImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); - imageNode->SetData( image ); - QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); + imageNode->SetData( newImage ); + QString name = node->GetName().c_str(); imageNode->SetName((name+"_resampled_"+outAdd).toStdString().c_str()); imageNode->SetVisibility(false); - GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); + GetDefaultDataStorage()->Add(imageNode, node); } - else if (m_SelectedImage.IsNotNull()) + else { - AccessFixedDimensionByItk(m_SelectedImage, TemplatedResampleImage,3); + AccessFixedDimensionByItk(image, TemplatedResampleImage,3); } } template < typename TPixel, unsigned int VImageDimension > void QmitkPreprocessingView::TemplatedResampleImage( itk::Image* itkImage) { + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + itk::Vector< double, 3 > newSpacing; itk::ImageRegion<3> newRegion; switch (m_Controls->m_ResampleTypeBox->currentIndex()) { case 0: { itk::Vector< double, 3 > sampling; sampling[0] = m_Controls->m_ResampleDoubleX->value(); sampling[1] = m_Controls->m_ResampleDoubleY->value(); sampling[2] = m_Controls->m_ResampleDoubleZ->value(); newSpacing = itkImage->GetSpacing(); newSpacing[0] /= sampling[0]; newSpacing[1] /= sampling[1]; newSpacing[2] /= sampling[2]; newRegion = itkImage->GetLargestPossibleRegion(); newRegion.SetSize(0, newRegion.GetSize(0)*sampling[0]); newRegion.SetSize(1, newRegion.GetSize(1)*sampling[1]); newRegion.SetSize(2, newRegion.GetSize(2)*sampling[2]); break; } case 1: { newSpacing[0] = m_Controls->m_ResampleDoubleX->value(); newSpacing[1] = m_Controls->m_ResampleDoubleY->value(); newSpacing[2] = m_Controls->m_ResampleDoubleZ->value(); itk::Vector< double, 3 > oldSpacing = itkImage->GetSpacing(); itk::Vector< double, 3 > sampling; sampling[0] = oldSpacing[0]/newSpacing[0]; sampling[1] = oldSpacing[1]/newSpacing[1]; sampling[2] = oldSpacing[2]/newSpacing[2]; newRegion = itkImage->GetLargestPossibleRegion(); newRegion.SetSize(0, newRegion.GetSize(0)*sampling[0]); newRegion.SetSize(1, newRegion.GetSize(1)*sampling[1]); newRegion.SetSize(2, newRegion.GetSize(2)*sampling[2]); break; } case 2: { newRegion.SetSize(0, m_Controls->m_ResampleIntX->value()); newRegion.SetSize(1, m_Controls->m_ResampleIntY->value()); newRegion.SetSize(2, m_Controls->m_ResampleIntZ->value()); itk::ImageRegion<3> oldRegion = itkImage->GetLargestPossibleRegion(); itk::Vector< double, 3 > sampling; sampling[0] = (double)newRegion.GetSize(0)/oldRegion.GetSize(0); sampling[1] = (double)newRegion.GetSize(1)/oldRegion.GetSize(1); sampling[2] = (double)newRegion.GetSize(2)/oldRegion.GetSize(2); newSpacing = itkImage->GetSpacing(); newSpacing[0] /= sampling[0]; newSpacing[1] /= sampling[1]; newSpacing[2] /= sampling[2]; break; } default: { MITK_WARN << "Unknown resampling parameters!"; return; } } itk::Point origin = itkImage->GetOrigin(); origin[0] -= itkImage->GetSpacing()[0]/2; origin[1] -= itkImage->GetSpacing()[1]/2; origin[2] -= itkImage->GetSpacing()[2]/2; origin[0] += newSpacing[0]/2; origin[1] += newSpacing[1]/2; origin[2] += newSpacing[2]/2; typedef itk::Image ImageType; typename ImageType::Pointer outImage = ImageType::New(); outImage->SetSpacing( newSpacing ); outImage->SetOrigin( origin ); outImage->SetDirection( itkImage->GetDirection() ); outImage->SetLargestPossibleRegion( newRegion ); outImage->SetBufferedRegion( newRegion ); outImage->SetRequestedRegion( newRegion ); outImage->Allocate(); typedef itk::ResampleImageFilter ResampleFilter; typename ResampleFilter::Pointer resampler = ResampleFilter::New(); resampler->SetInput(itkImage); resampler->SetOutputParametersFromImage(outImage); QString outAdd; switch (m_Controls->m_InterpolatorBox->currentIndex()) { case 0: { typename itk::NearestNeighborInterpolateImageFunction::Pointer interp = itk::NearestNeighborInterpolateImageFunction::New(); resampler->SetInterpolator(interp); outAdd = "NearestNeighbour"; break; } case 1: { typename itk::LinearInterpolateImageFunction::Pointer interp = itk::LinearInterpolateImageFunction::New(); resampler->SetInterpolator(interp); outAdd = "Linear"; break; } case 2: { typename itk::BSplineInterpolateImageFunction::Pointer interp = itk::BSplineInterpolateImageFunction::New(); resampler->SetInterpolator(interp); outAdd = "BSpline"; break; } case 3: { typename itk::WindowedSincInterpolateImageFunction::Pointer interp = itk::WindowedSincInterpolateImageFunction::New(); resampler->SetInterpolator(interp); outAdd = "WindowedSinc"; break; } default: { typename itk::NearestNeighborInterpolateImageFunction::Pointer interp = itk::NearestNeighborInterpolateImageFunction::New(); resampler->SetInterpolator(interp); outAdd = "NearestNeighbour"; } } resampler->Update(); mitk::Image::Pointer image = mitk::Image::New(); image->InitializeByItk( resampler->GetOutput() ); image->SetVolume( resampler->GetOutput()->GetBufferPointer() ); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); - QString name = m_SelectedImageNode->GetName().c_str(); + QString name = node->GetName().c_str(); imageNode->SetName((name+"_resampled_"+outAdd).toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode, m_SelectedImageNode); + GetDefaultDataStorage()->Add(imageNode, node); } void QmitkPreprocessingView::DoApplyDirectionMatrix() { - bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast(m_SelectedImageNode->GetData())) ); + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); + + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); if ( isDiffusionImage ) { ItkDwiType::DirectionType newDirection; for (int r=0; r<3; r++) { for (int c=0; c<3; c++) { QTableWidgetItem* item = m_Controls->m_DirectionMatrixTable->item(r,c); if (!item) return; newDirection[r][c] = item->text().toDouble(); } } ItkDwiType::Pointer itkDwi = ItkDwiType::New(); - mitk::CastToItkImage(m_SelectedImage, itkDwi); + mitk::CastToItkImage(image, itkDwi); itk::ImageDuplicator::Pointer duplicator = itk::ImageDuplicator::New(); duplicator->SetInputImage(itkDwi); duplicator->Update(); itkDwi = duplicator->GetOutput(); vnl_matrix_fixed< double,3,3 > oldInverseDirection = itkDwi->GetDirection().GetInverse(); - mitk::GradientDirectionsProperty::GradientDirectionsContainerType::Pointer oldGradients = static_cast( m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer(); + mitk::GradientDirectionsProperty::GradientDirectionsContainerType::Pointer oldGradients = static_cast( image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer(); mitk::GradientDirectionsProperty::GradientDirectionsContainerType::Pointer newGradients = mitk::GradientDirectionsProperty::GradientDirectionsContainerType::New(); for (unsigned int i=0; iSize(); i++) { mitk::GradientDirectionsProperty::GradientDirectionType g = oldGradients->GetElement(i); double mag = g.magnitude(); g.normalize(); mitk::GradientDirectionsProperty::GradientDirectionType newG = oldInverseDirection*g; newG = newDirection.GetVnlMatrix()*newG; newG.normalize(); newGradients->InsertElement(i, newG*mag); } itkDwi->SetDirection(newDirection); mitk::Image::Pointer newDwi2 = mitk::GrabItkImageMemory( itkDwi.GetPointer() ); newDwi2->SetProperty( mitk::DiffusionPropertyHelper::ORIGINALGRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( newGradients ) ); - newDwi2->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ) ); - newDwi2->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer() )->GetMeasurementFrame() ) ); + newDwi2->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ) ); + newDwi2->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer() )->GetMeasurementFrame() ) ); mitk::DiffusionPropertyHelper propertyHelper( newDwi2 ); propertyHelper.InitializeImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( newDwi2 ); - QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); + QString name = node->GetName().c_str(); imageNode->SetName((name+"_newdirection").toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); + GetDefaultDataStorage()->Add(imageNode, node); mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } - else if (m_SelectedImage.IsNotNull()) + else { - AccessFixedDimensionByItk(m_SelectedImage, TemplatedApplyRotation,3); + AccessFixedDimensionByItk(image, TemplatedApplyRotation,3); } } template < typename TPixel, unsigned int VImageDimension > void QmitkPreprocessingView::TemplatedApplyRotation( itk::Image* itkImage) { + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + ItkDwiType::DirectionType newDirection; for (int r=0; r<3; r++) for (int c=0; c<3; c++) { QTableWidgetItem* item = m_Controls->m_DirectionMatrixTable->item(r,c); if (!item) return; newDirection[r][c] = item->text().toDouble(); } typedef itk::Image ImageType; typename ImageType::Pointer newImage = ImageType::New(); newImage->SetSpacing( itkImage->GetSpacing() ); newImage->SetOrigin( itkImage->GetOrigin() ); newImage->SetDirection( newDirection ); newImage->SetLargestPossibleRegion( itkImage->GetLargestPossibleRegion() ); newImage->SetBufferedRegion( itkImage->GetLargestPossibleRegion() ); newImage->SetRequestedRegion( itkImage->GetLargestPossibleRegion() ); newImage->Allocate(); newImage->FillBuffer(0); itk::ImageRegionIterator< itk::Image > it(itkImage, itkImage->GetLargestPossibleRegion()); while(!it.IsAtEnd()) { newImage->SetPixel(it.GetIndex(), it.Get()); ++it; } mitk::Image::Pointer newMitkImage = mitk::Image::New(); newMitkImage->InitializeByItk(newImage.GetPointer()); newMitkImage->SetVolume(newImage->GetBufferPointer()); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( newMitkImage ); - QString name = m_SelectedImageNode->GetName().c_str(); + QString name = node->GetName().c_str(); imageNode->SetName((name+"_newdirection").toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode, m_SelectedImageNode); + GetDefaultDataStorage()->Add(imageNode, node); mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkPreprocessingView::DoProjectSignal() { switch(m_Controls->m_ProjectionMethodBox->currentIndex()) { case 0: DoADCAverage(); break; case 1: DoAKCFit(); break; case 2: DoBiExpFit(); break; default: DoADCAverage(); } } void QmitkPreprocessingView::DoDwiNormalization() { - bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast(m_SelectedImageNode->GetData())) ); + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); + + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); if ( ! isDiffusionImage ) return; - GradientDirectionContainerType::Pointer gradientContainer = static_cast( m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer(); + GradientDirectionContainerType::Pointer gradientContainer = static_cast( image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer(); int b0Index = -1; for (unsigned int i=0; isize(); i++) { GradientDirectionType g = gradientContainer->GetElement(i); if (g.magnitude()<0.001) { b0Index = i; break; } } if (b0Index==-1) return; typedef itk::DwiNormilzationFilter FilterType; ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); - mitk::CastToItkImage(m_SelectedImage, itkVectorImagePointer); + mitk::CastToItkImage(image, itkVectorImagePointer); FilterType::Pointer filter = FilterType::New(); filter->SetInput( itkVectorImagePointer ); - filter->SetGradientDirections( static_cast( m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ); + filter->SetGradientDirections( static_cast( image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ); UcharImageType::Pointer itkImage = NULL; if (m_Controls->m_NormalizationMaskBox->GetSelectedNode().IsNotNull()) { itkImage = UcharImageType::New(); mitk::CastToItkImage(dynamic_cast(m_Controls->m_NormalizationMaskBox->GetSelectedNode()->GetData()), itkImage); filter->SetMaskImage(itkImage); } // determin normalization reference switch(m_Controls->m_NormalizationReferenceBox->currentIndex()) { case 0: // normalize relative to mean white matter signal intensity { typedef itk::DiffusionTensor3DReconstructionImageFilter< short, short, double > TensorReconstructionImageFilterType; TensorReconstructionImageFilterType::Pointer dtFilter = TensorReconstructionImageFilterType::New(); dtFilter->SetGradientImage( gradientContainer, itkVectorImagePointer ); - dtFilter->SetBValue( static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ); + dtFilter->SetBValue( static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ); dtFilter->Update(); itk::Image< itk::DiffusionTensor3D< double >, 3 >::Pointer tensorImage = dtFilter->GetOutput(); itk::ImageRegionIterator< itk::Image< itk::DiffusionTensor3D< double >, 3 > > inIt(tensorImage, tensorImage->GetLargestPossibleRegion()); double ref = 0; unsigned int count = 0; while ( !inIt.IsAtEnd() ) { if (itkImage.IsNotNull() && itkImage->GetPixel(inIt.GetIndex())<=0) { ++inIt; continue; } double FA = inIt.Get().GetFractionalAnisotropy(); if (FA>0.4 && FA<0.99) { ref += itkVectorImagePointer->GetPixel(inIt.GetIndex())[b0Index]; count++; } ++inIt; } if (count>0) { ref /= count; filter->SetUseGlobalReference(true); filter->SetReference(ref); } break; } case 1: // normalize relative to mean CSF signal intensity { itk::AdcImageFilter< short, double >::Pointer adcFilter = itk::AdcImageFilter< short, double >::New(); adcFilter->SetInput( itkVectorImagePointer ); adcFilter->SetGradientDirections( gradientContainer); - adcFilter->SetB_value( static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ); + adcFilter->SetB_value( static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ); adcFilter->Update(); ItkDoubleImageType::Pointer adcImage = adcFilter->GetOutput(); itk::ImageRegionIterator inIt(adcImage, adcImage->GetLargestPossibleRegion()); double max = 0.0030; double ref = 0; unsigned int count = 0; while ( !inIt.IsAtEnd() ) { if (itkImage.IsNotNull() && itkImage->GetPixel(inIt.GetIndex())<=0) { ++inIt; continue; } if (inIt.Get()>max && inIt.Get()<0.004) { ref += itkVectorImagePointer->GetPixel(inIt.GetIndex())[b0Index]; count++; } ++inIt; } if (count>0) { ref /= count; filter->SetUseGlobalReference(true); filter->SetReference(ref); } break; } case 2: { filter->SetUseGlobalReference(false); } } filter->Update(); - mitk::Image::Pointer image = mitk::GrabItkImageMemory( filter->GetOutput() ); - image->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( static_cast( m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ) ); - image->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ) ); - image->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer() )->GetMeasurementFrame() ) ); - mitk::DiffusionPropertyHelper propertyHelper( image ); + mitk::Image::Pointer newImage = mitk::GrabItkImageMemory( filter->GetOutput() ); + newImage->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( static_cast( image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ) ); + newImage->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ) ); + newImage->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer() )->GetMeasurementFrame() ) ); + mitk::DiffusionPropertyHelper propertyHelper( newImage ); propertyHelper.InitializeImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); - imageNode->SetData( image ); - QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); + imageNode->SetData( newImage ); + QString name = node->GetName().c_str(); imageNode->SetName((name+"_normalized").toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); + GetDefaultDataStorage()->Add(imageNode, node); } void QmitkPreprocessingView::DoLengthCorrection() { - bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast(m_SelectedImageNode->GetData())) ); + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); + + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); if ( ! isDiffusionImage ) return; typedef itk::DwiGradientLengthCorrectionFilter FilterType; ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); - mitk::CastToItkImage(m_SelectedImage, itkVectorImagePointer); + mitk::CastToItkImage(image, itkVectorImagePointer); FilterType::Pointer filter = FilterType::New(); filter->SetRoundingValue( m_Controls->m_B_ValueMap_Rounder_SpinBox->value()); - filter->SetReferenceBValue( static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ); - filter->SetReferenceGradientDirectionContainer( static_cast( m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ); + filter->SetReferenceBValue( static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ); + filter->SetReferenceGradientDirectionContainer( static_cast( image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ); filter->Update(); - mitk::Image::Pointer image = mitk::ImportItkImage( itkVectorImagePointer ); - image->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( filter->GetOutputGradientDirectionContainer() ) ); - image->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( filter->GetNewBValue() ) ); - image->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer() )->GetMeasurementFrame() ) ); - mitk::DiffusionPropertyHelper propertyHelper( image ); + mitk::Image::Pointer newImage = mitk::ImportItkImage( itkVectorImagePointer ); + newImage->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( filter->GetOutputGradientDirectionContainer() ) ); + newImage->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( filter->GetNewBValue() ) ); + newImage->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer() )->GetMeasurementFrame() ) ); + mitk::DiffusionPropertyHelper propertyHelper( newImage ); propertyHelper.InitializeImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); - imageNode->SetData( image ); - QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); + imageNode->SetData( newImage ); + QString name = node->GetName().c_str(); imageNode->SetName((name+"_rounded").toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); + GetDefaultDataStorage()->Add(imageNode, node); } void QmitkPreprocessingView::UpdateDwiBValueMapRounder(int i) { - bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast(m_SelectedImageNode->GetData())) ); + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(node) ); if ( ! isDiffusionImage ) return; - //m_DiffusionImage->UpdateBValueMap(); + UpdateBValueTableWidget(i); } -void QmitkPreprocessingView::CallMultishellToSingleShellFilter(itk::DWIVoxelFunctor * functor, mitk::Image::Pointer ImPtr, QString imageName, mitk::DataNode* parent) +void QmitkPreprocessingView::CallMultishellToSingleShellFilter(itk::DWIVoxelFunctor * functor, mitk::Image::Pointer image, QString imageName, mitk::DataNode* parent) { typedef itk::RadialMultishellToSingleshellImageFilter FilterType; // filter input parameter const mitk::BValueMapProperty::BValueMap - &originalShellMap = static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap(); + &originalShellMap = static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap(); ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); - mitk::CastToItkImage(m_SelectedImage, itkVectorImagePointer); + mitk::CastToItkImage(image, itkVectorImagePointer); ItkDwiType *vectorImage = itkVectorImagePointer.GetPointer(); const mitk::GradientDirectionsProperty::GradientDirectionsContainerType::Pointer - gradientContainer = static_cast( m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer(); + gradientContainer = static_cast( image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer(); const unsigned int - &bValue = static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue(); + &bValue = static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue(); mitk::DataNode::Pointer imageNode = 0; // filter call FilterType::Pointer filter = FilterType::New(); filter->SetInput(vectorImage); filter->SetOriginalGradientDirections(gradientContainer); filter->SetOriginalBValueMap(originalShellMap); filter->SetOriginalBValue(bValue); filter->SetFunctor(functor); filter->Update(); // create new DWI image mitk::Image::Pointer outImage = mitk::GrabItkImageMemory( filter->GetOutput() ); outImage->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( filter->GetTargetGradientDirections() ) ); outImage->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( m_Controls->m_targetBValueSpinBox->value() ) ); - outImage->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer() )->GetMeasurementFrame() ) ); + outImage->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer() )->GetMeasurementFrame() ) ); mitk::DiffusionPropertyHelper propertyHelper( outImage ); propertyHelper.InitializeImage(); imageNode = mitk::DataNode::New(); imageNode->SetData( outImage ); imageNode->SetName(imageName.toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode, parent); // if(m_Controls->m_OutputRMSErrorImage->isChecked()){ // // create new Error image // FilterType::ErrorImageType::Pointer errImage = filter->GetErrorImage(); // mitk::Image::Pointer mitkErrImage = mitk::Image::New(); // mitkErrImage->InitializeByItk(errImage); // mitkErrImage->SetVolume(errImage->GetBufferPointer()); // imageNode = mitk::DataNode::New(); // imageNode->SetData( mitkErrImage ); // imageNode->SetName((imageName+"_Error").toStdString().c_str()); // GetDefaultDataStorage()->Add(imageNode); // } } void QmitkPreprocessingView::DoBiExpFit() { - itk::BiExpFitFunctor::Pointer functor = itk::BiExpFitFunctor::New(); - - for (unsigned int i=0; i(m_SelectedDiffusionNodes.at(i)->GetData()); + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); - QString name(m_SelectedDiffusionNodes.at(i)->GetName().c_str()); + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); + if ( ! isDiffusionImage ) + return; - const mitk::BValueMapProperty::BValueMap - &originalShellMap = static_cast(inImage->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap(); + itk::BiExpFitFunctor::Pointer functor = itk::BiExpFitFunctor::New(); - mitk::BValueMapProperty::BValueMap::const_iterator it = originalShellMap.begin(); - ++it;/* skip b=0*/ unsigned int s = 0; /*shell index */ - vnl_vector bValueList(originalShellMap.size()-1); - while(it != originalShellMap.end()) - bValueList.put(s++,(it++)->first); + QString name(node->GetName().c_str()); - const double targetBValue = m_Controls->m_targetBValueSpinBox->value(); - functor->setListOfBValues(bValueList); - functor->setTargetBValue(targetBValue); - CallMultishellToSingleShellFilter(functor,inImage,name + "_BiExp", m_SelectedDiffusionNodes.at(i)); - } + const mitk::BValueMapProperty::BValueMap + &originalShellMap = static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap(); + + mitk::BValueMapProperty::BValueMap::const_iterator it = originalShellMap.begin(); + ++it;/* skip b=0*/ unsigned int s = 0; /*shell index */ + vnl_vector bValueList(originalShellMap.size()-1); + while(it != originalShellMap.end()) + bValueList.put(s++,(it++)->first); + + const double targetBValue = m_Controls->m_targetBValueSpinBox->value(); + functor->setListOfBValues(bValueList); + functor->setTargetBValue(targetBValue); + CallMultishellToSingleShellFilter(functor,image,name + "_BiExp", node); } void QmitkPreprocessingView::DoAKCFit() { - itk::KurtosisFitFunctor::Pointer functor = itk::KurtosisFitFunctor::New(); - - for (unsigned int i=0; i(m_SelectedDiffusionNodes.at(i)->GetData()); + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); - QString name(m_SelectedDiffusionNodes.at(i)->GetName().c_str()); + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); + if ( ! isDiffusionImage ) + return; - const mitk::BValueMapProperty::BValueMap - &originalShellMap = static_cast(inImage->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap(); + itk::KurtosisFitFunctor::Pointer functor = itk::KurtosisFitFunctor::New(); - mitk::BValueMapProperty::BValueMap::const_iterator it = originalShellMap.begin(); - ++it;/* skip b=0*/ unsigned int s = 0; /*shell index */ - vnl_vector bValueList(originalShellMap.size()-1); - while(it != originalShellMap.end()) - bValueList.put(s++,(it++)->first); + QString name(node->GetName().c_str()); - const double targetBValue = m_Controls->m_targetBValueSpinBox->value(); - functor->setListOfBValues(bValueList); - functor->setTargetBValue(targetBValue); - CallMultishellToSingleShellFilter(functor,inImage,name + "_AKC", m_SelectedDiffusionNodes.at(i)); - } + const mitk::BValueMapProperty::BValueMap + &originalShellMap = static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap(); + + mitk::BValueMapProperty::BValueMap::const_iterator it = originalShellMap.begin(); + ++it;/* skip b=0*/ unsigned int s = 0; /*shell index */ + vnl_vector bValueList(originalShellMap.size()-1); + while(it != originalShellMap.end()) + bValueList.put(s++,(it++)->first); + + const double targetBValue = m_Controls->m_targetBValueSpinBox->value(); + functor->setListOfBValues(bValueList); + functor->setTargetBValue(targetBValue); + CallMultishellToSingleShellFilter(functor,image,name + "_AKC", node); } void QmitkPreprocessingView::DoADCFit() { // later } void QmitkPreprocessingView::DoADCAverage() { - itk::ADCAverageFunctor::Pointer functor = itk::ADCAverageFunctor::New(); - - for (unsigned int i=0; i(m_SelectedDiffusionNodes.at(i)->GetData()); + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); - QString name(m_SelectedDiffusionNodes.at(i)->GetName().c_str()); + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); + if ( ! isDiffusionImage ) + return; - const mitk::BValueMapProperty::BValueMap - &originalShellMap = static_cast(inImage->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap(); + itk::ADCAverageFunctor::Pointer functor = itk::ADCAverageFunctor::New(); - mitk::BValueMapProperty::BValueMap::const_iterator it = originalShellMap.begin(); - ++it;/* skip b=0*/ unsigned int s = 0; /*shell index */ - vnl_vector bValueList(originalShellMap.size()-1); - while(it != originalShellMap.end()) - bValueList.put(s++,(it++)->first); + QString name(node->GetName().c_str()); - const double targetBValue = m_Controls->m_targetBValueSpinBox->value(); - functor->setListOfBValues(bValueList); - functor->setTargetBValue(targetBValue); - CallMultishellToSingleShellFilter(functor,inImage,name + "_ADC", m_SelectedDiffusionNodes.at(i)); - } + const mitk::BValueMapProperty::BValueMap + &originalShellMap = static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap(); + + mitk::BValueMapProperty::BValueMap::const_iterator it = originalShellMap.begin(); + ++it;/* skip b=0*/ unsigned int s = 0; /*shell index */ + vnl_vector bValueList(originalShellMap.size()-1); + while(it != originalShellMap.end()) + bValueList.put(s++,(it++)->first); + + const double targetBValue = m_Controls->m_targetBValueSpinBox->value(); + functor->setListOfBValues(bValueList); + functor->setTargetBValue(targetBValue); + CallMultishellToSingleShellFilter(functor,image,name + "_ADC", node); } void QmitkPreprocessingView::DoAdcCalculation() { - bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast(m_SelectedImageNode->GetData())) ); + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); + + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); if ( ! isDiffusionImage ) return; typedef itk::AdcImageFilter< DiffusionPixelType, double > FilterType; + ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); + mitk::CastToItkImage(image, itkVectorImagePointer); + FilterType::Pointer filter = FilterType::New(); + filter->SetInput( itkVectorImagePointer ); + filter->SetGradientDirections( static_cast( image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ); + filter->SetB_value( static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ); + filter->Update(); - for (unsigned int i=0; i(m_SelectedDiffusionNodes.at(i)->GetData()); - ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); - mitk::CastToItkImage(inImage, itkVectorImagePointer); - FilterType::Pointer filter = FilterType::New(); - filter->SetInput( itkVectorImagePointer ); - filter->SetGradientDirections( static_cast( inImage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ); - filter->SetB_value( static_cast(inImage->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ); - filter->Update(); - - mitk::Image::Pointer image = mitk::Image::New(); - image->InitializeByItk( filter->GetOutput() ); - image->SetVolume( filter->GetOutput()->GetBufferPointer() ); - mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); - imageNode->SetData( image ); - QString name = m_SelectedDiffusionNodes.at(i)->GetName().c_str(); + mitk::Image::Pointer newImage = mitk::Image::New(); + newImage->InitializeByItk( filter->GetOutput() ); + newImage->SetVolume( filter->GetOutput()->GetBufferPointer() ); + mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); + imageNode->SetData( newImage ); + QString name = node->GetName().c_str(); - imageNode->SetName((name+"_ADC").toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.at(i)); - } + imageNode->SetName((name+"_ADC").toStdString().c_str()); + GetDefaultDataStorage()->Add(imageNode, node); } void QmitkPreprocessingView::UpdateBValueTableWidget(int i) { + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); + bool isDiffusionImage(false); - if( m_SelectedImageNode && m_SelectedImageNode.IsNotNull() ) - { - isDiffusionImage = mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast(m_SelectedImageNode->GetData())); - } + isDiffusionImage = mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image); if ( ! isDiffusionImage ) { m_Controls->m_B_ValueMap_TableWidget->clear(); m_Controls->m_B_ValueMap_TableWidget->setRowCount(1); QStringList headerList; headerList << "b-Value" << "Number of gradients"; m_Controls->m_B_ValueMap_TableWidget->setHorizontalHeaderLabels(headerList); m_Controls->m_B_ValueMap_TableWidget->setItem(0,0,new QTableWidgetItem("-")); m_Controls->m_B_ValueMap_TableWidget->setItem(0,1,new QTableWidgetItem("-")); }else{ typedef mitk::BValueMapProperty::BValueMap BValueMap; typedef mitk::BValueMapProperty::BValueMap::iterator BValueMapIterator; BValueMapIterator it; - BValueMap roundedBValueMap = static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap(); + BValueMap roundedBValueMap = static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap(); m_Controls->m_B_ValueMap_TableWidget->clear(); m_Controls->m_B_ValueMap_TableWidget->setRowCount(roundedBValueMap.size() ); QStringList headerList; headerList << "b-Value" << "Number of gradients"; m_Controls->m_B_ValueMap_TableWidget->setHorizontalHeaderLabels(headerList); int i = 0 ; for(it = roundedBValueMap.begin() ;it != roundedBValueMap.end(); it++) { m_Controls->m_B_ValueMap_TableWidget->setItem(i,0,new QTableWidgetItem(QString::number(it->first))); QTableWidgetItem* item = m_Controls->m_B_ValueMap_TableWidget->item(i,0); item->setFlags(item->flags() & ~Qt::ItemIsEditable); m_Controls->m_B_ValueMap_TableWidget->setItem(i,1,new QTableWidgetItem(QString::number(it->second.size()))); i++; } } } template < typename TPixel, unsigned int VImageDimension > void QmitkPreprocessingView::TemplatedUpdateGui( itk::Image* itkImage) { for (int r=0; r<3; r++) for (int c=0; c<3; c++) { QTableWidgetItem* item = m_Controls->m_DirectionMatrixTable->item(r,c); delete item; item = new QTableWidgetItem(); item->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter); item->setText(QString::number(itkImage->GetDirection()[r][c])); m_Controls->m_DirectionMatrixTable->setItem(r,c,item); } } -void QmitkPreprocessingView::OnSelectionChanged( std::vector nodes ) +void QmitkPreprocessingView::OnImageSelectionChanged() { - bool foundDwiVolume = false; - bool foundImageVolume = false; - m_SelectedImage = NULL; - m_SelectedImageNode = NULL; - m_SelectedDiffusionNodes.clear(); - - // iterate selection - for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) - { - mitk::DataNode::Pointer node = *it; - - if( node.IsNotNull() && dynamic_cast(node->GetData()) ) - { - foundImageVolume = true; - m_SelectedImage = dynamic_cast(node->GetData()); - m_Controls->m_DiffusionImageLabel->setText(node->GetName().c_str()); - m_SelectedImageNode = node; - - bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( m_SelectedImageNode ) ); - if( isDiffusionImage ) - { - foundDwiVolume = true; - m_SelectedDiffusionNodes.push_back(node); - } - } - } + bool foundImageVolume = true; + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + foundImageVolume; + bool foundDwiVolume( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( node ) ); m_Controls->m_ButtonAverageGradients->setEnabled(foundDwiVolume); m_Controls->m_ButtonExtractB0->setEnabled(foundDwiVolume); m_Controls->m_CheckExtractAll->setEnabled(foundDwiVolume); m_Controls->m_ModifyMeasurementFrame->setEnabled(foundDwiVolume); m_Controls->m_MeasurementFrameTable->setEnabled(foundDwiVolume); m_Controls->m_ReduceGradientsButton->setEnabled(foundDwiVolume); m_Controls->m_ShowGradientsButton->setEnabled(foundDwiVolume); m_Controls->m_MirrorGradientToHalfSphereButton->setEnabled(foundDwiVolume); m_Controls->m_MergeDwisButton->setEnabled(foundDwiVolume); m_Controls->m_B_ValueMap_Rounder_SpinBox->setEnabled(foundDwiVolume); m_Controls->m_ProjectSignalButton->setEnabled(foundDwiVolume); m_Controls->m_CreateLengthCorrectedDwi->setEnabled(foundDwiVolume); m_Controls->m_CalcAdcButton->setEnabled(foundDwiVolume); m_Controls->m_targetBValueSpinBox->setEnabled(foundDwiVolume); m_Controls->m_NormalizeImageValuesButton->setEnabled(foundDwiVolume); m_Controls->m_DirectionMatrixTable->setEnabled(foundImageVolume); m_Controls->m_ModifyDirection->setEnabled(foundImageVolume); m_Controls->m_ExtractBrainMask->setEnabled(foundImageVolume); m_Controls->m_ResampleImageButton->setEnabled(foundImageVolume); m_Controls->m_ModifySpacingButton->setEnabled(foundImageVolume); m_Controls->m_ModifyOriginButton->setEnabled(foundImageVolume); m_Controls->m_CropImageButton->setEnabled(foundImageVolume); m_Controls->m_RemoveGradientButton->setEnabled(foundDwiVolume); m_Controls->m_ExtractGradientButton->setEnabled(foundDwiVolume); + m_Controls->m_FlipAxis->setEnabled(foundImageVolume); // reset sampling frame to 1 and update all ealted components m_Controls->m_B_ValueMap_Rounder_SpinBox->setValue(1); UpdateBValueTableWidget(m_Controls->m_B_ValueMap_Rounder_SpinBox->value()); DoUpdateInterpolationGui(m_Controls->m_ResampleTypeBox->currentIndex()); - if( m_SelectedImageNode.IsNull() ) - { - return; - } - - bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( m_SelectedImageNode) ); - - if (foundDwiVolume && isDiffusionImage) + mitk::Image::Pointer image = dynamic_cast(node->GetData()); + if (foundDwiVolume) { m_Controls->m_InputData->setTitle("Input Data"); - vnl_matrix_fixed< double, 3, 3 > mf = static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer() )->GetMeasurementFrame(); + vnl_matrix_fixed< double, 3, 3 > mf = static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer() )->GetMeasurementFrame(); for (int r=0; r<3; r++) for (int c=0; c<3; c++) { // Measurement frame { QTableWidgetItem* item = m_Controls->m_MeasurementFrameTable->item(r,c); delete item; item = new QTableWidgetItem(); item->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter); item->setText(QString::number(mf.get(r,c))); m_Controls->m_MeasurementFrameTable->setItem(r,c,item); } // Direction matrix { ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); - mitk::CastToItkImage(m_SelectedImage, itkVectorImagePointer); + mitk::CastToItkImage(image, itkVectorImagePointer); QTableWidgetItem* item = m_Controls->m_DirectionMatrixTable->item(r,c); delete item; item = new QTableWidgetItem(); item->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter); item->setText(QString::number(itkVectorImagePointer->GetDirection()[r][c])); m_Controls->m_DirectionMatrixTable->setItem(r,c,item); } } //calculate target bValue for MultishellToSingleShellfilter - const mitk::BValueMapProperty::BValueMap & bValMap = static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap(); + const mitk::BValueMapProperty::BValueMap & bValMap = static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap(); mitk::BValueMapProperty::BValueMap::const_iterator it = bValMap.begin(); unsigned int targetBVal = 0; while(it != bValMap.end()) targetBVal += (it++)->first; targetBVal /= (float)bValMap.size()-1; m_Controls->m_targetBValueSpinBox->setValue(targetBVal); - m_Controls->m_HeaderSpacingX->setValue(m_SelectedImage->GetGeometry()->GetSpacing()[0]); - m_Controls->m_HeaderSpacingY->setValue(m_SelectedImage->GetGeometry()->GetSpacing()[1]); - m_Controls->m_HeaderSpacingZ->setValue(m_SelectedImage->GetGeometry()->GetSpacing()[2]); - m_Controls->m_HeaderOriginX->setValue(m_SelectedImage->GetGeometry()->GetOrigin()[0]); - m_Controls->m_HeaderOriginY->setValue(m_SelectedImage->GetGeometry()->GetOrigin()[1]); - m_Controls->m_HeaderOriginZ->setValue(m_SelectedImage->GetGeometry()->GetOrigin()[2]); - m_Controls->m_XstartBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(0)-1); - m_Controls->m_YstartBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(1)-1); - m_Controls->m_ZstartBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(2)-1); - m_Controls->m_XendBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(0)-1); - m_Controls->m_YendBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(1)-1); - m_Controls->m_ZendBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(2)-1); - m_Controls->m_RemoveGradientBox->setMaximum(static_cast( m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer()->Size()-1); - m_Controls->m_ExtractGradientBox->setMaximum(static_cast( m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer()->Size()-1); + m_Controls->m_HeaderSpacingX->setValue(image->GetGeometry()->GetSpacing()[0]); + m_Controls->m_HeaderSpacingY->setValue(image->GetGeometry()->GetSpacing()[1]); + m_Controls->m_HeaderSpacingZ->setValue(image->GetGeometry()->GetSpacing()[2]); + m_Controls->m_HeaderOriginX->setValue(image->GetGeometry()->GetOrigin()[0]); + m_Controls->m_HeaderOriginY->setValue(image->GetGeometry()->GetOrigin()[1]); + m_Controls->m_HeaderOriginZ->setValue(image->GetGeometry()->GetOrigin()[2]); + m_Controls->m_XstartBox->setMaximum(image->GetGeometry()->GetExtent(0)-1); + m_Controls->m_YstartBox->setMaximum(image->GetGeometry()->GetExtent(1)-1); + m_Controls->m_ZstartBox->setMaximum(image->GetGeometry()->GetExtent(2)-1); + m_Controls->m_XendBox->setMaximum(image->GetGeometry()->GetExtent(0)-1); + m_Controls->m_YendBox->setMaximum(image->GetGeometry()->GetExtent(1)-1); + m_Controls->m_ZendBox->setMaximum(image->GetGeometry()->GetExtent(2)-1); + m_Controls->m_RemoveGradientBox->setMaximum(static_cast( image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer()->Size()-1); + m_Controls->m_ExtractGradientBox->setMaximum(static_cast( image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer()->Size()-1); } else if (foundImageVolume) { for (int r=0; r<3; r++) for (int c=0; c<3; c++) { QTableWidgetItem* item = m_Controls->m_MeasurementFrameTable->item(r,c); delete item; item = new QTableWidgetItem(); m_Controls->m_MeasurementFrameTable->setItem(r,c,item); } - m_Controls->m_HeaderSpacingX->setValue(m_SelectedImage->GetGeometry()->GetSpacing()[0]); - m_Controls->m_HeaderSpacingY->setValue(m_SelectedImage->GetGeometry()->GetSpacing()[1]); - m_Controls->m_HeaderSpacingZ->setValue(m_SelectedImage->GetGeometry()->GetSpacing()[2]); - m_Controls->m_HeaderOriginX->setValue(m_SelectedImage->GetGeometry()->GetOrigin()[0]); - m_Controls->m_HeaderOriginY->setValue(m_SelectedImage->GetGeometry()->GetOrigin()[1]); - m_Controls->m_HeaderOriginZ->setValue(m_SelectedImage->GetGeometry()->GetOrigin()[2]); - m_Controls->m_XstartBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(0)-1); - m_Controls->m_YstartBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(1)-1); - m_Controls->m_ZstartBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(2)-1); - m_Controls->m_XendBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(0)-1); - m_Controls->m_YendBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(1)-1); - m_Controls->m_ZendBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(2)-1); - - AccessFixedDimensionByItk(m_SelectedImage, TemplatedUpdateGui,3); + m_Controls->m_HeaderSpacingX->setValue(image->GetGeometry()->GetSpacing()[0]); + m_Controls->m_HeaderSpacingY->setValue(image->GetGeometry()->GetSpacing()[1]); + m_Controls->m_HeaderSpacingZ->setValue(image->GetGeometry()->GetSpacing()[2]); + m_Controls->m_HeaderOriginX->setValue(image->GetGeometry()->GetOrigin()[0]); + m_Controls->m_HeaderOriginY->setValue(image->GetGeometry()->GetOrigin()[1]); + m_Controls->m_HeaderOriginZ->setValue(image->GetGeometry()->GetOrigin()[2]); + m_Controls->m_XstartBox->setMaximum(image->GetGeometry()->GetExtent(0)-1); + m_Controls->m_YstartBox->setMaximum(image->GetGeometry()->GetExtent(1)-1); + m_Controls->m_ZstartBox->setMaximum(image->GetGeometry()->GetExtent(2)-1); + m_Controls->m_XendBox->setMaximum(image->GetGeometry()->GetExtent(0)-1); + m_Controls->m_YendBox->setMaximum(image->GetGeometry()->GetExtent(1)-1); + m_Controls->m_ZendBox->setMaximum(image->GetGeometry()->GetExtent(2)-1); + + AccessFixedDimensionByItk(image, TemplatedUpdateGui,3); } else { for (int r=0; r<3; r++) for (int c=0; c<3; c++) { { QTableWidgetItem* item = m_Controls->m_MeasurementFrameTable->item(r,c); delete item; item = new QTableWidgetItem(); m_Controls->m_MeasurementFrameTable->setItem(r,c,item); } { QTableWidgetItem* item = m_Controls->m_DirectionMatrixTable->item(r,c); delete item; item = new QTableWidgetItem(); m_Controls->m_DirectionMatrixTable->setItem(r,c,item); } } - - m_Controls->m_DiffusionImageLabel->setText("mandatory"); - m_Controls->m_InputData->setTitle("Please Select Input Data"); } } void QmitkPreprocessingView::Activated() { QmitkFunctionality::Activated(); } void QmitkPreprocessingView::Deactivated() { QmitkFunctionality::Deactivated(); } void QmitkPreprocessingView::DoHalfSphereGradientDirections() { + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); - mitk::Image::Pointer newDwi = m_SelectedImage->Clone(); + mitk::Image::Pointer newDwi = image->Clone(); GradientDirectionContainerType::Pointer gradientContainer = static_cast( newDwi->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer(); for (unsigned int j=0; jSize(); j++) if (gradientContainer->at(j)[0]<0) gradientContainer->at(j) = -gradientContainer->at(j); newDwi->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( gradientContainer ) ); mitk::DiffusionPropertyHelper propertyHelper( newDwi ); propertyHelper.InitializeImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( newDwi ); - QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); + QString name = node->GetName().c_str(); imageNode->SetName((name+"_halfsphere").toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); + GetDefaultDataStorage()->Add(imageNode, node); } void QmitkPreprocessingView::DoApplyMesurementFrame() { - bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast(m_SelectedImageNode->GetData())) ); + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); + + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); if ( !isDiffusionImage ) return; vnl_matrix_fixed< double, 3, 3 > mf; for (int r=0; r<3; r++) for (int c=0; c<3; c++) { QTableWidgetItem* item = m_Controls->m_MeasurementFrameTable->item(r,c); if (!item) return; mf[r][c] = item->text().toDouble(); } - mitk::Image::Pointer newDwi = m_SelectedImage->Clone(); + mitk::Image::Pointer newDwi = image->Clone(); newDwi->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( mf ) ); mitk::DiffusionPropertyHelper propertyHelper( newDwi ); propertyHelper.InitializeImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( newDwi ); - QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); + QString name = node->GetName().c_str(); imageNode->SetName((name+"_new-MF").toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); + GetDefaultDataStorage()->Add(imageNode, node); } void QmitkPreprocessingView::DoShowGradientDirections() { - bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast(m_SelectedImageNode->GetData())) ); + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); + + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); if ( !isDiffusionImage ) return; int maxIndex = 0; - unsigned int maxSize = m_SelectedImage->GetDimension(0); - if (maxSizeGetDimension(1)) + unsigned int maxSize = image->GetDimension(0); + if (maxSizeGetDimension(1)) { - maxSize = m_SelectedImage->GetDimension(1); + maxSize = image->GetDimension(1); maxIndex = 1; } - if (maxSizeGetDimension(2)) + if (maxSizeGetDimension(2)) { - maxSize = m_SelectedImage->GetDimension(2); + maxSize = image->GetDimension(2); maxIndex = 2; } - mitk::Point3D origin = m_SelectedImage->GetGeometry()->GetOrigin(); + mitk::Point3D origin = image->GetGeometry()->GetOrigin(); mitk::PointSet::Pointer originSet = mitk::PointSet::New(); typedef mitk::BValueMapProperty::BValueMap BValueMap; typedef mitk::BValueMapProperty::BValueMap::iterator BValueMapIterator; - BValueMap bValMap = static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap(); + BValueMap bValMap = static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap(); - GradientDirectionContainerType::Pointer gradientContainer = static_cast( m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer(); - mitk::BaseGeometry::Pointer geometry = m_SelectedImage->GetGeometry(); + GradientDirectionContainerType::Pointer gradientContainer = static_cast( image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer(); + mitk::BaseGeometry::Pointer geometry = image->GetGeometry(); int shellCount = 1; for(BValueMapIterator it = bValMap.begin(); it!=bValMap.end(); ++it) { mitk::PointSet::Pointer pointset = mitk::PointSet::New(); for (unsigned int j=0; jsecond.size(); j++) { mitk::Point3D ip; vnl_vector_fixed< double, 3 > v = gradientContainer->at(it->second[j]); if (v.magnitude()>mitk::eps) { - ip[0] = v[0]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[0]-0.5*geometry->GetSpacing()[0] + geometry->GetSpacing()[0]*m_SelectedImage->GetDimension(0)/2; - ip[1] = v[1]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[1]-0.5*geometry->GetSpacing()[1] + geometry->GetSpacing()[1]*m_SelectedImage->GetDimension(1)/2; - ip[2] = v[2]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[2]-0.5*geometry->GetSpacing()[2] + geometry->GetSpacing()[2]*m_SelectedImage->GetDimension(2)/2; + ip[0] = v[0]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[0]-0.5*geometry->GetSpacing()[0] + geometry->GetSpacing()[0]*image->GetDimension(0)/2; + ip[1] = v[1]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[1]-0.5*geometry->GetSpacing()[1] + geometry->GetSpacing()[1]*image->GetDimension(1)/2; + ip[2] = v[2]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[2]-0.5*geometry->GetSpacing()[2] + geometry->GetSpacing()[2]*image->GetDimension(2)/2; pointset->InsertPoint(j, ip); } else if (originSet->IsEmpty()) { - ip[0] = v[0]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[0]-0.5*geometry->GetSpacing()[0] + geometry->GetSpacing()[0]*m_SelectedImage->GetDimension(0)/2; - ip[1] = v[1]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[1]-0.5*geometry->GetSpacing()[1] + geometry->GetSpacing()[1]*m_SelectedImage->GetDimension(1)/2; - ip[2] = v[2]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[2]-0.5*geometry->GetSpacing()[2] + geometry->GetSpacing()[2]*m_SelectedImage->GetDimension(2)/2; + ip[0] = v[0]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[0]-0.5*geometry->GetSpacing()[0] + geometry->GetSpacing()[0]*image->GetDimension(0)/2; + ip[1] = v[1]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[1]-0.5*geometry->GetSpacing()[1] + geometry->GetSpacing()[1]*image->GetDimension(1)/2; + ip[2] = v[2]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[2]-0.5*geometry->GetSpacing()[2] + geometry->GetSpacing()[2]*image->GetDimension(2)/2; originSet->InsertPoint(j, ip); } } if (it->firstSetData(pointset); - QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); + mitk::DataNode::Pointer newNode = mitk::DataNode::New(); + newNode->SetData(pointset); + QString name = node->GetName().c_str(); name += "_Shell_"; name += QString::number(it->first); - node->SetName(name.toStdString().c_str()); - node->SetProperty("pointsize", mitk::FloatProperty::New((float)maxSize/50)); + newNode->SetName(name.toStdString().c_str()); + newNode->SetProperty("pointsize", mitk::FloatProperty::New((float)maxSize/50)); int b0 = shellCount%2; int b1 = 0; int b2 = 0; if (shellCount>4) b2 = 1; if (shellCount%4 >= 2) b1 = 1; - node->SetProperty("color", mitk::ColorProperty::New(b2, b1, b0)); - GetDefaultDataStorage()->Add(node, m_SelectedDiffusionNodes.front()); + newNode->SetProperty("color", mitk::ColorProperty::New(b2, b1, b0)); + GetDefaultDataStorage()->Add(newNode, node); shellCount++; } // add origin to datastorage - mitk::DataNode::Pointer node = mitk::DataNode::New(); - node->SetData(originSet); - QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); + mitk::DataNode::Pointer newNode = mitk::DataNode::New(); + newNode->SetData(originSet); + QString name = node->GetName().c_str(); name += "_Origin"; - node->SetName(name.toStdString().c_str()); - node->SetProperty("pointsize", mitk::FloatProperty::New((float)maxSize/50)); - node->SetProperty("color", mitk::ColorProperty::New(1,1,1)); - GetDefaultDataStorage()->Add(node, m_SelectedDiffusionNodes.front()); + newNode->SetName(name.toStdString().c_str()); + newNode->SetProperty("pointsize", mitk::FloatProperty::New((float)maxSize/50)); + newNode->SetProperty("color", mitk::ColorProperty::New(1,1,1)); + GetDefaultDataStorage()->Add(newNode, node); } void QmitkPreprocessingView::DoReduceGradientDirections() { - bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( dynamic_cast(m_SelectedImageNode->GetData())) ); + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); + + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); if ( !isDiffusionImage ) return; typedef itk::ElectrostaticRepulsionDiffusionGradientReductionFilter FilterType; typedef mitk::BValueMapProperty::BValueMap BValueMap; // GetShellSelection from GUI BValueMap shellSlectionMap; - BValueMap originalShellMap = static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap(); + BValueMap originalShellMap = static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str()).GetPointer() )->GetBValueMap(); std::vector newNumGradientDirections; int shellCounter = 0; - QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); + QString name = node->GetName().c_str(); for (int i=0; im_B_ValueMap_TableWidget->rowCount(); i++) { double BValue = m_Controls->m_B_ValueMap_TableWidget->item(i,0)->text().toDouble(); shellSlectionMap[BValue] = originalShellMap[BValue]; unsigned int num = m_Controls->m_B_ValueMap_TableWidget->item(i,1)->text().toUInt(); newNumGradientDirections.push_back(num); name += "_"; name += QString::number(num); shellCounter++; } if (newNumGradientDirections.empty()) return; - GradientDirectionContainerType::Pointer gradientContainer = static_cast( m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer(); + GradientDirectionContainerType::Pointer gradientContainer = static_cast( image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer(); ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); - mitk::CastToItkImage(m_SelectedImage, itkVectorImagePointer); + mitk::CastToItkImage(image, itkVectorImagePointer); FilterType::Pointer filter = FilterType::New(); filter->SetInput( itkVectorImagePointer ); filter->SetOriginalGradientDirections(gradientContainer); filter->SetNumGradientDirections(newNumGradientDirections); filter->SetOriginalBValueMap(originalShellMap); filter->SetShellSelectionBValueMap(shellSlectionMap); filter->Update(); - mitk::Image::Pointer image = mitk::GrabItkImageMemory( filter->GetOutput() ); - image->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( filter->GetGradientDirections() ) ); - image->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer() )->GetMeasurementFrame() ) ); - image->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( static_cast(m_SelectedImage->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ) ); - mitk::DiffusionPropertyHelper propertyHelper( image ); + mitk::Image::Pointer newImage = mitk::GrabItkImageMemory( filter->GetOutput() ); + newImage->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( filter->GetGradientDirections() ) ); + newImage->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str()).GetPointer() )->GetMeasurementFrame() ) ); + newImage->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ) ); + mitk::DiffusionPropertyHelper propertyHelper( newImage ); propertyHelper.InitializeImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); - imageNode->SetData( image ); + imageNode->SetData( newImage ); imageNode->SetName(name.toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); + GetDefaultDataStorage()->Add(imageNode, node); } void QmitkPreprocessingView::MergeDwis() { typedef mitk::GradientDirectionsProperty::GradientDirectionsContainerType GradientContainerType; - if (m_SelectedDiffusionNodes.size()<2) + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); + + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); + if ( !isDiffusionImage ) return; + mitk::DataNode::Pointer node2 = m_Controls->m_MergeDwiBox->GetSelectedNode(); + if (node2.IsNull()) + return; + mitk::Image::Pointer image2 = dynamic_cast(node2->GetData()); + typedef itk::VectorImage DwiImageType; typedef DwiImageType::PixelType DwiPixelType; typedef DwiImageType::RegionType DwiRegionType; typedef std::vector< DwiImageType::Pointer > DwiImageContainerType; typedef std::vector< GradientContainerType::Pointer > GradientListContainerType; DwiImageContainerType imageContainer; GradientListContainerType gradientListContainer; std::vector< double > bValueContainer; - QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); - for (unsigned int i=0; i( m_SelectedDiffusionNodes.at(i)->GetData() ); - if ( dwi.IsNotNull() ) - { - ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); - mitk::CastToItkImage(dwi, itkVectorImagePointer); + ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); + mitk::CastToItkImage(image, itkVectorImagePointer); - imageContainer.push_back( itkVectorImagePointer ); - gradientListContainer.push_back( static_cast( dwi->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ); - bValueContainer.push_back( static_cast(dwi->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ); - if (i>0) - { - name += "+"; - name += m_SelectedDiffusionNodes.at(i)->GetName().c_str(); - } - } + imageContainer.push_back( itkVectorImagePointer ); + gradientListContainer.push_back( static_cast( image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ); + bValueContainer.push_back( static_cast(image->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ); + name += node->GetName().c_str(); + } + + { + ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); + mitk::CastToItkImage(image2, itkVectorImagePointer); + + imageContainer.push_back( itkVectorImagePointer ); + gradientListContainer.push_back( static_cast( image2->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ); + bValueContainer.push_back( static_cast(image2->GetProperty(mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str()).GetPointer() )->GetValue() ); + name += "+"; + name += node2->GetName().c_str(); } typedef itk::MergeDiffusionImagesFilter FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetImageVolumes(imageContainer); filter->SetGradientLists(gradientListContainer); filter->SetBValues(bValueContainer); filter->Update(); vnl_matrix_fixed< double, 3, 3 > mf; mf.set_identity(); - mitk::Image::Pointer image = mitk::GrabItkImageMemory( filter->GetOutput() ); + mitk::Image::Pointer newImage = mitk::GrabItkImageMemory( filter->GetOutput() ); - image->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( filter->GetOutputGradients() ) ); - image->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( mf ) ); - image->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( filter->GetB_Value() ) ); - mitk::DiffusionPropertyHelper propertyHelper( image ); + newImage->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( filter->GetOutputGradients() ) ); + newImage->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( mf ) ); + newImage->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( filter->GetB_Value() ) ); + mitk::DiffusionPropertyHelper propertyHelper( newImage ); propertyHelper.InitializeImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); - imageNode->SetData( image ); + imageNode->SetData( newImage ); imageNode->SetName(name.toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode); } void QmitkPreprocessingView::ExtractB0() { - typedef mitk::GradientDirectionsProperty::GradientDirectionsContainerType GradientContainerType; + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); + + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); + if ( !isDiffusionImage ) + return; - int nrFiles = m_SelectedDiffusionNodes.size(); - if (!nrFiles) return; + typedef mitk::GradientDirectionsProperty::GradientDirectionsContainerType GradientContainerType; // call the extraction withou averaging if the check-box is checked if( this->m_Controls->m_CheckExtractAll->isChecked() ) { DoExtractBOWithoutAveraging(); return; } - mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_SelectedDiffusionNodes.begin() ); - mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_SelectedDiffusionNodes.end() ); - - std::vector nodes; - while ( itemiter != itemiterend ) // for all items - { - - mitk::Image* vols = - static_cast( - (*itemiter)->GetData()); - - std::string nodename; - (*itemiter)->GetStringProperty("name", nodename); - - ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); - mitk::CastToItkImage(vols, itkVectorImagePointer); - - // Extract image using found index - typedef itk::B0ImageExtractionImageFilter FilterType; - FilterType::Pointer filter = FilterType::New(); - filter->SetInput( itkVectorImagePointer ); - filter->SetDirections( static_cast( vols->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ); - filter->Update(); + ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); + mitk::CastToItkImage(image, itkVectorImagePointer); - mitk::Image::Pointer mitkImage = mitk::Image::New(); - mitkImage->InitializeByItk( filter->GetOutput() ); - mitkImage->SetVolume( filter->GetOutput()->GetBufferPointer() ); - mitk::DataNode::Pointer node=mitk::DataNode::New(); - node->SetData( mitkImage ); - node->SetProperty( "name", mitk::StringProperty::New(nodename + "_B0")); + // Extract image using found index + typedef itk::B0ImageExtractionImageFilter FilterType; + FilterType::Pointer filter = FilterType::New(); + filter->SetInput( itkVectorImagePointer ); + filter->SetDirections( static_cast( image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ); + filter->Update(); - GetDefaultDataStorage()->Add(node, (*itemiter)); + mitk::Image::Pointer mitkImage = mitk::Image::New(); + mitkImage->InitializeByItk( filter->GetOutput() ); + mitkImage->SetVolume( filter->GetOutput()->GetBufferPointer() ); + mitk::DataNode::Pointer newNode=mitk::DataNode::New(); + newNode->SetData( mitkImage ); + newNode->SetProperty( "name", mitk::StringProperty::New(node->GetName() + "_B0")); - ++itemiter; - } + GetDefaultDataStorage()->Add(newNode, node); } void QmitkPreprocessingView::DoExtractBOWithoutAveraging() { - // typedefs - typedef mitk::GradientDirectionsProperty::GradientDirectionsContainerType GradientContainerType; - typedef itk::B0ImageExtractionToSeparateImageFilter< short, short> FilterType; - - // check number of selected objects, return if empty - int nrFiles = m_SelectedDiffusionNodes.size(); - if (!nrFiles) + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); - mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_SelectedDiffusionNodes.begin() ); - mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_SelectedDiffusionNodes.end() ); - - while ( itemiter != itemiterend ) // for all items - { - mitk::Image* vols = - static_cast( - (*itemiter)->GetData()); + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); + if ( !isDiffusionImage ) + return; - std::string nodename; - (*itemiter)->GetStringProperty("name", nodename); + // typedefs + typedef mitk::GradientDirectionsProperty::GradientDirectionsContainerType GradientContainerType; + typedef itk::B0ImageExtractionToSeparateImageFilter< short, short> FilterType; - ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); - mitk::CastToItkImage(vols, itkVectorImagePointer); + ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New(); + mitk::CastToItkImage(image, itkVectorImagePointer); - // Extract image using found index - FilterType::Pointer filter = FilterType::New(); - filter->SetInput( itkVectorImagePointer ); - filter->SetDirections( static_cast( vols->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ); - filter->Update(); + // Extract image using found index + FilterType::Pointer filter = FilterType::New(); + filter->SetInput( itkVectorImagePointer ); + filter->SetDirections( static_cast( image->GetProperty(mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str()).GetPointer() )->GetGradientDirectionsContainer() ); + filter->Update(); - mitk::Image::Pointer mitkImage = mitk::Image::New(); - mitkImage->InitializeByItk( filter->GetOutput() ); - mitkImage->SetImportChannel( filter->GetOutput()->GetBufferPointer() ); - mitk::DataNode::Pointer node=mitk::DataNode::New(); - node->SetData( mitkImage ); - node->SetProperty( "name", mitk::StringProperty::New(nodename + "_B0_ALL")); + mitk::Image::Pointer mitkImage = mitk::Image::New(); + mitkImage->InitializeByItk( filter->GetOutput() ); + mitkImage->SetImportChannel( filter->GetOutput()->GetBufferPointer() ); + mitk::DataNode::Pointer newNode=mitk::DataNode::New(); + newNode->SetData( mitkImage ); + newNode->SetProperty( "name", mitk::StringProperty::New(node->GetName() + "_B0_ALL")); - GetDefaultDataStorage()->Add(node, (*itemiter)); + GetDefaultDataStorage()->Add(newNode, node); - /*A reinitialization is needed to access the time channels via the ImageNavigationController + /*A reinitialization is needed to access the time channels via the ImageNavigationController The Global-Geometry can not recognize the time channel without a re-init. (for a new selection in datamanger a automatically updated of the Global-Geometry should be done - if it contains the time channel)*/ - mitk::RenderingManager::GetInstance()->InitializeViews(node->GetData()->GetTimeGeometry(),mitk::RenderingManager::REQUEST_UPDATE_ALL, true); - - ++itemiter; - } + mitk::RenderingManager::GetInstance()->InitializeViews(newNode->GetData()->GetTimeGeometry(),mitk::RenderingManager::REQUEST_UPDATE_ALL, true); } void QmitkPreprocessingView::AverageGradients() { - int nrFiles = m_SelectedDiffusionNodes.size(); - if (!nrFiles) return; - - mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_SelectedDiffusionNodes.begin() ); - mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_SelectedDiffusionNodes.end() ); - - while ( itemiter != itemiterend ) // for all items - { - mitk::Image* mitkDwi = - static_cast( - (*itemiter)->GetData()); + mitk::DataNode::Pointer node = m_Controls->m_SelctedImageComboBox->GetSelectedNode(); + if (node.IsNull()) + return; + mitk::Image::Pointer image = dynamic_cast(node->GetData()); - mitk::Image::Pointer newDwi = mitkDwi->Clone(); - newDwi->SetPropertyList(mitkDwi->GetPropertyList()->Clone()); + bool isDiffusionImage( mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(image) ); + if ( !isDiffusionImage ) + return; - mitk::DiffusionPropertyHelper propertyHelper(newDwi); - propertyHelper.AverageRedundantGradients(m_Controls->m_Blur->value()); - propertyHelper.InitializeImage(); + mitk::Image::Pointer newDwi = image->Clone(); + newDwi->SetPropertyList(image->GetPropertyList()->Clone()); - mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); - imageNode->SetData( newDwi ); - QString name = (*itemiter)->GetName().c_str(); - imageNode->SetName((name+"_averaged").toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode, (*itemiter)); + mitk::DiffusionPropertyHelper propertyHelper(newDwi); + propertyHelper.AverageRedundantGradients(m_Controls->m_Blur->value()); + propertyHelper.InitializeImage(); - ++itemiter; - } + mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); + imageNode->SetData( newDwi ); + QString name = node->GetName().c_str(); + imageNode->SetName((name+"_averaged").toStdString().c_str()); + GetDefaultDataStorage()->Add(imageNode, node); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.h b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.h index d2e798d963..8b7ccd6cde 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.h +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.h @@ -1,159 +1,159 @@ /*=================================================================== 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 _QMITKPREPROCESSINGVIEW_H_INCLUDED #define _QMITKPREPROCESSINGVIEW_H_INCLUDED #include #include "ui_QmitkPreprocessingViewControls.h" // st includes #include // itk includes #include #include // mitk includes #include #include "itkDWIVoxelFunctor.h" #include typedef short DiffusionPixelType; struct PrpSelListener; /*! * \ingroup org_mitk_gui_qt_preprocessing_internal * * \brief QmitkPreprocessingView * * Document your class here. * * \sa QmitkFunctionality */ class QmitkPreprocessingView : public QmitkFunctionality { friend struct PrpSelListener; // 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; typedef mitk::DiffusionPropertyHelper::GradientDirectionType GradientDirectionType; typedef mitk::DiffusionPropertyHelper::GradientDirectionsContainerType GradientDirectionContainerType; typedef itk::VectorImage< short, 3 > ItkDwiType; typedef itk::Image< unsigned char, 3 > UcharImageType; typedef itk::Image< double, 3 > ItkDoubleImageType; QmitkPreprocessingView(); virtual ~QmitkPreprocessingView(); 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(); static const int nrconvkernels; protected slots: void AverageGradients(); void ExtractB0(); void MergeDwis(); void DoApplySpacing(); void DoApplyOrigin(); void DoApplyDirectionMatrix(); void DoApplyMesurementFrame(); void DoReduceGradientDirections(); void DoShowGradientDirections(); void DoHalfSphereGradientDirections(); void UpdateDwiBValueMapRounder(int i); void DoLengthCorrection(); void DoAdcCalculation(); void DoDwiNormalization(); void DoProjectSignal(); void DoExtractBrainMask(); void DoResampleImage(); void DoCropImage(); void DoUpdateInterpolationGui(int i); void DoRemoveGradient(); void DoExtractGradient(); + void DoFlipAxis(); + void OnImageSelectionChanged(); protected: void DoADCFit(); void DoAKCFit(); void DoBiExpFit(); void DoADCAverage(); + template < typename TPixel, unsigned int VImageDimension > + void TemplatedFlipAxis( itk::Image* itkImage); + template < typename TPixel, unsigned int VImageDimension > void TemplatedCropImage( itk::Image* itkImage); template < typename TPixel, unsigned int VImageDimension > void TemplatedApplyRotation( itk::Image* itkImage); template < typename TPixel, unsigned int VImageDimension > void TemplatedUpdateGui( itk::Image* itkImage); template < typename TPixel, unsigned int VImageDimension > void TemplatedResampleImage( itk::Image* itkImage); template < typename TPixel, unsigned int VImageDimension > void TemplatedSetImageSpacing( itk::Image* itkImage); template < typename TPixel, unsigned int VImageDimension > void TemplatedSetImageOrigin( itk::Image* itkImage); /** Called by ExtractB0 if check-box activated, extracts all b0 images without averaging */ void DoExtractBOWithoutAveraging(); void UpdateBValueTableWidget(int i); /// \brief called by QmitkFunctionality when DataManager's selection has changed - virtual void OnSelectionChanged( std::vector nodes ); +// virtual void OnSelectionChanged( std::vector nodes ); Ui::QmitkPreprocessingViewControls* m_Controls; QmitkStdMultiWidget* m_MultiWidget; void SetDefaultNodeProperties(mitk::DataNode::Pointer node, std::string name); - - mitk::DataNode::Pointer m_SelectedImageNode; - mitk::Image::Pointer m_SelectedImage; - std::vector< mitk::DataNode::Pointer > m_SelectedDiffusionNodes; - void CallMultishellToSingleShellFilter(itk::DWIVoxelFunctor * functor, mitk::Image::Pointer ImPtr, QString imageName, mitk::DataNode* parent); }; #endif // _QMITKPREPROCESSINGVIEW_H_INCLUDED diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingViewControls.ui index b2460f04b2..1641e5acfa 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingViewControls.ui +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingViewControls.ui @@ -1,1574 +1,1645 @@ QmitkPreprocessingViewControls 0 0 - 639 - 1148 + 523 + 1158 0 0 false QmitkPreprocessingViewControls true Please Select Input Data Image: - - - <html><head/><body><p><span style=" color:#ff0000;">mandatory</span></p></body></html> - - - true + + + QComboBox::AdjustToMinimumContentsLength 0 Gradients - - - - Qt::Vertical + + + + + 0 + 0 + - - - 20 - 40 - + + Qt::ScrollBarAsNeeded - + + Qt::ScrollBarAlwaysOff + + + true + + + 100 + + + true + + + false + + + true + + + + b-Value + + + + + Number of gradients + + + QFrame::NoFrame QFrame::Raised 0 0 0 0 6 false Sometimes the gradient directions are not located on one half sphere. Mirror gradients to half sphere false Round b-values false Retain only the specified number of gradient directions and according image volumes. The retained directions are spread equally over the half sphere using an iterative energy repulsion strategy. Reduce number of gradients <html><head/><body><p>Define the sampling frame the b-Values are rounded with.</p></body></html> Sampling frame: false <html><head/><body><p>Round b-values to nearest multiple of this value (click &quot;Round b-value&quot; to create new image with these values).</p></body></html> QAbstractSpinBox::CorrectToNearestValue 1 10000 10 false Generate pointset displaying the gradient vectors (applied measurement frame). Show gradients - - - - - 0 - 0 - - - - Qt::ScrollBarAsNeeded - - - Qt::ScrollBarAlwaysOff - - - true - - - 100 - - - true - - - false - - - true - - - - b-Value - - - - - Number of gradients - - - - - - + + - Qt::Horizontal + Qt::Vertical - 40 - 20 + 20 + 40 Image Values Qt::Vertical 20 40 QFrame::NoFrame QFrame::Raised 0 0 0 0 0 QFrame::NoFrame QFrame::Raised 0 0 0 0 Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. 6 2.000000000000000 0.000100000000000 0.001000000000000 Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. Merge radius false Merges selected DWIs of same dimension. If several b-values are present, the resulting image will contain multiple b-shells. Merge selected DWIs false Normalize image values QFrame::NoFrame QFrame::Raised 0 0 0 0 0 false Target b-value 100000 500 Select projection method. + + QComboBox::AdjustToMinimumContentsLength + ADC Average AKC Bi-Exponential false Multiple acquistions of one gradient direction can be averaged. Due to rounding errors, similar gradients often differ in the last decimal positions. The Merge radius allows to average them by taking all directions within a certain radius into account. Average repetitions false Project image values onto one b-shell. Project onto shell QFrame::NoFrame QFrame::Raised 0 0 0 0 0 Select binary mask image. + + QComboBox::AdjustToMinimumContentsLength + Select normalization reference. + + QComboBox::AdjustToMinimumContentsLength + White matter CSF Voxel-wise baseline + + + + false + + + Merges selected DWIs of same dimension. If several b-values are present, the resulting image will contain multiple b-shells. + + + + + + + + + Flip axis + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Y + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + X + + + + + + + Z + + + + + + + Axis: + + + + + + + + + + QComboBox::AdjustToMinimumContentsLength + + + Resample image QFrame::NoFrame QFrame::Raised 0 0 0 0 0 0.010000000000000 2.000000000000000 0.010000000000000 2.000000000000000 0.010000000000000 2.000000000000000 Sampling factor New image spacing New image size QFrame::NoFrame QFrame::Raised 0 0 0 0 0 Interpolator: Nearest neighbour Linear B-spline Windowed sinc false Resample image QFrame::NoFrame QFrame::Raised 0 0 0 0 0 1 10000 1 10000 1 10000 Header - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Voxel size - - - - 0 - - - 0 - - - 0 - - - - - 4 - - - - - - - 4 - - - - - - - 4 - - - 0.000000000000000 - - - 99.989999999999995 - - - - - - - false - - - - - - - - - - - - Set new voxel size - - - - - - Image size 0 0 0 y: Number of pixels to remove on lower image bound. 999999999 Number of pixels to remove on upper image bound. 999999999 Number of pixels to remove on upper image bound. 999999999 Number of pixels to remove on lower image bound. 999999999 x: Number of pixels to remove on lower image bound. 999999999 Number of pixels to remove on upper image bound. 999999999 z: false Crop image - - + + - Origin + Remove or extract gradient volumes - + + + + + false + + + Generate pointset displaying the gradient vectors (applied measurement frame). + + + + + + + + + Remove + + + + + + + false + + + Generate pointset displaying the gradient vectors (applied measurement frame). + + + + + + + + + Extract + + + + + + + + + + + + + + + + Voxel size + + 0 0 0 - + 4 - - -999999999.000000000000000 - - - 999999999.000000000000000 - - - + + 4 - - -999999999.000000000000000 - - - 999999999.000000000000000 - - - + + 4 - -99999999.000000000000000 + 0.000000000000000 - 999999999.000000000000000 + 99.989999999999995 - + false - Set new origin + Set new voxel size - - + + - Qt::Horizontal + Qt::Vertical - 40 - 20 + 20 + 40 - - + + + + + 0 + 0 + + - Direction matrix + Measurment frame - + 0 - - 9 - 0 0 + + + + Qt::Horizontal + + + + 40 + 20 + + + + - + false 0 0 0 0 IBeamCursor true Qt::ScrollBarAlwaysOff Qt::ScrollBarAlwaysOff true false false true true 0 false true true New Row New Row New Row New Column New Column New Column - + false Diffusion encoding gradient directions are rotated accordingly. - Apply new direction + Apply new measurement frame - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - + + - Measurment frame + Direction matrix - + 0 + + 9 + 0 0 - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + false 0 0 0 0 IBeamCursor true Qt::ScrollBarAlwaysOff Qt::ScrollBarAlwaysOff true false false true true 0 false true true New Row New Row New Row New Column New Column New Column - + false Diffusion encoding gradient directions are rotated accordingly. - Apply new measurement frame + Apply new direction + + + + Qt::Horizontal + + + + 40 + 20 + + + + - - + + - Remove or extract gradient volumes + Origin - + + + 0 + + + 0 + + + 0 + - - - false + + + 4 - - Generate pointset displaying the gradient vectors (applied measurement frame). + + -999999999.000000000000000 - - + + 999999999.000000000000000 - - + + + + + + 4 - - Remove + + -999999999.000000000000000 + + + 999999999.000000000000000 + + + + + + + 4 + + + -99999999.000000000000000 + + + 999999999.000000000000000 - + false - Generate pointset displaying the gradient vectors (applied measurement frame). + - Extract + Set new origin - - - - - - Other Create a 3D+t data set containing all b0 images as timesteps Disable averaging false If multiple baseline acquisitions are present, the default behaviour is to output an averaged image. Extract baseline image Qt::Vertical 20 40 false If multiple baseline acquisitions are present, the default behaviour is to output an averaged image. Calculate ADC map false If multiple baseline acquisitions are present, the default behaviour is to output an averaged image. Estimate binary brain mask Maximum number of iterations. 10000 10000 QmitkDataStorageComboBox QComboBox
QmitkDataStorageComboBox.h
m_B_ValueMap_Rounder_SpinBox m_Blur m_targetBValueSpinBox m_ProjectionMethodBox m_ResampleTypeBox m_ResampleDoubleX m_ResampleDoubleY m_ResampleDoubleZ m_ResampleIntX m_ResampleIntY m_ResampleIntZ m_InterpolatorBox m_HeaderSpacingX m_HeaderSpacingY m_HeaderSpacingZ m_HeaderOriginX m_HeaderOriginY m_HeaderOriginZ m_DirectionMatrixTable m_MeasurementFrameTable m_CheckExtractAll m_BrainMaskIterationsBox tabWidget m_B_ValueMap_TableWidget m_CreateLengthCorrectedDwi m_ShowGradientsButton m_MirrorGradientToHalfSphereButton m_ReduceGradientsButton m_ButtonAverageGradients m_ProjectSignalButton m_NormalizeImageValuesButton m_MergeDwisButton m_ResampleImageButton m_ModifySpacingButton m_ModifyOriginButton m_ModifyDirection m_ModifyMeasurementFrame m_ButtonExtractB0 m_CalcAdcButton m_ExtractBrainMask