diff --git a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.h b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.h index 42506c0386..b7495a590f 100644 --- a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.h +++ b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.h @@ -1,126 +1,129 @@ /*=================================================================== 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 __mitkDiffusionImage__h #define __mitkDiffusionImage__h #include "mitkImage.h" #include "itkVectorImage.h" #include "itkVectorImageToImageAdaptor.h" #include #include namespace mitk { /** * \brief this class encapsulates diffusion volumes (vectorimages not * yet supported by mitkImage) */ template class DiffusionImage : public Image { public: typedef TPixelType PixelType; typedef typename itk::VectorImage ImageType; typedef vnl_vector_fixed< double, 3 > GradientDirectionType; typedef itk::VectorContainer< unsigned int, GradientDirectionType > GradientDirectionContainerType; typedef itk::VectorImageToImageAdaptor< TPixelType, 3 > AdaptorType; typedef vnl_matrix_fixed< double, 3, 3 > MeasurementFrameType; // BValue Map // key := b-Value // value := indicesVector (containing corresponding gradient directions for a b-Value-Shell typedef std::vector< unsigned int > IndicesVector; typedef std::map< double , IndicesVector > BValueMap; mitkClassMacro( DiffusionImage, Image ) itkNewMacro(Self) void AverageRedundantGradients(double precision); GradientDirectionContainerType::Pointer CalcAveragedDirectionSet(double precision, GradientDirectionContainerType::Pointer directions); void CorrectDKFZBrokenGradientScheme(double precision); typename ImageType::Pointer GetVectorImage() { return m_VectorImage; } void SetVectorImage(typename ImageType::Pointer image ) { this->m_VectorImage = image; } void InitializeFromVectorImage(); void SetDisplayIndexForRendering(int displayIndex); GradientDirectionContainerType::Pointer GetDirectionsWithoutMeasurementFrame() { return m_OriginalDirections; } GradientDirectionContainerType::Pointer GetDirections() { return m_Directions; } void SetDirections( GradientDirectionContainerType::Pointer directions ) { this->m_OriginalDirections = directions; ApplyMeasurementFrame(); } void SetDirections(const std::vector > directions); MeasurementFrameType GetMeasurementFrame() { return m_MeasurementFrame; } void SetMeasurementFrame( MeasurementFrameType mFrame ) { this->m_MeasurementFrame = mFrame; this->ApplyMeasurementFrame(); } bool AreAlike(GradientDirectionType g1, GradientDirectionType g2, double precision); int GetNumDirections(); int GetNumB0(); float GetB_Value(int i); bool IsMultiBval(); - void UpdateBValueList(); + void UpdateBValueMap(); IndicesVector GetB0Indices(); itkGetMacro(B_Value, float) itkSetMacro(B_Value, float) + itkGetMacro(B_ValueMap_Rounder, int) + itkSetMacro(B_ValueMap_Rounder, int) BValueMap GetB_ValueMap(){ return m_B_ValueMap; } void AddDirectionsContainerObserver(); void RemoveDirectionsContainerObserver(); protected: DiffusionImage(); virtual ~DiffusionImage(); void ApplyMeasurementFrame(); typename ImageType::Pointer m_VectorImage; GradientDirectionContainerType::Pointer m_Directions; GradientDirectionContainerType::Pointer m_OriginalDirections; float m_B_Value; typename AdaptorType::Pointer m_VectorImageAdaptor; int m_DisplayIndex; MeasurementFrameType m_MeasurementFrame; BValueMap m_B_ValueMap; + int m_B_ValueMap_Rounder; unsigned long m_DirectionsObserverTag; }; } // namespace mitk #include "mitkDiffusionImage.txx" #endif /* __mitkDiffusionImage__h */ diff --git a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.txx b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.txx index 4778589dae..e7b59c3bee 100644 --- a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.txx +++ b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.txx @@ -1,430 +1,421 @@ /*=================================================================== 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 "itkImageRegionIterator.h" #include "itkImageRegionConstIterator.h" #include "mitkImageCast.h" template mitk::DiffusionImage::DiffusionImage() - : m_VectorImage(0), m_Directions(0), m_OriginalDirections(0), m_B_Value(-1.0), m_VectorImageAdaptor(0) + : m_VectorImage(0), m_Directions(0), m_OriginalDirections(0), m_B_Value(-1.0), m_VectorImageAdaptor(0), m_B_ValueMap_Rounder(100) { MeasurementFrameType mf; for(int i=0; i<3; i++) for(int j=0; j<3; j++) mf[i][j] = 0; for(int i=0; i<3; i++) mf[i][i] = 1; m_MeasurementFrame = mf; } template mitk::DiffusionImage::~DiffusionImage() { // Remove Observer for m_Directions RemoveDirectionsContainerObserver(); } template void mitk::DiffusionImage ::InitializeFromVectorImage() { if(!m_VectorImage || !m_Directions || m_B_Value==-1.0) { MITK_INFO << "DiffusionImage could not be initialized. Set all members first!" << std::endl; return; } // find bzero index int firstZeroIndex = -1; for(GradientDirectionContainerType::ConstIterator it = m_Directions->Begin(); it != m_Directions->End(); ++it) { firstZeroIndex++; GradientDirectionType g = it.Value(); if(g[0] == 0 && g[1] == 0 && g[2] == 0 ) break; } typedef itk::Image ImgType; typename ImgType::Pointer img = ImgType::New(); img->SetSpacing( m_VectorImage->GetSpacing() ); // Set the image spacing img->SetOrigin( m_VectorImage->GetOrigin() ); // Set the image origin img->SetDirection( m_VectorImage->GetDirection() ); // Set the image direction img->SetLargestPossibleRegion( m_VectorImage->GetLargestPossibleRegion()); img->SetBufferedRegion( m_VectorImage->GetLargestPossibleRegion() ); img->Allocate(); int vecLength = m_VectorImage->GetVectorLength(); InitializeByItk( img.GetPointer(), 1, vecLength ); itk::ImageRegionIterator itw (img, img->GetLargestPossibleRegion() ); itw = itw.Begin(); itk::ImageRegionConstIterator itr (m_VectorImage, m_VectorImage->GetLargestPossibleRegion() ); itr = itr.Begin(); while(!itr.IsAtEnd()) { itw.Set(itr.Get().GetElement(firstZeroIndex)); ++itr; ++itw; } // init SetImportVolume(img->GetBufferPointer()); m_DisplayIndex = firstZeroIndex; MITK_INFO << "Diffusion-Image successfully initialized."; } template void mitk::DiffusionImage ::SetDisplayIndexForRendering(int displayIndex) { int index = displayIndex; int vecLength = m_VectorImage->GetVectorLength(); index = index > vecLength-1 ? vecLength-1 : index; if( m_DisplayIndex != index ) { typedef itk::Image ImgType; typename ImgType::Pointer img = ImgType::New(); CastToItkImage(this, img); itk::ImageRegionIterator itw (img, img->GetLargestPossibleRegion() ); itw = itw.Begin(); itk::ImageRegionConstIterator itr (m_VectorImage, m_VectorImage->GetLargestPossibleRegion() ); itr = itr.Begin(); while(!itr.IsAtEnd()) { itw.Set(itr.Get().GetElement(index)); ++itr; ++itw; } } m_DisplayIndex = index; } template bool mitk::DiffusionImage::AreAlike(GradientDirectionType g1, GradientDirectionType g2, double precision) { GradientDirectionType diff = g1 - g2; GradientDirectionType diff2 = g1 + g2; return diff.two_norm() < precision || diff2.two_norm() < precision; } template void mitk::DiffusionImage::CorrectDKFZBrokenGradientScheme(double precision) { GradientDirectionContainerType::Pointer directionSet = CalcAveragedDirectionSet(precision, m_Directions); if(directionSet->size() < 7) { MITK_INFO << "Too few directions, assuming and correcting DKFZ-bogus sequence details."; double v [7][3] = {{ 0, 0, 0 }, {-0.707057, 0, 0.707057 }, { 0.707057, 0, 0.707057 }, { 0, 0.707057, 0.707057 }, { 0, 0.707057, -0.707057 }, {-0.707057, 0.707057, 0 }, { 0.707057, 0.707057, 0 } }; int i=0; for(GradientDirectionContainerType::Iterator it = m_OriginalDirections->Begin(); it != m_OriginalDirections->End(); ++it) { it.Value().set(v[i++%7]); } ApplyMeasurementFrame(); } } template mitk::DiffusionImage::GradientDirectionContainerType::Pointer mitk::DiffusionImage::CalcAveragedDirectionSet(double precision, GradientDirectionContainerType::Pointer directions) { // save old and construct new direction container GradientDirectionContainerType::Pointer newDirections = GradientDirectionContainerType::New(); // fill new direction container for(GradientDirectionContainerType::ConstIterator gdcitOld = directions->Begin(); gdcitOld != directions->End(); ++gdcitOld) { // already exists? bool found = false; for(GradientDirectionContainerType::ConstIterator gdcitNew = newDirections->Begin(); gdcitNew != newDirections->End(); ++gdcitNew) { if(AreAlike(gdcitNew.Value(), gdcitOld.Value(), precision)) { found = true; break; } } // if not found, add it to new container if(!found) { newDirections->push_back(gdcitOld.Value()); } } return newDirections; } template void mitk::DiffusionImage::AverageRedundantGradients(double precision) { GradientDirectionContainerType::Pointer newDirs = CalcAveragedDirectionSet(precision, m_Directions); GradientDirectionContainerType::Pointer newOriginalDirs = CalcAveragedDirectionSet(precision, m_OriginalDirections); // if sizes equal, we do not need to do anything in this function if(m_Directions->size() == newDirs->size() || m_OriginalDirections->size() == newOriginalDirs->size()) return; GradientDirectionContainerType::Pointer oldDirections = m_OriginalDirections; m_Directions = newDirs; m_OriginalDirections = newOriginalDirs; // new image typename ImageType::Pointer oldImage = m_VectorImage; m_VectorImage = ImageType::New(); m_VectorImage->SetSpacing( oldImage->GetSpacing() ); // Set the image spacing m_VectorImage->SetOrigin( oldImage->GetOrigin() ); // Set the image origin m_VectorImage->SetDirection( oldImage->GetDirection() ); // Set the image direction m_VectorImage->SetLargestPossibleRegion( oldImage->GetLargestPossibleRegion() ); m_VectorImage->SetVectorLength( m_Directions->size() ); m_VectorImage->SetBufferedRegion( oldImage->GetLargestPossibleRegion() ); m_VectorImage->Allocate(); // average image data that corresponds to identical directions itk::ImageRegionIterator< ImageType > newIt(m_VectorImage, m_VectorImage->GetLargestPossibleRegion()); newIt.GoToBegin(); itk::ImageRegionIterator< ImageType > oldIt(oldImage, oldImage->GetLargestPossibleRegion()); oldIt.GoToBegin(); // initial new value of voxel typename ImageType::PixelType newVec; newVec.SetSize(m_Directions->size()); newVec.AllocateElements(m_Directions->size()); std::vector > dirIndices; for(GradientDirectionContainerType::ConstIterator gdcitNew = m_Directions->Begin(); gdcitNew != m_Directions->End(); ++gdcitNew) { dirIndices.push_back(std::vector(0)); for(GradientDirectionContainerType::ConstIterator gdcitOld = oldDirections->Begin(); gdcitOld != oldDirections->End(); ++gdcitOld) { if(AreAlike(gdcitNew.Value(), gdcitOld.Value(), precision)) { //MITK_INFO << gdcitNew.Value() << " " << gdcitOld.Value(); dirIndices[gdcitNew.Index()].push_back(gdcitOld.Index()); } } } //int ind1 = -1; while(!newIt.IsAtEnd()) { // progress //typename ImageType::IndexType ind = newIt.GetIndex(); //ind1 = ind.m_Index[2]; // init new vector with zeros newVec.Fill(0.0); // the old voxel value with duplicates typename ImageType::PixelType oldVec = oldIt.Get(); for(unsigned int i=0; i void mitk::DiffusionImage::ApplyMeasurementFrame() { RemoveDirectionsContainerObserver(); m_Directions = GradientDirectionContainerType::New(); int c = 0; for(GradientDirectionContainerType::ConstIterator gdcit = m_OriginalDirections->Begin(); gdcit != m_OriginalDirections->End(); ++gdcit) { vnl_vector vec = gdcit.Value(); vec = vec.pre_multiply(m_MeasurementFrame); m_Directions->InsertElement(c, vec); c++; } - UpdateBValueList(); + UpdateBValueMap(); AddDirectionsContainerObserver(); } // returns number of gradients template int mitk::DiffusionImage::GetNumDirections() { int gradients = m_OriginalDirections->Size(); for (int i=0; iSize(); i++) if (GetB_Value(i)<=0) { gradients--; } return gradients; } // returns number of not diffusion weighted images template int mitk::DiffusionImage::GetNumB0() { int b0 = 0; for (int i=0; iSize(); i++) if (GetB_Value(i)<=0) { b0++; } return b0; } // returns a list of indices belonging to the not diffusion weighted images template typename mitk::DiffusionImage::IndicesVector mitk::DiffusionImage::GetB0Indices() { IndicesVector indices; for (int i=0; iSize(); i++) if (GetB_Value(i)<=0) { indices.push_back(i); } return indices; } template bool mitk::DiffusionImage::IsMultiBval() { int gradients = m_OriginalDirections->Size(); for (int i=0; i0 && std::fabs(m_B_Value-GetB_Value(i))>50) return true; return false; } template -void mitk::DiffusionImage::UpdateBValueList() +void mitk::DiffusionImage::UpdateBValueMap() { m_B_ValueMap.clear(); GradientDirectionContainerType::ConstIterator gdcit; for( gdcit = this->m_Directions->Begin(); gdcit != this->m_Directions->End(); ++gdcit) { float currentBvalue = std::floor(GetB_Value(gdcit.Index())); - double rounded = int((currentBvalue+7.5)/100)*100; + double rounded = int((currentBvalue + 0.5 * m_B_ValueMap_Rounder)/m_B_ValueMap_Rounder)*m_B_ValueMap_Rounder; m_B_ValueMap[rounded].push_back(gdcit.Index()); } - - /* - BValueMap::iterator it = m_B_ValueMap.begin(); - for(;it != m_B_ValueMap.end(); it++) - { - MITK_INFO << it->first << " : " << it->second.size(); - } - */ - } template float mitk::DiffusionImage::GetB_Value(int i) { if(i > m_Directions->Size()-1) return -1; if(m_Directions->ElementAt(i).one_norm() <= 0.0) { return 0; } else { double twonorm = m_Directions->ElementAt(i).two_norm(); return m_B_Value*twonorm*twonorm ; } } template void mitk::DiffusionImage::SetDirections(const std::vector > directions) { m_OriginalDirections = GradientDirectionContainerType::New(); for(unsigned int i=0; iInsertElement( i, directions[i].Get_vnl_vector() ); } this->ApplyMeasurementFrame(); } template void mitk::DiffusionImage::AddDirectionsContainerObserver() { // Add Modified Observer to invoke an UpdateBValueList by modifieng the DirectionsContainer (m_Directions) typedef DiffusionImage< TPixelType > Self; typedef itk::SimpleMemberCommand< Self > DCCommand ; typename DCCommand::Pointer command = DCCommand::New(); - command->SetCallbackFunction(this, &Self::UpdateBValueList); + command->SetCallbackFunction(this, &Self::UpdateBValueMap); } template void mitk::DiffusionImage::RemoveDirectionsContainerObserver() { if(m_Directions){ m_Directions->RemoveAllObservers(); } } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp index 8f2eb733e7..3c1f2d8c59 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp @@ -1,798 +1,798 @@ /*=================================================================== 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 "QmitkDiffusionDicomImportView.h" // qt includes #include // itk includes #include "itkTimeProbesCollectorBase.h" #include "itkGDCMSeriesFileNames.h" #include "itksys/SystemTools.hxx" // mitk includes #include "mitkProgressBar.h" #include "mitkStatusBar.h" #include "mitkProperties.h" #include "mitkRenderingManager.h" #include "mitkMemoryUtilities.h" // diffusion module includes #include "mitkDicomDiffusionImageHeaderReader.h" #include "mitkDicomDiffusionImageReader.h" #include "mitkDiffusionImage.h" #include "mitkNrrdDiffusionImageWriter.h" #include "gdcmDirectory.h" #include "gdcmScanner.h" #include "gdcmSorter.h" #include "gdcmIPPSorter.h" #include "gdcmAttribute.h" #include "gdcmVersion.h" #include const std::string QmitkDiffusionDicomImport::VIEW_ID = "org.mitk.views.diffusiondicomimport"; QmitkDiffusionDicomImport::QmitkDiffusionDicomImport(QObject* /*parent*/, const char* /*name*/) : QmitkFunctionality(), m_Controls(NULL), m_MultiWidget(NULL), m_OutputFolderName(""), m_OutputFolderNameSet(false) { } QmitkDiffusionDicomImport::QmitkDiffusionDicomImport(const QmitkDiffusionDicomImport& other) { Q_UNUSED(other) throw std::runtime_error("Copy constructor not implemented"); } QmitkDiffusionDicomImport::~QmitkDiffusionDicomImport() {} void QmitkDiffusionDicomImport::CreateQtPartControl(QWidget *parent) { m_Parent = parent; if (m_Controls == NULL) { m_Controls = new Ui::QmitkDiffusionDicomImportControls; m_Controls->setupUi(parent); this->CreateConnections(); m_Controls->m_DicomLoadRecursiveCheckbox->setChecked(true); m_Controls->m_DicomLoadAverageDuplicatesCheckbox->setChecked(false); m_Controls->m_DicomLoadRecursiveCheckbox->setVisible(false); m_Controls->m_OverrideOptionCheckbox->setVisible(false); AverageClicked(); } } void QmitkDiffusionDicomImport::CreateConnections() { if ( m_Controls ) { connect( m_Controls->m_AddFoldersButton, SIGNAL(clicked()), this, SLOT(DicomLoadAddFolderNames()) ); connect( m_Controls->m_DeleteFoldersButton, SIGNAL(clicked()), this, SLOT(DicomLoadDeleteFolderNames()) ); connect( m_Controls->m_DicomLoadStartLoadButton, SIGNAL(clicked()), this, SLOT(DicomLoadStartLoad()) ); connect( m_Controls->m_DicomLoadAverageDuplicatesCheckbox, SIGNAL(clicked()), this, SLOT(AverageClicked()) ); connect( m_Controls->m_OutputSetButton, SIGNAL(clicked()), this, SLOT(OutputSet()) ); connect( m_Controls->m_OutputClearButton, SIGNAL(clicked()), this, SLOT(OutputClear()) ); connect( m_Controls->m_Remove, SIGNAL(clicked()), this, SLOT(Remove()) ); } } void QmitkDiffusionDicomImport::Remove() { int i = m_Controls->listWidget->currentRow(); m_Controls->listWidget->takeItem(i); } void QmitkDiffusionDicomImport::OutputSet() { // SELECT FOLDER DIALOG QFileDialog* w = new QFileDialog( m_Parent, QString("Select folders containing DWI data") ); w->setFileMode( QFileDialog::Directory ); // RETRIEVE SELECTION if ( w->exec() != QDialog::Accepted ) return; m_OutputFolderName = w->selectedFiles()[0]; m_OutputFolderNameSet = true; m_Controls->m_OutputLabel->setText(m_OutputFolderName); // show file override option checkbox m_Controls->m_OverrideOptionCheckbox->setVisible(true); } void QmitkDiffusionDicomImport::OutputClear() { m_OutputFolderName = ""; m_OutputFolderNameSet = false; m_Controls->m_OutputLabel->setText("... optional out-folder ..."); // hide file override option checkbox - no output specified m_Controls->m_OverrideOptionCheckbox->setVisible(false); } void QmitkDiffusionDicomImport::AverageClicked() { m_Controls->m_Blur->setEnabled(m_Controls->m_DicomLoadAverageDuplicatesCheckbox->isChecked()); } void QmitkDiffusionDicomImport::Activated() { QmitkFunctionality::Activated(); } void QmitkDiffusionDicomImport::DicomLoadDeleteFolderNames() { m_Controls->listWidget->clear(); } void QmitkDiffusionDicomImport::DicomLoadAddFolderNames() { // SELECT FOLDER DIALOG QFileDialog* w = new QFileDialog( m_Parent, QString("Select folders containing DWI data") ); w->setFileMode( QFileDialog::Directory ); // RETRIEVE SELECTION if ( w->exec() != QDialog::Accepted ) return; m_Controls->listWidget->addItems(w->selectedFiles()); } bool SortBySeriesUID(gdcm::DataSet const & ds1, gdcm::DataSet const & ds2 ) { gdcm::Attribute<0x0020,0x000e> at1; at1.Set( ds1 ); gdcm::Attribute<0x0020,0x000e> at2; at2.Set( ds2 ); return at1 < at2; } bool SortByAcquisitionNumber(gdcm::DataSet const & ds1, gdcm::DataSet const & ds2 ) { gdcm::Attribute<0x0020,0x0012> at1; at1.Set( ds1 ); gdcm::Attribute<0x0020,0x0012> at2; at2.Set( ds2 ); return at1 < at2; } bool SortBySeqName(gdcm::DataSet const & ds1, gdcm::DataSet const & ds2 ) { gdcm::Attribute<0x0018, 0x0024> at1; at1.Set( ds1 ); gdcm::Attribute<0x0018, 0x0024> at2; at2.Set( ds2 ); std::string str1 = at1.GetValue().Trim(); std::string str2 = at2.GetValue().Trim(); return std::lexicographical_compare(str1.begin(), str1.end(), str2.begin(), str2.end() ); } void QmitkDiffusionDicomImport::Status(QString status) { mitk::StatusBar::GetInstance()->DisplayText(status.toAscii()); MITK_INFO << status.toStdString().c_str(); } void QmitkDiffusionDicomImport::Status(std::string status) { mitk::StatusBar::GetInstance()->DisplayText(status.c_str()); MITK_INFO << status.c_str(); } void QmitkDiffusionDicomImport::Status(const char* status) { mitk::StatusBar::GetInstance()->DisplayText(status); MITK_INFO << status; } void QmitkDiffusionDicomImport::Error(QString status) { mitk::StatusBar::GetInstance()->DisplayErrorText(status.toAscii()); MITK_ERROR << status.toStdString().c_str(); } void QmitkDiffusionDicomImport::Error(std::string status) { mitk::StatusBar::GetInstance()->DisplayErrorText(status.c_str()); MITK_ERROR << status.c_str(); } void QmitkDiffusionDicomImport::Error(const char* status) { mitk::StatusBar::GetInstance()->DisplayErrorText(status); MITK_ERROR << status; } void QmitkDiffusionDicomImport::PrintMemoryUsage() { size_t processSize = mitk::MemoryUtilities::GetProcessMemoryUsage(); size_t totalSize = mitk::MemoryUtilities::GetTotalSizeOfPhysicalRam(); float percentage = ( (float) processSize / (float) totalSize ) * 100.0; MITK_INFO << "Current memory usage: " << GetMemoryDescription( processSize, percentage ); } std::string QmitkDiffusionDicomImport::FormatMemorySize( size_t size ) { double val = size; std::string descriptor("B"); if ( val >= 1000.0 ) { val /= 1024.0; descriptor = "KB"; } if ( val >= 1000.0 ) { val /= 1024.0; descriptor = "MB"; } if ( val >= 1000.0 ) { val /= 1024.0; descriptor = "GB"; } std::ostringstream str; str << std::fixed << std::setprecision(2) << val << " " << descriptor; return str.str(); } std::string QmitkDiffusionDicomImport::FormatPercentage( double val ) { std::ostringstream str; str << std::fixed << std::setprecision(2) << val << " " << "%"; return str.str(); } std::string QmitkDiffusionDicomImport::GetMemoryDescription( size_t processSize, float percentage ) { std::ostringstream str; str << FormatMemorySize(processSize) << " (" << FormatPercentage( percentage ) <<")" ; return str.str(); } void QmitkDiffusionDicomImport::DicomLoadStartLoad() { itk::TimeProbesCollectorBase clock; bool imageSuccessfullySaved = true; try { const std::string& locale = "C"; const std::string& currLocale = setlocale( LC_ALL, NULL ); if ( locale.compare(currLocale)!=0 ) { try { MITK_INFO << " ** Changing locale from " << setlocale(LC_ALL, NULL) << " to '" << locale << "'"; setlocale(LC_ALL, locale.c_str()); } catch(...) { MITK_INFO << "Could not set locale " << locale; } } int nrFolders = m_Controls->listWidget->count(); if(!nrFolders) { Error(QString("No input folders were selected. ABORTING.")); return; } Status(QString("GDCM %1 used for DICOM parsing and sorting!").arg(gdcm::Version::GetVersion())); PrintMemoryUsage(); QString status; mitk::DataNode::Pointer node; mitk::ProgressBar::GetInstance()->AddStepsToDo(2*nrFolders); std::string folder = m_Controls->m_OutputLabel->text().toStdString(); if(berry::Platform::IsWindows()) { folder.append("\\import.log"); } else { folder.append("/import.log"); } ofstream logfile; if(m_OutputFolderNameSet) logfile.open(folder.c_str()); while(m_Controls->listWidget->count()) { // RETREIVE FOLDERNAME QListWidgetItem * item = m_Controls->listWidget->takeItem(0); QString folderName = item->text(); if(m_OutputFolderNameSet) logfile << "Reading " << folderName.toStdString() << '\n'; // PARSING DIRECTORY PrintMemoryUsage(); clock.Start(folderName.toAscii()); std::vector seriesUIDs(0); std::vector > seriesFilenames(0); Status("== Initial Directory Scan =="); if(m_OutputFolderNameSet) logfile << "== Initial Directory Scan ==\n"; gdcm::Directory d; d.Load( folderName.toStdString().c_str(), true ); // recursive ! const gdcm::Directory::FilenamesType &l1 = d.GetFilenames(); const unsigned int ntotalfiles = l1.size(); Status(QString(" ... found %1 different files").arg(ntotalfiles)); if(m_OutputFolderNameSet)logfile << "...found " << ntotalfiles << " different files\n"; Status("Scanning Headers"); if(m_OutputFolderNameSet) logfile << "Scanning Headers\n"; gdcm::Scanner s; const gdcm::Tag t1(0x0020,0x000d); // Study Instance UID const gdcm::Tag t2(0x0020,0x000e); // Series Instance UID const gdcm::Tag t5(0x0028, 0x0010); // number rows const gdcm::Tag t6(0x0028, 0x0011); // number cols s.AddTag( t1 ); s.AddTag( t2 ); s.AddTag( t5 ); s.AddTag( t6 ); bool b = s.Scan( d.GetFilenames() ); if( !b ) { Error("Scanner failed"); if(m_OutputFolderNameSet )logfile << "ERROR: scanner failed\n"; continue; } // Only get the DICOM files: gdcm::Directory::FilenamesType l2 = s.GetKeys(); const int nfiles = l2.size(); if(nfiles < 1) { Error("No DICOM files found"); if(m_OutputFolderNameSet)logfile << "ERROR: No DICOM files found\n"; continue; } Status(QString(" ... successfully scanned %1 headers.").arg(nfiles)); if(m_OutputFolderNameSet) logfile << "...succesfully scanned " << nfiles << " headers\n"; Status("Sorting"); if(m_OutputFolderNameSet) logfile << "Sorting\n"; const gdcm::Scanner::ValuesType &values1 = s.GetValues(t1); int nvalues; if(m_Controls->m_DuplicateID->isChecked()) { nvalues = 1; } else { nvalues = values1.size(); } if(nvalues>1) { Error("Multiple sSeries tudies found. Please limit to 1 study per folder"); if(m_OutputFolderNameSet) logfile << "Multiple series found. Limit to one. If you are convinced this is an error use the merge duplicate study IDs option \n"; continue; } const gdcm::Scanner::ValuesType &values5 = s.GetValues(t5); const gdcm::Scanner::ValuesType &values6 = s.GetValues(t6); if(values5.size()>1 || values6.size()>1) { Error("Folder contains images of unequal dimensions that cannot be combined in one 3d volume. ABORTING."); if(m_OutputFolderNameSet) logfile << "Folder contains images of unequal dimensions that cannot be combined in one 3d volume. ABORTING\n."; continue; } const gdcm::Scanner::ValuesType &values2 = s.GetValues(t2); int nSeries; if(m_Controls->m_DuplicateID->isChecked()) { nSeries = 1; } else { nSeries = values2.size(); } gdcm::Directory::FilenamesType files; if(nSeries > 1) { gdcm::Sorter sorter; sorter.SetSortFunction( SortBySeriesUID ); sorter.StableSort( l2 ); files = sorter.GetFilenames(); } else { files = l2; } unsigned int nTotalAcquis = 0; if(nfiles % nSeries != 0) { Error("Number of files in series not equal, ABORTING"); if(m_OutputFolderNameSet) logfile << "Number of files in series not equal, Some volumes are probably incomplete. ABORTING \n"; continue; } int filesPerSeries = nfiles / nSeries; gdcm::Scanner::ValuesType::const_iterator it2 = values2.begin(); for(int i=0; i 1) // More than one element must have this tag (Not != ) { subsorter.SetSortFunction( SortByAcquisitionNumber ); it = values3.begin(); } else if (values4.size() > 1) { nAcquis = values4.size(); subsorter.SetSortFunction( SortBySeqName ); it = values4.begin(); } // Hotfix for Bug 14758, better fix by selecting always availible tags. else { Error("Sorting tags (0x0020,0x0012) and (0x0018,0x0024) missing, ABORTING"); if(m_OutputFolderNameSet) logfile << "Sorting tags (0x0020,0x0012) and (0x0018,0x0024) missing, ABORTING\n"; continue; } nTotalAcquis += nAcquis; subsorter.Sort( sub ); if(filesPerSeries % nAcquis != 0) { Error("Number of files per acquisition not equal, ABORTING"); if(m_OutputFolderNameSet) logfile << "Number of files per acquisition not equal, ABORTING \n"; continue; } int filesPerAcqu = filesPerSeries / nAcquis; gdcm::Directory::FilenamesType subfiles = subsorter.GetFilenames(); for ( unsigned int j = 0 ; j < nAcquis ; ++j ) { std::string identifier = "serie_" + *it2 + "_acquis_" + *it++; gdcm::IPPSorter ippsorter; gdcm::Directory::FilenamesType ipplist((j)*filesPerAcqu+subfiles.begin(),(j+1)*filesPerAcqu+subfiles.begin()); ippsorter.SetComputeZSpacing( true ); if( !ippsorter.Sort( ipplist ) ) { Error(QString("Failed to sort acquisition %1, ABORTING").arg(identifier.c_str())); if(m_OutputFolderNameSet) logfile << "Failed to sort acquisition " << identifier.c_str() << " , Aborting\n"; continue; } const std::vector & list = ippsorter.GetFilenames(); seriesFilenames.push_back(list); seriesUIDs.push_back(identifier.c_str()); } ++it2; } // Hot Fix for Bug 14758, checking if no file is acuired. if (nTotalAcquis < 1) // Test if zero, if true than error because no file was selected { Error("Nno files in acquisitions, ABORTING"); if(m_OutputFolderNameSet) logfile << "Nno files in acquisitions, ABORTING \n"; continue; } if(nfiles % nTotalAcquis != 0) { Error("Number of files per acquisition differs between series, ABORTING"); if(m_OutputFolderNameSet) logfile << "Number of files per acquisition differs between series, ABORTING \n"; continue; } int slices = nfiles/nTotalAcquis; Status(QString("Series is composed of %1 different 3D volumes with %2 slices.").arg(nTotalAcquis).arg(slices)); if(m_OutputFolderNameSet) logfile << "Series is composed of " << nTotalAcquis << " different 3D volumes with " << slices << " slices\n"; // READING HEADER-INFOS PrintMemoryUsage(); Status(QString("Reading Headers %1").arg(folderName)); if(m_OutputFolderNameSet) logfile << "Reading Headers "<< folderName.toStdString() << "\n"; mitk::DicomDiffusionImageHeaderReader::Pointer headerReader; typedef short PixelValueType; typedef mitk::DicomDiffusionImageReader< PixelValueType, 3 > VolumesReader; VolumesReader::HeaderContainer inHeaders; unsigned int size2 = seriesUIDs.size(); for ( unsigned int i = 0 ; i < size2 ; ++i ) { // Hot Fix for Bug 14459, catching if no valid data in datafile. try { Status(QString("Reading header image #%1/%2").arg(i+1).arg(size2)); headerReader = mitk::DicomDiffusionImageHeaderReader::New(); headerReader->SetSeriesDicomFilenames(seriesFilenames[i]); headerReader->Update(); inHeaders.push_back(headerReader->GetOutput()); } catch (mitk::Exception e) { Error("Could not read file header, ABORTING"); if(m_OutputFolderNameSet) logfile << e; continue; } //Status(std::endl; } mitk::ProgressBar::GetInstance()->Progress(); // // GROUP HEADERS // mitk::GroupDiffusionHeadersFilter::Pointer grouper // = mitk::GroupDiffusionHeadersFilter::New(); // mitk::GroupDiffusionHeadersFilter::OutputType outHeaders; // grouper->SetInput(inHeaders); // grouper->Update(); // outHeaders = grouper->GetOutput(); // READ VOLUMES PrintMemoryUsage(); if(m_OutputFolderNameSet) logfile << "Loading volumes\n"; Status(QString("Loading Volumes %1").arg(folderName)); VolumesReader::Pointer vReader = VolumesReader::New(); VolumesReader::HeaderContainer hc = inHeaders; // hc.insert(hc.end(), outHeaders[1].begin(), outHeaders[1].end() ); // hc.insert(hc.end(), outHeaders[2].begin(), outHeaders[2].end() ); if(hc.size()>1) { vReader->SetHeaders(hc); vReader->Update(); VolumesReader::OutputImageType::Pointer vecImage; vecImage = vReader->GetOutput(); Status(QString("Volumes Loaded (%1)").arg(folderName)); // CONSTRUCT CONTAINER WITH DIRECTIONS typedef vnl_vector_fixed< double, 3 > GradientDirectionType; typedef itk::VectorContainer< unsigned int, GradientDirectionType > GradientDirectionContainerType; GradientDirectionContainerType::Pointer directions = GradientDirectionContainerType::New(); std::vector b_vals; double maxb = 0; for(unsigned int i=0; ibValue; if(maxb vect = hc[i]->DiffusionVector; vect.normalize(); vect *= sqrt(b_vals[i]/maxb); directions->push_back(vect); } // DWI TO DATATREE PrintMemoryUsage(); Status(QString("Initializing Diffusion Image")); if(m_OutputFolderNameSet) logfile << "Initializing Diffusion Image\n"; typedef mitk::DiffusionImage DiffVolumesType; DiffVolumesType::Pointer diffImage = DiffVolumesType::New(); diffImage->SetDirections(directions); diffImage->SetVectorImage(vecImage); diffImage->SetB_Value(maxb); diffImage->InitializeFromVectorImage(); - diffImage->UpdateBValueList(); + diffImage->UpdateBValueMap(); Status(QString("Diffusion Image initialized")); if(m_OutputFolderNameSet) logfile << "Diffusion Image initialized\n"; if(m_Controls->m_DicomLoadAverageDuplicatesCheckbox->isChecked()) { PrintMemoryUsage(); Status(QString("Averaging gradient directions")); logfile << "Averaging gradient directions\n"; diffImage->AverageRedundantGradients(m_Controls->m_Blur->value()); } QString descr = QString("%1_%2_%3") .arg(((inHeaders)[0])->seriesDescription.c_str()) .arg(((inHeaders)[0])->seriesNumber) .arg(((inHeaders)[0])->patientName.c_str()); descr = descr.trimmed(); descr = descr.replace(" ", "_"); if(!m_OutputFolderNameSet) { node=mitk::DataNode::New(); node->SetData( diffImage ); GetDefaultDataStorage()->Add(node); SetDwiNodeProperties(node, descr.toStdString().c_str()); Status(QString("Image %1 added to datastorage").arg(descr)); } else { typedef mitk::NrrdDiffusionImageWriter WriterType; WriterType::Pointer writer = WriterType::New(); QString fullpath = QString("%1/%2.dwi") .arg(m_OutputFolderName) .arg(descr); // if the override option is not checked, we need to make sure that the current filepath // does not point to an existing file if( !(m_Controls->m_OverrideOptionCheckbox->isChecked()) ) { QFile outputFile( fullpath ); // generate new filename if file exists int file_counter = 0; while( outputFile.exists() ) { // copy base name QString newdescr = descr; file_counter++; MITK_WARN << "The file "<< fullpath.toStdString() << " exists already."; QString appendix = QString("_%1").arg( QString::number(file_counter) ); newdescr.append(appendix); fullpath = QString("%1/%2.dwi") .arg(m_OutputFolderName) .arg(newdescr); // set the new generated filename for next check outputFile.setFileName( fullpath ); } } writer->SetFileName(fullpath.toStdString()); writer->SetInput(diffImage); try { writer->Update(); } catch (itk::ExceptionObject &ex) { imageSuccessfullySaved = false; Error(QString("%1\n%2\n%3\n%4\n%5\n%6").arg(ex.GetNameOfClass()).arg(ex.GetFile()).arg(ex.GetLine()).arg(ex.GetLocation()).arg(ex.what()).arg(ex.GetDescription())); logfile << QString("%1\n%2\n%3\n%4\n%5\n%6").arg(ex.GetNameOfClass()).arg(ex.GetFile()).arg(ex.GetLine()).arg(ex.GetLocation()).arg(ex.what()).arg(ex.GetDescription()).toStdString() << "\n"; node=mitk::DataNode::New(); node->SetData( diffImage ); GetDefaultDataStorage()->Add(node); SetDwiNodeProperties(node, descr.toStdString().c_str()); Status(QString("Image %1 added to datastorage").arg(descr)); logfile << "Image " << descr.toStdString() << " added to datastorage\n"; continue ; } Status(QString("Image %1 written to disc (%1)").arg(fullpath.toStdString().c_str())); logfile << "Image " << fullpath.toStdString() << "\n"; } } else { Status(QString("No diffusion information found (%1)").arg(folderName)); if(m_OutputFolderNameSet) logfile << "No diffusion information found "<< folderName.toStdString(); } Status(QString("Finished processing %1 with memory:").arg(folderName)); if(m_OutputFolderNameSet) logfile << "Finished processing " << folderName.toStdString() << "\n"; PrintMemoryUsage(); clock.Stop(folderName.toAscii()); mitk::ProgressBar::GetInstance()->Progress(); int lwidget = m_Controls->listWidget->count(); std::cout << lwidget <GetData(); if (basedata.IsNotNull()) { mitk::RenderingManager::GetInstance()->InitializeViews( basedata->GetTimeSlicedGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); } } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); try { MITK_INFO << " ** Changing locale back from " << setlocale(LC_ALL, NULL) << " to '" << currLocale << "'"; setlocale(LC_ALL, currLocale.c_str()); } catch(...) { MITK_INFO << "Could not reset locale " << currLocale; } } catch (itk::ExceptionObject &ex) { Error(QString("%1\n%2\n%3\n%4\n%5\n%6").arg(ex.GetNameOfClass()).arg(ex.GetFile()).arg(ex.GetLine()).arg(ex.GetLocation()).arg(ex.what()).arg(ex.GetDescription())); return ; } if (!imageSuccessfullySaved) QMessageBox::warning(NULL,"WARNING","One or more files could not be saved! The according files where moved to the datastorage."); Status(QString("Finished import with memory:")); PrintMemoryUsage(); } void QmitkDiffusionDicomImport::SetDwiNodeProperties(mitk::DataNode::Pointer node, std::string name) { node->SetProperty( "IsDWIRawVolume", mitk::BoolProperty::New( true ) ); // set foldername as string property mitk::StringProperty::Pointer nameProp = mitk::StringProperty::New( name ); node->SetProperty( "name", nameProp ); } 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 50d0df7dcf..8fed48bf35 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.cpp @@ -1,634 +1,662 @@ /*=================================================================== 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 // 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 const std::string QmitkPreprocessingView::VIEW_ID = - "org.mitk.views.preprocessing"; + "org.mitk.views.preprocessing"; #define DI_INFO MITK_INFO("DiffusionImaging") typedef float TTensorPixelType; QmitkPreprocessingView::QmitkPreprocessingView() - : QmitkFunctionality(), - m_Controls(NULL), - m_MultiWidget(NULL), - m_DiffusionImage(NULL) + : QmitkFunctionality(), + m_Controls(NULL), + m_MultiWidget(NULL), + m_DiffusionImage(NULL) { } QmitkPreprocessingView::QmitkPreprocessingView(const QmitkPreprocessingView& other) { - Q_UNUSED(other) - throw std::runtime_error("Copy constructor not implemented"); + Q_UNUSED(other) + throw std::runtime_error("Copy constructor not implemented"); } QmitkPreprocessingView::~QmitkPreprocessingView() { } void QmitkPreprocessingView::CreateQtPartControl(QWidget *parent) { - if (!m_Controls) - { - // create GUI widgets - m_Controls = new Ui::QmitkPreprocessingViewControls; - m_Controls->setupUi(parent); - this->CreateConnections(); - - m_Controls->m_MeasurementFrameTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch); - m_Controls->m_MeasurementFrameTable->verticalHeader()->setResizeMode(QHeaderView::Stretch); - } + if (!m_Controls) + { + // create GUI widgets + m_Controls = new Ui::QmitkPreprocessingViewControls; + m_Controls->setupUi(parent); + this->CreateConnections(); + + m_Controls->m_MeasurementFrameTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch); + m_Controls->m_MeasurementFrameTable->verticalHeader()->setResizeMode(QHeaderView::Stretch); + } } void QmitkPreprocessingView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { - m_MultiWidget = &stdMultiWidget; + m_MultiWidget = &stdMultiWidget; } void QmitkPreprocessingView::StdMultiWidgetNotAvailable() { - m_MultiWidget = NULL; + m_MultiWidget = NULL; } void QmitkPreprocessingView::CreateConnections() { - if ( m_Controls ) - { - 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_AdcAverage), SIGNAL(clicked()), this, SLOT(DoAdcAverage()) ); + if ( m_Controls ) + { + 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_AdcAverage), SIGNAL(clicked()), this, SLOT(DoAdcAverage()) ); + connect( (QObject*)(m_Controls->m_B_ValueMap_Rounder_SpinBox), SIGNAL(valueChanged(int)), this, SLOT(UpdateDwiBValueMapRounder(int))); + + + } +} - } +void QmitkPreprocessingView::UpdateDwiBValueMapRounder(int i) +{ + if (m_DiffusionImage.IsNull()) + return; + m_DiffusionImage->SetB_ValueMap_Rounder(i); + m_DiffusionImage->UpdateBValueMap(); + UpdateBValueTableWidget(); } void QmitkPreprocessingView::DoAdcAverage() { if (m_DiffusionImage.IsNull()) - return; + return; typedef mitk::DiffusionImage DiffusionImageType; typedef itk::MultiShellAdcAverageReconstructionImageFilter FilterType; typedef DiffusionImageType::BValueMap BValueMap; BValueMap originalShellMap = m_DiffusionImage->GetB_ValueMap(); GradientDirectionContainerType::Pointer gradientContainer = m_DiffusionImage->GetDirections(); FilterType::Pointer filter = FilterType::New(); filter->SetInput(m_DiffusionImage->GetVectorImage()); filter->SetOriginalGradientDirections(gradientContainer); filter->SetOriginalBValueMap(originalShellMap); - filter->SetB_Value(m_DiffusionImage->GetB_Value()); + filter->SetBValue(m_DiffusionImage->GetB_Value()); filter->Update(); DiffusionImageType::Pointer image = DiffusionImageType::New(); image->SetVectorImage( filter->GetOutput() ); - image->SetB_Value( filter->GetTargetB_Value() ); + image->SetB_Value( filter->GetTargetBValue() ); + //image->SetOriginalDirections( filter->GetTargetGradientDirections() ); image->SetDirections( filter->GetTargetGradientDirections() ); + //image->SetMeasurementFrame( m_DiffusionImage->GetMeasurementFrame() ); image->InitializeFromVectorImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); imageNode->SetName((name+"_averaged").toStdString().c_str()); GetDefaultDataStorage()->Add(imageNode); } -void QmitkPreprocessingView::OnSelectionChanged( std::vector nodes ) +void QmitkPreprocessingView::UpdateBValueTableWidget() { - bool foundDwiVolume = false; - m_DiffusionImage = 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()) ) - { - foundDwiVolume = true; - m_DiffusionImage = dynamic_cast*>(node->GetData()); - m_Controls->m_DiffusionImageLabel->setText(node->GetName().c_str()); - m_SelectedDiffusionNodes.push_back(node); - } - } + if (m_DiffusionImage.IsNull()) + { + 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{ - 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_AdcAverage->setEnabled(foundDwiVolume); - - foreach(QCheckBox * box, m_ReduceGradientCheckboxes) - { - m_Controls->m_ReductionFrame->layout()->removeWidget(box); - delete box; - } - foreach(QSpinBox * box, m_ReduceGradientSpinboxes) - { - m_Controls->m_ReductionFrame->layout()->removeWidget(box); - delete box; - } - m_ReduceGradientCheckboxes.clear(); - m_ReduceGradientSpinboxes.clear(); + typedef mitk::DiffusionImage::BValueMap BValueMap; + typedef mitk::DiffusionImage::BValueMap::iterator BValueMapIterator; - if (foundDwiVolume) + BValueMap bValMap = m_DiffusionImage->GetB_ValueMap(); + BValueMapIterator it = bValMap.begin(); + m_Controls->m_B_ValueMap_TableWidget->clear(); + m_Controls->m_B_ValueMap_TableWidget->setRowCount(bValMap.size() ); + QStringList headerList; + headerList << "b-Value" << "Number of gradients"; + m_Controls->m_B_ValueMap_TableWidget->setHorizontalHeaderLabels(headerList); + + + QCheckBox* checkBox; + QSpinBox* spinBox; + int i = 0 ; + for(;it != bValMap.end(); it++) { - m_Controls->m_InputData->setTitle("Input Data"); - vnl_matrix_fixed< double, 3, 3 > mf = m_DiffusionImage->GetMeasurementFrame(); - 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(); - item->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter); - item->setText(QString::number(mf.get(r,c))); - m_Controls->m_MeasurementFrameTable->setItem(r,c,item); - } - - typedef mitk::DiffusionImage::BValueMap BValueMap; - typedef mitk::DiffusionImage::BValueMap::iterator BValueMapIterator; - - BValueMap bValMap = m_DiffusionImage->GetB_ValueMap(); - BValueMapIterator it = bValMap.begin(); - m_Controls->m_BvalueTable->clear(); - m_Controls->m_BvalueTable->setRowCount(bValMap.size() ); - QStringList headerList; - headerList << "b-Value" << "Number of gradients"; - m_Controls->m_BvalueTable->setHorizontalHeaderLabels(headerList); - - - QCheckBox* checkBox; - QSpinBox* spinBox; - int i = 0 ; - for(;it != bValMap.end(); it++) - { - m_Controls->m_BvalueTable->setItem(i,0,new QTableWidgetItem(QString::number(it->first))); - m_Controls->m_BvalueTable->setItem(i,1,new QTableWidgetItem(QString::number(it->second.size()))); - - // Reduce Gradients GUI adaption - if(it->first != 0 && bValMap.size() > 1){ - checkBox = new QCheckBox(QString::number(it->first) + " with " + QString::number(it->second.size()) + " directions"); - checkBox->setEnabled(true); - checkBox->setChecked(true); - checkBox->setCheckable(true); - m_ReduceGradientCheckboxes.push_back(checkBox); - m_Controls->m_ReductionFrame->layout()->addWidget(checkBox); - - spinBox = new QSpinBox(); - spinBox->setValue(std::ceil((float)it->second.size()/2)); - spinBox->setMaximum(it->second.size()); - spinBox->setMinimum(0); - m_ReduceGradientSpinboxes.push_back(spinBox); - m_Controls->m_ReductionFrame->layout()->addWidget(spinBox); - } - i++; - } + m_Controls->m_B_ValueMap_TableWidget->setItem(i,0,new QTableWidgetItem(QString::number(it->first))); + m_Controls->m_B_ValueMap_TableWidget->setItem(i,1,new QTableWidgetItem(QString::number(it->second.size()))); + + // Reduce Gradients GUI adaption + if(it->first != 0 && bValMap.size() > 1){ + checkBox = new QCheckBox(QString::number(it->first) + " with " + QString::number(it->second.size()) + " directions"); + checkBox->setEnabled(true); + checkBox->setChecked(true); + checkBox->setCheckable(true); + m_ReduceGradientCheckboxes.push_back(checkBox); + m_Controls->m_ReductionFrame->layout()->addWidget(checkBox); + + spinBox = new QSpinBox(); + spinBox->setValue(std::ceil((float)it->second.size()/2)); + spinBox->setMaximum(it->second.size()); + spinBox->setMinimum(0); + m_ReduceGradientSpinboxes.push_back(spinBox); + m_Controls->m_ReductionFrame->layout()->addWidget(spinBox); + } + i++; } - else + } + +} + +void QmitkPreprocessingView::OnSelectionChanged( std::vector nodes ) +{ + bool foundDwiVolume = false; + m_DiffusionImage = 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()) ) { - 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_BvalueTable->clear(); - m_Controls->m_BvalueTable->setRowCount(1); - QStringList headerList; - headerList << "b-Value" << "Number of gradients"; - m_Controls->m_BvalueTable->setHorizontalHeaderLabels(headerList); - m_Controls->m_BvalueTable->setItem(0,0,new QTableWidgetItem("-")); - m_Controls->m_BvalueTable->setItem(0,1,new QTableWidgetItem("-")); - m_Controls->m_DiffusionImageLabel->setText("mandatory"); - m_Controls->m_InputData->setTitle("Please Select Input Data"); + foundDwiVolume = true; + m_DiffusionImage = dynamic_cast*>(node->GetData()); + m_Controls->m_DiffusionImageLabel->setText(node->GetName().c_str()); + m_SelectedDiffusionNodes.push_back(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); + if(foundDwiVolume)m_Controls->m_B_ValueMap_Rounder_SpinBox->setValue(m_DiffusionImage->GetB_ValueMap_Rounder()); + + + foreach(QCheckBox * box, m_ReduceGradientCheckboxes) + { + m_Controls->m_ReductionFrame->layout()->removeWidget(box); + delete box; + } + foreach(QSpinBox * box, m_ReduceGradientSpinboxes) + { + m_Controls->m_ReductionFrame->layout()->removeWidget(box); + delete box; + } + m_ReduceGradientCheckboxes.clear(); + m_ReduceGradientSpinboxes.clear(); + + UpdateBValueTableWidget(); + + if (foundDwiVolume) + { + m_Controls->m_InputData->setTitle("Input Data"); + vnl_matrix_fixed< double, 3, 3 > mf = m_DiffusionImage->GetMeasurementFrame(); + 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(); + item->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter); + item->setText(QString::number(mf.get(r,c))); + m_Controls->m_MeasurementFrameTable->setItem(r,c,item); + } + } + 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); + } + + m_Controls->m_DiffusionImageLabel->setText("mandatory"); + m_Controls->m_InputData->setTitle("Please Select Input Data"); + } } void QmitkPreprocessingView::Activated() { - QmitkFunctionality::Activated(); + QmitkFunctionality::Activated(); } void QmitkPreprocessingView::Deactivated() { - QmitkFunctionality::Deactivated(); + QmitkFunctionality::Deactivated(); } void QmitkPreprocessingView::DoHalfSphereGradientDirections() { - GradientDirectionContainerType::Pointer gradientContainer = m_DiffusionImage->GetDirections(); + GradientDirectionContainerType::Pointer gradientContainer = m_DiffusionImage->GetDirections(); - for (int j=0; jSize(); j++) - if (gradientContainer->at(j)[0]<0) - gradientContainer->at(j) = -gradientContainer->at(j); - m_DiffusionImage->SetDirections(gradientContainer); + for (int j=0; jSize(); j++) + if (gradientContainer->at(j)[0]<0) + gradientContainer->at(j) = -gradientContainer->at(j); + m_DiffusionImage->SetDirections(gradientContainer); } void QmitkPreprocessingView::DoApplyMesurementFrame() { - if (m_DiffusionImage.IsNull()) - return; + if (m_DiffusionImage.IsNull()) + 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(); - } - m_DiffusionImage->SetMeasurementFrame(mf); + 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(); + } + m_DiffusionImage->SetMeasurementFrame(mf); } void QmitkPreprocessingView::DoShowGradientDirections() { - if (m_DiffusionImage.IsNull()) - return; - - int maxIndex = 0; - int maxSize = m_DiffusionImage->GetDimension(0); - if (maxSizeGetDimension(1)) - { - maxSize = m_DiffusionImage->GetDimension(1); - maxIndex = 1; - } - if (maxSizeGetDimension(2)) - { - maxSize = m_DiffusionImage->GetDimension(2); - maxIndex = 2; - } - - mitk::Point3D origin = m_DiffusionImage->GetGeometry()->GetOrigin(); - mitk::PointSet::Pointer originSet = mitk::PointSet::New(); - - typedef mitk::DiffusionImage::BValueMap BValueMap; - typedef mitk::DiffusionImage::BValueMap::iterator BValueMapIterator; - BValueMap bValMap = m_DiffusionImage->GetB_ValueMap(); + if (m_DiffusionImage.IsNull()) + return; + + int maxIndex = 0; + int maxSize = m_DiffusionImage->GetDimension(0); + if (maxSizeGetDimension(1)) + { + maxSize = m_DiffusionImage->GetDimension(1); + maxIndex = 1; + } + if (maxSizeGetDimension(2)) + { + maxSize = m_DiffusionImage->GetDimension(2); + maxIndex = 2; + } + + mitk::Point3D origin = m_DiffusionImage->GetGeometry()->GetOrigin(); + mitk::PointSet::Pointer originSet = mitk::PointSet::New(); + + typedef mitk::DiffusionImage::BValueMap BValueMap; + typedef mitk::DiffusionImage::BValueMap::iterator BValueMapIterator; + BValueMap bValMap = m_DiffusionImage->GetB_ValueMap(); - GradientDirectionContainerType::Pointer gradientContainer = m_DiffusionImage->GetDirections(); - mitk::Geometry3D::Pointer geometry = m_DiffusionImage->GetGeometry(); - int shellCount = 1; - for(BValueMapIterator it = bValMap.begin(); it!=bValMap.end(); ++it) + GradientDirectionContainerType::Pointer gradientContainer = m_DiffusionImage->GetDirections(); + mitk::Geometry3D::Pointer geometry = m_DiffusionImage->GetGeometry(); + int shellCount = 1; + for(BValueMapIterator it = bValMap.begin(); it!=bValMap.end(); ++it) + { + mitk::PointSet::Pointer pointset = mitk::PointSet::New(); + for (int j=0; jsecond.size(); j++) { - mitk::PointSet::Pointer pointset = mitk::PointSet::New(); - for (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_DiffusionImage->GetDimension(0)/2; - ip[1] = v[1]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[1]-0.5*geometry->GetSpacing()[1] + geometry->GetSpacing()[1]*m_DiffusionImage->GetDimension(1)/2; - ip[2] = v[2]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[2]-0.5*geometry->GetSpacing()[2] + geometry->GetSpacing()[2]*m_DiffusionImage->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_DiffusionImage->GetDimension(0)/2; - ip[1] = v[1]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[1]-0.5*geometry->GetSpacing()[1] + geometry->GetSpacing()[1]*m_DiffusionImage->GetDimension(1)/2; - ip[2] = v[2]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[2]-0.5*geometry->GetSpacing()[2] + geometry->GetSpacing()[2]*m_DiffusionImage->GetDimension(2)/2; - - originSet->InsertPoint(j, ip); - } - } - if (it->firstSetData(pointset); - QString name = m_SelectedDiffusionNodes.front()->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)); - 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()); - shellCount++; + 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_DiffusionImage->GetDimension(0)/2; + ip[1] = v[1]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[1]-0.5*geometry->GetSpacing()[1] + geometry->GetSpacing()[1]*m_DiffusionImage->GetDimension(1)/2; + ip[2] = v[2]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[2]-0.5*geometry->GetSpacing()[2] + geometry->GetSpacing()[2]*m_DiffusionImage->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_DiffusionImage->GetDimension(0)/2; + ip[1] = v[1]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[1]-0.5*geometry->GetSpacing()[1] + geometry->GetSpacing()[1]*m_DiffusionImage->GetDimension(1)/2; + ip[2] = v[2]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[2]-0.5*geometry->GetSpacing()[2] + geometry->GetSpacing()[2]*m_DiffusionImage->GetDimension(2)/2; + + originSet->InsertPoint(j, ip); + } } + if (it->firstSetData(originSet); + node->SetData(pointset); QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); - name += "_Origin"; + name += "_Shell_"; + name += QString::number(it->first); node->SetName(name.toStdString().c_str()); node->SetProperty("pointsize", mitk::FloatProperty::New((float)maxSize/50)); - node->SetProperty("color", mitk::ColorProperty::New(1,1,1)); + 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()); + shellCount++; + } + + // add origin to datastorage + mitk::DataNode::Pointer node = mitk::DataNode::New(); + node->SetData(originSet); + QString name = m_SelectedDiffusionNodes.front()->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()); } void QmitkPreprocessingView::DoReduceGradientDirections() { - if (m_DiffusionImage.IsNull()) - return; + if (m_DiffusionImage.IsNull()) + return; - typedef mitk::DiffusionImage DiffusionImageType; - typedef itk::ElectrostaticRepulsionDiffusionGradientReductionFilter FilterType; - typedef DiffusionImageType::BValueMap BValueMap; + typedef mitk::DiffusionImage DiffusionImageType; + typedef itk::ElectrostaticRepulsionDiffusionGradientReductionFilter FilterType; + typedef DiffusionImageType::BValueMap BValueMap; - // GetShellSelection from GUI - BValueMap shellSlectionMap; - BValueMap originalShellMap = m_DiffusionImage->GetB_ValueMap(); - std::vector newNumGradientDirections; - int shellCounter = 0; + // GetShellSelection from GUI + BValueMap shellSlectionMap; + BValueMap originalShellMap = m_DiffusionImage->GetB_ValueMap(); + std::vector newNumGradientDirections; + int shellCounter = 0; - foreach(QCheckBox * box , m_ReduceGradientCheckboxes) + foreach(QCheckBox * box , m_ReduceGradientCheckboxes) + { + if(box->isChecked()) { - if(box->isChecked()) - { - double BValue = (box->text().split(' ')).at(0).toDouble(); - shellSlectionMap[BValue] = originalShellMap[BValue]; - newNumGradientDirections.push_back(m_ReduceGradientSpinboxes.at(shellCounter)->value()); - } - shellCounter++; + double BValue = (box->text().split(' ')).at(0).toDouble(); + shellSlectionMap[BValue] = originalShellMap[BValue]; + newNumGradientDirections.push_back(m_ReduceGradientSpinboxes.at(shellCounter)->value()); } + shellCounter++; + } - if (newNumGradientDirections.empty()) - return; + if (newNumGradientDirections.empty()) + return; - GradientDirectionContainerType::Pointer gradientContainer = m_DiffusionImage->GetDirections(); - FilterType::Pointer filter = FilterType::New(); - filter->SetInput(m_DiffusionImage->GetVectorImage()); - filter->SetOriginalGradientDirections(gradientContainer); - filter->SetNumGradientDirections(newNumGradientDirections); - filter->SetOriginalBValueMap(originalShellMap); - filter->SetShellSelectionBValueMap(shellSlectionMap); - filter->Update(); + GradientDirectionContainerType::Pointer gradientContainer = m_DiffusionImage->GetDirections(); + FilterType::Pointer filter = FilterType::New(); + filter->SetInput(m_DiffusionImage->GetVectorImage()); + filter->SetOriginalGradientDirections(gradientContainer); + filter->SetNumGradientDirections(newNumGradientDirections); + filter->SetOriginalBValueMap(originalShellMap); + filter->SetShellSelectionBValueMap(shellSlectionMap); + filter->Update(); - DiffusionImageType::Pointer image = DiffusionImageType::New(); - image->SetVectorImage( filter->GetOutput() ); - image->SetB_Value(m_DiffusionImage->GetB_Value()); - image->SetDirections(filter->GetGradientDirections()); - image->SetMeasurementFrame(m_DiffusionImage->GetMeasurementFrame()); - image->InitializeFromVectorImage(); + DiffusionImageType::Pointer image = DiffusionImageType::New(); + image->SetVectorImage( filter->GetOutput() ); + image->SetB_Value(m_DiffusionImage->GetB_Value()); + image->SetDirections(filter->GetGradientDirections()); + image->SetMeasurementFrame(m_DiffusionImage->GetMeasurementFrame()); + image->InitializeFromVectorImage(); - mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); - imageNode->SetData( image ); - QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); + mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); + imageNode->SetData( image ); + QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); - foreach(QSpinBox* box, m_ReduceGradientSpinboxes) - { - name += "_"; - name += QString::number(box->value()); - } + foreach(QSpinBox* box, m_ReduceGradientSpinboxes) + { + name += "_"; + name += QString::number(box->value()); + } - imageNode->SetName(name.toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode); + imageNode->SetName(name.toStdString().c_str()); + GetDefaultDataStorage()->Add(imageNode); } void QmitkPreprocessingView::MergeDwis() { - typedef mitk::DiffusionImage DiffusionImageType; - typedef DiffusionImageType::GradientDirectionContainerType GradientContainerType; + typedef mitk::DiffusionImage DiffusionImageType; + typedef DiffusionImageType::GradientDirectionContainerType GradientContainerType; - if (m_SelectedDiffusionNodes.size()<2) - return; + if (m_SelectedDiffusionNodes.size()<2) + return; - typedef itk::VectorImage DwiImageType; - typedef DwiImageType::PixelType DwiPixelType; - typedef DwiImageType::RegionType DwiRegionType; - typedef std::vector< DwiImageType::Pointer > DwiImageContainerType; + typedef itk::VectorImage DwiImageType; + typedef DwiImageType::PixelType DwiPixelType; + typedef DwiImageType::RegionType DwiRegionType; + typedef std::vector< DwiImageType::Pointer > DwiImageContainerType; - typedef std::vector< GradientContainerType::Pointer > GradientListContainerType; + typedef std::vector< GradientContainerType::Pointer > GradientListContainerType; - DwiImageContainerType imageContainer; - GradientListContainerType gradientListContainer; - std::vector< double > bValueContainer; + DwiImageContainerType imageContainer; + GradientListContainerType gradientListContainer; + std::vector< double > bValueContainer; - QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); - for (int i=0; iGetName().c_str(); + for (int i=0; i* >( m_SelectedDiffusionNodes.at(i)->GetData() ); + if ( dwi.IsNotNull() ) { - DiffusionImageType::Pointer dwi = dynamic_cast< mitk::DiffusionImage* >( m_SelectedDiffusionNodes.at(i)->GetData() ); - if ( dwi.IsNotNull() ) - { - imageContainer.push_back(dwi->GetVectorImage()); - gradientListContainer.push_back(dwi->GetDirections()); - bValueContainer.push_back(dwi->GetB_Value()); - if (i>0) - { - name += "+"; - name += m_SelectedDiffusionNodes.at(i)->GetName().c_str(); - } - } + imageContainer.push_back(dwi->GetVectorImage()); + gradientListContainer.push_back(dwi->GetDirections()); + bValueContainer.push_back(dwi->GetB_Value()); + if (i>0) + { + name += "+"; + name += m_SelectedDiffusionNodes.at(i)->GetName().c_str(); + } } + } - typedef itk::MergeDiffusionImagesFilter FilterType; - FilterType::Pointer filter = FilterType::New(); - filter->SetImageVolumes(imageContainer); - filter->SetGradientLists(gradientListContainer); - filter->SetBValues(bValueContainer); - filter->Update(); + 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(); - DiffusionImageType::Pointer image = DiffusionImageType::New(); - image->SetVectorImage( filter->GetOutput() ); - image->SetB_Value(filter->GetB_Value()); - image->SetDirections(filter->GetOutputGradients()); - image->SetMeasurementFrame(mf); - image->InitializeFromVectorImage(); - - mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); - imageNode->SetData( image ); - imageNode->SetName(name.toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode); + vnl_matrix_fixed< double, 3, 3 > mf; mf.set_identity(); + DiffusionImageType::Pointer image = DiffusionImageType::New(); + image->SetVectorImage( filter->GetOutput() ); + image->SetB_Value(filter->GetB_Value()); + image->SetDirections(filter->GetOutputGradients()); + image->SetMeasurementFrame(mf); + image->InitializeFromVectorImage(); + + mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); + imageNode->SetData( image ); + imageNode->SetName(name.toStdString().c_str()); + GetDefaultDataStorage()->Add(imageNode); } void QmitkPreprocessingView::ExtractB0() { - typedef mitk::DiffusionImage DiffusionImageType; - typedef DiffusionImageType::GradientDirectionContainerType GradientContainerType; + typedef mitk::DiffusionImage DiffusionImageType; + typedef DiffusionImageType::GradientDirectionContainerType GradientContainerType; - int nrFiles = m_SelectedDiffusionNodes.size(); - if (!nrFiles) return; + int nrFiles = m_SelectedDiffusionNodes.size(); + if (!nrFiles) return; - // call the extraction withou averaging if the check-box is checked - if( this->m_Controls->m_CheckExtractAll->isChecked() ) - { - DoExtractBOWithoutAveraging(); - return; - } + // 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() ); + 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 - { + std::vector nodes; + while ( itemiter != itemiterend ) // for all items + { - DiffusionImageType* vols = - static_cast( - (*itemiter)->GetData()); + DiffusionImageType* vols = + static_cast( + (*itemiter)->GetData()); - std::string nodename; - (*itemiter)->GetStringProperty("name", nodename); + std::string nodename; + (*itemiter)->GetStringProperty("name", nodename); - // Extract image using found index - typedef itk::B0ImageExtractionImageFilter FilterType; - FilterType::Pointer filter = FilterType::New(); - filter->SetInput(vols->GetVectorImage()); - filter->SetDirections(vols->GetDirections()); - filter->Update(); + // Extract image using found index + typedef itk::B0ImageExtractionImageFilter FilterType; + FilterType::Pointer filter = FilterType::New(); + filter->SetInput(vols->GetVectorImage()); + filter->SetDirections(vols->GetDirections()); + filter->Update(); - 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")); + 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")); - GetDefaultDataStorage()->Add(node); + GetDefaultDataStorage()->Add(node); - ++itemiter; - } + ++itemiter; + } } void QmitkPreprocessingView::DoExtractBOWithoutAveraging() { - // typedefs - typedef mitk::DiffusionImage DiffusionImageType; - typedef DiffusionImageType::GradientDirectionContainerType GradientContainerType; - typedef itk::B0ImageExtractionToSeparateImageFilter< short, short> FilterType; - - // check number of selected objects, return if empty - int nrFiles = m_SelectedDiffusionNodes.size(); - if (!nrFiles) - return; + // typedefs + typedef mitk::DiffusionImage DiffusionImageType; + typedef DiffusionImageType::GradientDirectionContainerType GradientContainerType; + typedef itk::B0ImageExtractionToSeparateImageFilter< short, short> FilterType; - mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_SelectedDiffusionNodes.begin() ); - mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_SelectedDiffusionNodes.end() ); + // check number of selected objects, return if empty + int nrFiles = m_SelectedDiffusionNodes.size(); + if (!nrFiles) + return; - while ( itemiter != itemiterend ) // for all items - { - DiffusionImageType* vols = - static_cast( - (*itemiter)->GetData()); + mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_SelectedDiffusionNodes.begin() ); + mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_SelectedDiffusionNodes.end() ); - std::string nodename; - (*itemiter)->GetStringProperty("name", nodename); + while ( itemiter != itemiterend ) // for all items + { + DiffusionImageType* vols = + static_cast( + (*itemiter)->GetData()); - // Extract image using found index - FilterType::Pointer filter = FilterType::New(); - filter->SetInput(vols->GetVectorImage()); - filter->SetDirections(vols->GetDirections()); - filter->Update(); + std::string nodename; + (*itemiter)->GetStringProperty("name", nodename); - 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")); + // Extract image using found index + FilterType::Pointer filter = FilterType::New(); + filter->SetInput(vols->GetVectorImage()); + filter->SetDirections(vols->GetDirections()); + filter->Update(); - GetDefaultDataStorage()->Add(node); + 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")); - ++itemiter; - } + GetDefaultDataStorage()->Add(node); + + ++itemiter; + } } void QmitkPreprocessingView::AverageGradients() { - int nrFiles = m_SelectedDiffusionNodes.size(); - if (!nrFiles) return; + 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() ); + 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 - { + std::vector nodes; + while ( itemiter != itemiterend ) // for all items + { - mitk::DiffusionImage* vols = - static_cast*>( - (*itemiter)->GetData()); + mitk::DiffusionImage* vols = + static_cast*>( + (*itemiter)->GetData()); - vols->AverageRedundantGradients(m_Controls->m_Blur->value()); + vols->AverageRedundantGradients(m_Controls->m_Blur->value()); - ++itemiter; - } + ++itemiter; + } } 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 0e25d361f8..8741bd1a7f 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.h +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.h @@ -1,110 +1,113 @@ /*=================================================================== 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 #include "ui_QmitkPreprocessingViewControls.h" #include "mitkDiffusionImage.h" 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 vnl_vector_fixed< double, 3 > GradientDirectionType; typedef itk::VectorContainer< unsigned int, GradientDirectionType > GradientDirectionContainerType; QmitkPreprocessingView(); QmitkPreprocessingView(const QmitkPreprocessingView& other); 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 DoApplyMesurementFrame(); void DoReduceGradientDirections(); void DoShowGradientDirections(); void DoHalfSphereGradientDirections(); void DoAdcAverage(); + void UpdateDwiBValueMapRounder(int i); protected: /** Called by ExtractB0 if check-box activated, extracts all b0 images without averaging */ void DoExtractBOWithoutAveraging(); + void UpdateBValueTableWidget(); + /// \brief called by QmitkFunctionality when DataManager's selection has changed virtual void OnSelectionChanged( std::vector nodes ); Ui::QmitkPreprocessingViewControls* m_Controls; QmitkStdMultiWidget* m_MultiWidget; void SetDefaultNodeProperties(mitk::DataNode::Pointer node, std::string name); mitk::DiffusionImage::Pointer m_DiffusionImage; std::vector< mitk::DataNode::Pointer > m_SelectedDiffusionNodes; QList m_ReduceGradientCheckboxes; QList m_ReduceGradientSpinboxes; }; #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 5b4cb3ef19..2827d6fc3b 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingViewControls.ui +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingViewControls.ui @@ -1,562 +1,578 @@ QmitkPreprocessingViewControls 0 0 892 1114 0 0 false QmitkPreprocessingViewControls true Please Select Input Data Raw DWI: <html><head/><body><p><span style=" color:#ff0000;">mandatory</span></p></body></html> true 0 0 Info - - + + 0 0 Qt::ScrollBarAsNeeded Qt::ScrollBarAlwaysOff true 100 true false true b-Value Number of gradients - - - - Qt::Horizontal + + + + <html><head/><body><p>This rounder allowes you to manipulate <a name="result_box"/>the classification of the b-Values to the corresponding shells. But is not manipulating the original b-Values or data.</p></body></html> - - - 40 - 20 - + + 1 - + + 10000 + + + 10 + + - + false Generate pointset displaying the gradient vectors (applied measurement frame). Show gradients + + + + Qt::Horizontal + + + + 40 + 20 + + + + Non diffusion weighted image 0 30 Average and extract all images that were acquired without diffusion weighting. true false If multiple baseline acquisitions are present, the default behaviour is to output an averaged image. Extract B0 Create a 3D+t data set containing all b0 images as timesteps Extract all B0 images without averaging Modify DWI QFrame::NoFrame QFrame::Raised 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 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 redundant gradients false <html><head/><body><p>Create a new Diffusion Weighted Image (DWI) using an ADC average over all q-shells.</p></body></html> ADC Average (Multi-Shell) Qt::Horizontal QFrame::NoFrame QFrame::Raised 0 9 Specify desired number of gradients per shell: 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 Qt::Horizontal false Sometimes the gradient directions are not located on one half sphere. Mirror gradients to half sphere Merge selected images false Merges selected DWIs of same dimension. If several b-values are present, the resulting image will contain multiple b-shells. Merge selected DWIs 0 0 Measurment frame 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 Apply new measurement frame Qt::Vertical 20 40