void QmitkTensorReconstructionView::ResidualClicked(int slice, int volume) { // Use image coord to reset crosshair // Find currently selected diffusion image // Update Label // to do: This position should be modified in order to skip B0 volumes that are not taken into account // when calculating residuals // Find the diffusion image mitk::DiffusionImage<DiffusionPixelType>* diffImage; mitk::DataNode::Pointer correctNode; mitk::Geometry3D* geometry; if (m_DiffusionImage.IsNotNull()) { diffImage = static_cast<mitk::DiffusionImage<DiffusionPixelType>*>(m_DiffusionImage->GetData()); geometry = diffImage->GetGeometry(); // Remember the node whose display index must be updated correctNode = mitk::DataNode::New(); correctNode = m_DiffusionImage; } if(diffImage != NULL) { typedef vnl_vector_fixed< double, 3 > GradientDirectionType; typedef itk::VectorContainer< unsigned int, GradientDirectionType > GradientDirectionContainerType; GradientDirectionContainerType::Pointer dirs = diffImage->GetDirections(); for(int i=0; i<dirs->Size() && i<=volume; i++) { GradientDirectionType grad = dirs->ElementAt(i); // check if image is b0 weighted if(fabs(grad[0]) < 0.001 && fabs(grad[1]) < 0.001 && fabs(grad[2]) < 0.001) { volume++; } } QString pos = "Volume: "; pos.append(QString::number(volume)); pos.append(", Slice: "); pos.append(QString::number(slice)); m_Controls->m_PositionLabel->setText(pos); if(correctNode) { int oldDisplayVal; correctNode->GetIntProperty("DisplayChannel", oldDisplayVal); std::string oldVal = QString::number(oldDisplayVal).toStdString(); std::string newVal = QString::number(volume).toStdString(); correctNode->SetIntProperty("DisplayChannel",volume); correctNode->SetSelected(true); this->FirePropertyChanged("DisplayChannel", oldVal, newVal); correctNode->UpdateOutputInformation(); mitk::Point3D p3 = m_MultiWidget->GetCrossPosition(); itk::Index<3> ix; geometry->WorldToIndex(p3, ix); // ix[2] = slice; mitk::Vector3D vec; vec[0] = ix[0]; vec[1] = ix[1]; vec[2] = slice; mitk::Vector3D v3New; geometry->IndexToWorld(vec, v3New); mitk::Point3D origin = geometry->GetOrigin(); mitk::Point3D p3New; p3New[0] = v3New[0] + origin[0]; p3New[1] = v3New[1] + origin[1]; p3New[2] = v3New[2] + origin[2]; m_MultiWidget->MoveCrossToPosition(p3New); m_MultiWidget->RequestUpdate(); } } }
void QmitkTensorReconstructionView::ItkTensorReconstruction(mitk::DataStorage::SetOfObjects::Pointer inImages) { try { itk::TimeProbe clock; int nrFiles = inImages->size(); if (!nrFiles) return; QString status; mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles); mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() ); std::vector<mitk::DataNode::Pointer> nodes; while ( itemiter != itemiterend ) // for all items { mitk::DiffusionImage<DiffusionPixelType>* vols = static_cast<mitk::DiffusionImage<DiffusionPixelType>*>( (*itemiter)->GetData()); std::string nodename; (*itemiter)->GetStringProperty("name", nodename); ++itemiter; // TENSOR RECONSTRUCTION clock.Start(); MITK_DEBUG << "Tensor reconstruction "; mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Tensor reconstruction for %s", nodename.c_str()).toAscii()); typedef itk::DiffusionTensor3DReconstructionImageFilter< DiffusionPixelType, DiffusionPixelType, TTensorPixelType > TensorReconstructionImageFilterType; TensorReconstructionImageFilterType::Pointer tensorReconstructionFilter = TensorReconstructionImageFilterType::New(); typedef mitk::DiffusionImage<DiffusionPixelType> DiffusionImageType; typedef DiffusionImageType::GradientDirectionContainerType GradientDirectionContainerType; GradientDirectionContainerType::Pointer gradientContainerCopy = GradientDirectionContainerType::New(); for(GradientDirectionContainerType::ConstIterator it = vols->GetDirections()->Begin(); it != vols->GetDirections()->End(); it++) { gradientContainerCopy->push_back(it.Value()); } tensorReconstructionFilter->SetGradientImage( gradientContainerCopy, vols->GetVectorImage() ); tensorReconstructionFilter->SetBValue(vols->GetB_Value()); tensorReconstructionFilter->SetThreshold( m_Controls->m_TensorReconstructionThreshold->value() ); tensorReconstructionFilter->Update(); clock.Stop(); MITK_DEBUG << "took " << clock.GetMeanTime() << "s."; // TENSORS TO DATATREE mitk::TensorImage::Pointer image = mitk::TensorImage::New(); typedef itk::Image<itk::DiffusionTensor3D<TTensorPixelType>, 3> TensorImageType; TensorImageType::Pointer tensorImage; tensorImage = tensorReconstructionFilter->GetOutput(); // Check the tensor for negative eigenvalues if(m_Controls->m_CheckNegativeEigenvalues->isChecked()) { typedef itk::ImageRegionIterator<TensorImageType> TensorImageIteratorType; TensorImageIteratorType tensorIt(tensorImage, tensorImage->GetRequestedRegion()); tensorIt.GoToBegin(); while(!tensorIt.IsAtEnd()) { typedef itk::DiffusionTensor3D<TTensorPixelType> TensorType; //typedef itk::Tensor<TTensorPixelType, 3> TensorType2; TensorType tensor = tensorIt.Get(); TensorType::EigenValuesArrayType ev; tensor.ComputeEigenValues(ev); for(unsigned int i=0; i<ev.Size(); i++) { if(ev[i] < 0.0) { tensor.Fill(0.0); tensorIt.Set(tensor); break; } } ++tensorIt; } } tensorImage->SetDirection( vols->GetVectorImage()->GetDirection() ); image->InitializeByItk( tensorImage.GetPointer() ); image->SetVolume( tensorReconstructionFilter->GetOutput()->GetBufferPointer() ); mitk::DataNode::Pointer node=mitk::DataNode::New(); node->SetData( image ); QString newname; newname = newname.append(nodename.c_str()); newname = newname.append("_dti"); SetDefaultNodeProperties(node, newname.toStdString()); nodes.push_back(node); mitk::ProgressBar::GetInstance()->Progress(); } std::vector<mitk::DataNode::Pointer>::iterator nodeIt; for(nodeIt = nodes.begin(); nodeIt != nodes.end(); ++nodeIt) GetDefaultDataStorage()->Add(*nodeIt); mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toAscii()); m_MultiWidget->RequestUpdate(); } catch (itk::ExceptionObject &ex) { MITK_INFO << ex ; QMessageBox::information(0, "Reconstruction not possible:", ex.GetDescription()); return; } }
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<std::string> seriesUIDs(0); std::vector<std::vector<std::string> > 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(); gdcm::Directory::FilenamesType::iterator it; for (it = l2.begin() ; it != l2.end(); ++it) { MITK_INFO << "-------FN " << *it; } 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 ); if (sorter.StableSort( l2 )) { files = sorter.GetFilenames(); } else { Error("Loading of at least one DICOM file not successfull!"); return; } } 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<nSeries; i++) { gdcm::Directory::FilenamesType sub( files.begin() + i*filesPerSeries, files.begin() + (i+1)*filesPerSeries); gdcm::Scanner s; const gdcm::Tag t3(0x0020,0x0012); // Acquisition ID const gdcm::Tag t4(0x0018,0x0024); // Sequence Name (in case acquisitions are equal for all) // const gdcm::Tag t5(0x20,0x32) ); // Image Position (Patient) s.AddTag(t3); s.AddTag(t4); // s.AddTag(t5); bool b = s.Scan( sub ); if( !b ) { Error("Scanner failed"); if(m_OutputFolderNameSet) logfile << "Scanner failed\n"; continue; } gdcm::Sorter subsorter; gdcm::Scanner::ValuesType::const_iterator it; const gdcm::Scanner::ValuesType &values3 = s.GetValues(t3); const gdcm::Scanner::ValuesType &values4 = s.GetValues(t4);; unsigned int nAcquis = values3.size(); if(nAcquis > 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<std::string> & 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<double> b_vals; double maxb = 0; for(unsigned int i=0; i<hc.size(); i++) { double bv = hc[i]->bValue; if(maxb<bv) { maxb = bv; } b_vals.push_back(bv); } for(unsigned int i=0; i<hc.size(); i++) { vnl_vector_fixed<double, 3> vect = hc[i]->DiffusionVector; // since some protocols provide a gradient direction of (0,0,0) in their dicom files when isotropic diffusion is assumed, // the nrrd compatible way of storing b-values is not possible, so in this case we overwrite // the gradient direction to (1,1,1) if (b_vals[i] > 0 && vect[0] == 0.0 && vect[1] == 0.0 && vect[2] ==0.0) { vect.fill(1.0); } 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<PixelValueType> DiffVolumesType; DiffVolumesType::Pointer diffImage = DiffVolumesType::New(); diffImage->SetDirections(directions); diffImage->SetVectorImage(vecImage); diffImage->SetB_Value(maxb); diffImage->InitializeFromVectorImage(); 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<PixelValueType> 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 <<std::endl; logfile << "\n"; } logfile.close(); Status("Timing information"); clock.Report(); if(!m_OutputFolderNameSet && node.IsNotNull()) { mitk::BaseData::Pointer basedata = node->GetData(); if (basedata.IsNotNull()) { mitk::RenderingManager::GetInstance()->InitializeViews( basedata->GetTimeGeometry(), 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 QmitkTensorReconstructionView::TensorReconstructionWithCorr (mitk::DataStorage::SetOfObjects::Pointer inImages) { try { itk::TimeProbe clock; int nrFiles = inImages->size(); if (!nrFiles) return; QString status; mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles); mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() ); mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() ); std::vector<mitk::DataNode::Pointer> nodes; while ( itemiter != itemiterend ) // for all items { typedef mitk::DiffusionImage<DiffusionPixelType> DiffusionImageType; typedef DiffusionImageType::GradientDirectionContainerType GradientDirectionContainerType; DiffusionImageType* vols = static_cast<DiffusionImageType*>((*itemiter)->GetData()); std::string nodename; (*itemiter)->GetStringProperty("name", nodename); ++itemiter; // TENSOR RECONSTRUCTION clock.Start(); MITK_INFO << "Tensor reconstruction with correction for negative eigenvalues"; mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Tensor reconstruction for %s", nodename.c_str()).toAscii()); typedef itk::TensorReconstructionWithEigenvalueCorrectionFilter< DiffusionPixelType, TTensorPixelType > ReconstructionFilter; float b0Threshold = m_Controls->m_TensorReconstructionThreshold->value(); GradientDirectionContainerType::Pointer gradientContainerCopy = GradientDirectionContainerType::New(); for(GradientDirectionContainerType::ConstIterator it = vols->GetDirections()->Begin(); it != vols->GetDirections()->End(); it++) { gradientContainerCopy->push_back(it.Value()); } ReconstructionFilter::Pointer reconFilter = ReconstructionFilter::New(); reconFilter->SetGradientImage( gradientContainerCopy, vols->GetVectorImage() ); reconFilter->SetBValue(vols->GetB_Value()); reconFilter->SetB0Threshold(b0Threshold); reconFilter->Update(); typedef itk::Image<itk::DiffusionTensor3D<TTensorPixelType>, 3> TensorImageType; TensorImageType::Pointer outputTensorImg = reconFilter->GetOutput(); typedef itk::ImageRegionIterator<TensorImageType> TensorImageIteratorType; TensorImageIteratorType tensorIt(outputTensorImg, outputTensorImg->GetRequestedRegion()); tensorIt.GoToBegin(); int negatives = 0; while(!tensorIt.IsAtEnd()) { typedef itk::DiffusionTensor3D<TTensorPixelType> TensorType; TensorType tensor = tensorIt.Get(); TensorType::EigenValuesArrayType ev; tensor.ComputeEigenValues(ev); for(unsigned int i=0; i<ev.Size(); i++) { if(ev[i] < 0.0) { tensor.Fill(0.0); tensorIt.Set(tensor); negatives++; break; } } ++tensorIt; } MITK_INFO << negatives << " tensors with negative eigenvalues" << std::endl; mitk::TensorImage::Pointer image = mitk::TensorImage::New(); image->InitializeByItk( outputTensorImg.GetPointer() ); image->SetVolume( outputTensorImg->GetBufferPointer() ); mitk::DataNode::Pointer node=mitk::DataNode::New(); node->SetData( image ); QString newname; newname = newname.append(nodename.c_str()); newname = newname.append("_dti_corrected"); SetDefaultNodeProperties(node, newname.toStdString()); nodes.push_back(node); // Corrected diffusion image // typedef itk::VectorImage<short, 3> ImageType; // ImageType::Pointer correctedVols = reconFilter->GetVectorImage(); // DiffusionImageType::Pointer correctedDiffusion = DiffusionImageType::New(); // correctedDiffusion->SetVectorImage(correctedVols); // correctedDiffusion->SetDirections(vols->GetDirections()); // correctedDiffusion->SetB_Value(vols->GetB_Value()); // correctedDiffusion->InitializeFromVectorImage(); // mitk::DataNode::Pointer diffNode = mitk::DataNode::New(); // diffNode->SetData( correctedDiffusion ); // QString diffname; // diffname = diffname.append(nodename.c_str()); // diffname = diffname.append("corrDiff"); // SetDefaultNodeProperties(diffNode, diffname.toStdString()); // nodes.push_back(diffNode); mitk::ProgressBar::GetInstance()->Progress(); } std::vector<mitk::DataNode::Pointer>::iterator nodeIt; for(nodeIt = nodes.begin(); nodeIt != nodes.end(); ++nodeIt) GetDefaultDataStorage()->Add(*nodeIt); mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toAscii()); m_MultiWidget->RequestUpdate(); } catch (itk::ExceptionObject &ex) { MITK_INFO << ex ; QMessageBox::information(0, "Reconstruction not possible:", ex.GetDescription()); } }