Ejemplo n.º 1
0
void QmitkPreprocessingView::CallMultishellToSingleShellFilter(itk::DWIVoxelFunctor * functor, mitk::DiffusionImage<DiffusionPixelType>::Pointer ImPtr, QString imageName)
{
  typedef itk::RadialMultishellToSingleshellImageFilter<DiffusionPixelType, DiffusionPixelType> FilterType;

  // filter input parameter
  const mitk::DiffusionImage<DiffusionPixelType>::BValueMap
      &originalShellMap  = ImPtr->GetBValueMap();

  const mitk::DiffusionImage<DiffusionPixelType>::ImageType
      *vectorImage       = ImPtr->GetVectorImage();

  const mitk::DiffusionImage<DiffusionPixelType>::GradientDirectionContainerType::Pointer
      gradientContainer = ImPtr->GetDirections();

  const unsigned int
      &bValue            = ImPtr->GetReferenceBValue();

  mitk::DataNode::Pointer imageNode = 0;

  // filter call
  FilterType::Pointer filter = FilterType::New();
  filter->SetInput(vectorImage);
  filter->SetOriginalGradientDirections(gradientContainer);
  filter->SetOriginalBValueMap(originalShellMap);
  filter->SetOriginalBValue(bValue);
  filter->SetFunctor(functor);
  filter->Update();

  // create new DWI image
  mitk::DiffusionImage<DiffusionPixelType>::Pointer outImage = mitk::DiffusionImage<DiffusionPixelType>::New();
  outImage->SetVectorImage( filter->GetOutput() );
  outImage->SetReferenceBValue( m_Controls->m_targetBValueSpinBox->value() );
  outImage->SetDirections( filter->GetTargetGradientDirections() );
  outImage->InitializeFromVectorImage();

  imageNode = mitk::DataNode::New();
  imageNode->SetData( outImage );
  imageNode->SetName(imageName.toStdString().c_str());
  GetDefaultDataStorage()->Add(imageNode);

  if(m_Controls->m_OutputRMSErrorImage->isChecked()){
    // create new Error image
    FilterType::ErrorImageType::Pointer errImage = filter->GetErrorImage();
    mitk::Image::Pointer mitkErrImage = mitk::Image::New();
    mitkErrImage->InitializeByItk<FilterType::ErrorImageType>(errImage);
    mitkErrImage->SetVolume(errImage->GetBufferPointer());

    imageNode = mitk::DataNode::New();
    imageNode->SetData( mitkErrImage );
    imageNode->SetName((imageName+"_Error").toStdString().c_str());
    GetDefaultDataStorage()->Add(imageNode);
  }
}
Ejemplo n.º 2
0
void QmitkPreprocessingView::DoAdcCalculation()
{
  if (m_DiffusionImage.IsNull())
    return;

  typedef mitk::DiffusionImage< DiffusionPixelType >            DiffusionImageType;
  typedef itk::AdcImageFilter< DiffusionPixelType, double >     FilterType;


  for (unsigned int i=0; i<m_SelectedDiffusionNodes.size(); i++)
  {
    DiffusionImageType::Pointer inImage = dynamic_cast< DiffusionImageType* >(m_SelectedDiffusionNodes.at(i)->GetData());
    FilterType::Pointer filter = FilterType::New();
    filter->SetInput(inImage->GetVectorImage());
    filter->SetGradientDirections(inImage->GetDirections());
    filter->SetB_value(inImage->GetReferenceBValue());
    filter->Update();

    mitk::Image::Pointer image = mitk::Image::New();
    image->InitializeByItk( filter->GetOutput() );
    image->SetVolume( filter->GetOutput()->GetBufferPointer() );
    mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
    imageNode->SetData( image );
    QString name = m_SelectedDiffusionNodes.at(i)->GetName().c_str();

    imageNode->SetName((name+"_ADC").toStdString().c_str());
    GetDefaultDataStorage()->Add(imageNode);
  }
}
Ejemplo n.º 3
0
void QmitkPreprocessingView::DoLengthCorrection()
{
  if (m_DiffusionImage.IsNull())
    return;

  typedef mitk::DiffusionImage<DiffusionPixelType>  DiffusionImageType;
  typedef itk::DwiGradientLengthCorrectionFilter  FilterType;

  FilterType::Pointer filter = FilterType::New();
  filter->SetRoundingValue( m_Controls->m_B_ValueMap_Rounder_SpinBox->value());
  filter->SetReferenceBValue(m_DiffusionImage->GetReferenceBValue());
  filter->SetReferenceGradientDirectionContainer(m_DiffusionImage->GetDirections());
  filter->Update();

  DiffusionImageType::Pointer image = DiffusionImageType::New();
  image->SetVectorImage( m_DiffusionImage->GetVectorImage());
  image->SetReferenceBValue( filter->GetNewBValue() );
  image->SetDirections( filter->GetOutputGradientDirectionContainer());
  image->InitializeFromVectorImage();

  mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
  imageNode->SetData( image );
  QString name = m_SelectedDiffusionNodes.front()->GetName().c_str();

  imageNode->SetName((name+"_rounded").toStdString().c_str());
  GetDefaultDataStorage()->Add(imageNode);
}
Ejemplo n.º 4
0
void QmitkDenoisingView::AfterThread()
{
  m_ThreadIsRunning = false;
  // stop timer to stop updates of progressbar
  m_DenoisingTimer->stop();
  // make sure progressbar is finished
  mitk::ProgressBar::GetInstance()->Progress(m_MaxProgressCount);
  if (m_CompletedCalculation)
  {
    switch (m_SelectedFilter)
    {
      case NOFILTERSELECTED:
      case GAUSS:
      {
        break;
      }

      case NLM:
      {
        DiffusionImageType::Pointer image = DiffusionImageType::New();
        image->SetVectorImage(m_NonLocalMeansFilter->GetOutput());
        image->SetReferenceBValue(m_InputImage->GetReferenceBValue());
        image->SetDirections(m_InputImage->GetDirections());
        image->InitializeFromVectorImage();
        mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
        imageNode->SetData( image );
        QString name = m_ImageNode->GetName().c_str();

        //TODO: Rician adaption & joint information in name
        if (m_Controls->m_RicianCheckbox->isChecked() && !m_Controls->m_JointInformationCheckbox->isChecked())
        {
          imageNode->SetName((name+"_NLMr_"+QString::number(m_Controls->m_SpinBoxParameter1->value())+"-"+QString::number(m_Controls->m_SpinBoxParameter2->value())).toStdString().c_str());
        }
        else if(!m_Controls->m_RicianCheckbox->isChecked() && m_Controls->m_JointInformationCheckbox->isChecked())
        {
          imageNode->SetName((name+"_NLMv_"+QString::number(m_Controls->m_SpinBoxParameter1->value())+"-"+QString::number(m_Controls->m_SpinBoxParameter2->value())).toStdString().c_str());
        }
        else if(m_Controls->m_RicianCheckbox->isChecked() && m_Controls->m_JointInformationCheckbox->isChecked())
        {
          imageNode->SetName((name+"_NLMvr_"+QString::number(m_Controls->m_SpinBoxParameter1->value())+"-"+QString::number(m_Controls->m_SpinBoxParameter2->value())).toStdString().c_str());
        }
        else
        {
          imageNode->SetName((name+"_NLM_"+QString::number(m_Controls->m_SpinBoxParameter1->value())+"-"+QString::number(m_Controls->m_SpinBoxParameter2->value())).toStdString().c_str());
        }
        GetDefaultDataStorage()->Add(imageNode);
        break;
      }
    }
  }

  m_Controls->m_ParameterBox->setEnabled(true);
  m_Controls->m_ApplyButton->setText("Apply");
}
void QmitkDiffusionQuantificationView::TensorQuantification(
        mitk::DataStorage::SetOfObjects::Pointer inImages, int method)
{
    itk::TimeProbe clock;
    QString status;

    int nrFiles = inImages->size();
    if (!nrFiles) return;

    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 float                                       TTensorPixelType;
        typedef itk::DiffusionTensor3D< TTensorPixelType >  TensorPixelType;
        typedef itk::Image< TensorPixelType, 3 >            TensorImageType;

        mitk::Image* vol =
                static_cast<mitk::Image*>((*itemiter)->GetData());
        TensorImageType::Pointer itkvol = TensorImageType::New();
        mitk::CastToItkImage<TensorImageType>(vol, itkvol);

        std::string nodename;
        (*itemiter)->GetStringProperty("name", nodename);
        ++itemiter;

        // COMPUTE FA
        clock.Start();
        MBI_INFO << "Computing FA ";
        mitk::StatusBar::GetInstance()->DisplayText(status.sprintf(
                                                        "Computing FA for %s", nodename.c_str()).toAscii());
        typedef itk::Image< TTensorPixelType, 3 >              FAImageType;

        typedef itk::ShiftScaleImageFilter<FAImageType, FAImageType>
                ShiftScaleFilterType;
        ShiftScaleFilterType::Pointer multi =
                ShiftScaleFilterType::New();
        multi->SetShift(0.0);
        multi->SetScale(m_Controls->m_ScaleImageValuesBox->value());//itk::NumericTraits<RealValueType>::max()

        typedef itk::TensorDerivedMeasurementsFilter<TTensorPixelType> MeasurementsType;

        if(method == 0) //FA
        {
            /* typedef itk::TensorFractionalAnisotropyImageFilter<
        TensorImageType, FAImageType >                       FilterType;
      FilterType::Pointer anisotropyFilter = FilterType::New();
      anisotropyFilter->SetInput( itkvol.GetPointer() );
      anisotropyFilter->Update();
      multi->SetInput(anisotropyFilter->GetOutput());
      nodename = QString(nodename.c_str()).append("_FA").toStdString();*/


            MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
            measurementsCalculator->SetInput(itkvol.GetPointer() );
            measurementsCalculator->SetMeasure(MeasurementsType::FA);
            measurementsCalculator->Update();
            multi->SetInput(measurementsCalculator->GetOutput());
            nodename = QString(nodename.c_str()).append("_FA").toStdString();

        }
        else if(method == 1) //RA
        {
            /*typedef itk::TensorRelativeAnisotropyImageFilter<
        TensorImageType, FAImageType >                       FilterType;
      FilterType::Pointer anisotropyFilter = FilterType::New();
      anisotropyFilter->SetInput( itkvol.GetPointer() );
      anisotropyFilter->Update();
      multi->SetInput(anisotropyFilter->GetOutput());
      nodename = QString(nodename.c_str()).append("_RA").toStdString();*/

            MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
            measurementsCalculator->SetInput(itkvol.GetPointer() );
            measurementsCalculator->SetMeasure(MeasurementsType::RA);
            measurementsCalculator->Update();
            multi->SetInput(measurementsCalculator->GetOutput());
            nodename = QString(nodename.c_str()).append("_RA").toStdString();

        }
        else if(method == 2) // AD (Axial diffusivity)
        {
            MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
            measurementsCalculator->SetInput(itkvol.GetPointer() );
            measurementsCalculator->SetMeasure(MeasurementsType::AD);
            measurementsCalculator->Update();
            multi->SetInput(measurementsCalculator->GetOutput());
            nodename = QString(nodename.c_str()).append("_AD").toStdString();
        }
        else if(method == 3) // RD (Radial diffusivity, (Lambda2+Lambda3)/2
        {
            MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
            measurementsCalculator->SetInput(itkvol.GetPointer() );
            measurementsCalculator->SetMeasure(MeasurementsType::RD);
            measurementsCalculator->Update();
            multi->SetInput(measurementsCalculator->GetOutput());
            nodename = QString(nodename.c_str()).append("_RD").toStdString();
        }
        else if(method == 4) // 1-(Lambda2+Lambda3)/(2*Lambda1)
        {
            MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
            measurementsCalculator->SetInput(itkvol.GetPointer() );
            measurementsCalculator->SetMeasure(MeasurementsType::CA);
            measurementsCalculator->Update();
            multi->SetInput(measurementsCalculator->GetOutput());
            nodename = QString(nodename.c_str()).append("_CA").toStdString();
        }
        else if(method == 5) // MD (Mean Diffusivity, (Lambda1+Lambda2+Lambda3)/3 )
        {
            MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
            measurementsCalculator->SetInput(itkvol.GetPointer() );
            measurementsCalculator->SetMeasure(MeasurementsType::MD);
            measurementsCalculator->Update();
            multi->SetInput(measurementsCalculator->GetOutput());
            nodename = QString(nodename.c_str()).append("_MD").toStdString();
        }

        multi->Update();
        clock.Stop();
        MBI_DEBUG << "took " << clock.GetMeanTime() << "s.";

        // FA TO DATATREE
        mitk::Image::Pointer image = mitk::Image::New();
        image->InitializeByItk( multi->GetOutput() );
        image->SetVolume( multi->GetOutput()->GetBufferPointer() );
        mitk::DataNode::Pointer node=mitk::DataNode::New();
        node->SetData( image );
        node->SetProperty( "name", mitk::StringProperty::New(nodename) );
        nodes.push_back(node);

        mitk::StatusBar::GetInstance()->DisplayText("Computation complete.");

    }

    std::vector<mitk::DataNode::Pointer>::iterator nodeIt;
    for(nodeIt = nodes.begin(); nodeIt != nodes.end(); ++nodeIt)
        GetDefaultDataStorage()->Add(*nodeIt);

    m_MultiWidget->RequestUpdate();

}
void QmitkDiffusionQuantificationView::QBIQuantification(
        mitk::DataStorage::SetOfObjects::Pointer inImages, int method)
{
    itk::TimeProbe clock;
    QString status;

    int nrFiles = inImages->size();
    if (!nrFiles) return;

    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 float TOdfPixelType;
        const int odfsize = QBALL_ODFSIZE;
        typedef itk::Vector<TOdfPixelType,odfsize> OdfVectorType;
        typedef itk::Image<OdfVectorType,3> OdfVectorImgType;
        mitk::Image* vol =
                static_cast<mitk::Image*>((*itemiter)->GetData());
        OdfVectorImgType::Pointer itkvol = OdfVectorImgType::New();
        mitk::CastToItkImage<OdfVectorImgType>(vol, itkvol);

        std::string nodename;
        (*itemiter)->GetStringProperty("name", nodename);
        ++itemiter;

        float p1 = m_Controls->m_ParamKEdit->text().toFloat();
        float p2 = m_Controls->m_ParamPEdit->text().toFloat();

        // COMPUTE RA
        clock.Start();
        MBI_INFO << "Computing GFA ";
        mitk::StatusBar::GetInstance()->DisplayText(status.sprintf(
                                                        "Computing GFA for %s", nodename.c_str()).toAscii());
        typedef OdfVectorType::ValueType                 RealValueType;
        typedef itk::Image< RealValueType, 3 >                 RAImageType;
        typedef itk::DiffusionQballGeneralizedFaImageFilter<TOdfPixelType,TOdfPixelType,odfsize>
                GfaFilterType;
        GfaFilterType::Pointer gfaFilter = GfaFilterType::New();
        gfaFilter->SetInput(itkvol);

        double scale = 1;
        std::string newname;
        newname.append(nodename);
        switch(method)
        {
        case 0:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_STANDARD);
            newname.append("GFA");
            break;
        }
        case 1:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILES_HIGH_LOW);
            newname.append("01");
            break;
        }
        case 2:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILE_HIGH);
            newname.append("02");
            break;
        }
        case 3:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_MAX_ODF_VALUE);
            newname.append("03");
            break;
        }
        case 4:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_DECONVOLUTION_COEFFS);
            newname.append("04");
            break;
        }
        case 5:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_MIN_MAX_NORMALIZED_STANDARD);
            newname.append("05");
            break;
        }
        case 6:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_NORMALIZED_ENTROPY);
            newname.append("06");
            break;
        }
        case 7:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_NEMATIC_ORDER_PARAMETER);
            newname.append("07");
            break;
        }
        case 8:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILES_LOW_HIGH);
            newname.append("08");
            break;
        }
        case 9:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILE_LOW);
            newname.append("09");
            break;
        }
        case 10:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_MIN_ODF_VALUE);
            newname.append("10");
            break;
        }
        case 11:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_STD_BY_MAX);
            newname.append("11");
            break;
        }
        case 12:
        {
            p1 = m_Controls->MinAngle->text().toFloat();
            p2 = m_Controls->MaxAngle->text().toFloat();
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_PRINCIPLE_CURVATURE);
            QString paramString;
            paramString = paramString.append("PC%1-%2").arg(p1).arg(p2);
            newname.append(paramString.toAscii());
            gfaFilter->SetParam1(p1);
            gfaFilter->SetParam2(p2);
            break;
        }
        case 13:
        {
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_GENERALIZED_GFA);
            QString paramString;
            paramString = paramString.append("GFAK%1P%2").arg(p1).arg(p2);
            newname.append(paramString.toAscii());
            gfaFilter->SetParam1(p1);
            gfaFilter->SetParam2(p2);
            break;
        }
        default:
        {
            newname.append("0");
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_STANDARD);
        }
        }
        gfaFilter->Update();
        clock.Stop();
        MBI_DEBUG << "took " << clock.GetMeanTime() << "s.";

        typedef itk::Image<TOdfPixelType, 3> ImgType;
        ImgType::Pointer img = ImgType::New();
        img->SetSpacing( gfaFilter->GetOutput()->GetSpacing() );   // Set the image spacing
        img->SetOrigin( gfaFilter->GetOutput()->GetOrigin() );     // Set the image origin
        img->SetDirection( gfaFilter->GetOutput()->GetDirection() );  // Set the image direction
        img->SetLargestPossibleRegion( gfaFilter->GetOutput()->GetLargestPossibleRegion());
        img->SetBufferedRegion( gfaFilter->GetOutput()->GetLargestPossibleRegion() );
        img->Allocate();
        itk::ImageRegionIterator<ImgType> ot (img, img->GetLargestPossibleRegion() );
        ot = ot.Begin();
        itk::ImageRegionConstIterator<GfaFilterType::OutputImageType> it
                (gfaFilter->GetOutput(), gfaFilter->GetOutput()->GetLargestPossibleRegion() );
        it = it.Begin();

        for (it = it.Begin(); !it.IsAtEnd(); ++it)
        {
            GfaFilterType::OutputImageType::PixelType val = it.Get();
            ot.Set(val * m_Controls->m_ScaleImageValuesBox->value());
            ++ot;
        }


        // GFA TO DATATREE
        mitk::Image::Pointer image = mitk::Image::New();
        image->InitializeByItk( img.GetPointer() );
        image->SetVolume( img->GetBufferPointer() );
        mitk::DataNode::Pointer node=mitk::DataNode::New();
        node->SetData( image );
        node->SetProperty( "name", mitk::StringProperty::New(newname) );
        nodes.push_back(node);

        mitk::StatusBar::GetInstance()->DisplayText("Computation complete.");

    }

    std::vector<mitk::DataNode::Pointer>::iterator nodeIt;
    for(nodeIt = nodes.begin(); nodeIt != nodes.end(); ++nodeIt)
        GetDefaultDataStorage()->Add(*nodeIt);

    m_MultiWidget->RequestUpdate();

}
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 QmitkBasicImageProcessing::StartButtonClicked()
{
  if(!m_SelectedImageNode->GetNode()) return;

  this->BusyCursorOn();

  mitk::Image::Pointer newImage;

  try
  {
    newImage = dynamic_cast<mitk::Image*>(m_SelectedImageNode->GetNode()->GetData());
  }
  catch ( std::exception &e )
  {
  QString exceptionString = "An error occured during image loading:\n";
  exceptionString.append( e.what() );
    QMessageBox::warning( NULL, "Basic Image Processing", exceptionString , QMessageBox::Ok, QMessageBox::NoButton );
    this->BusyCursorOff();
    return;
  }

  // check if input image is valid, casting does not throw exception when casting from 'NULL-Object'
  if ( (! newImage) || (newImage->IsInitialized() == false) )
  {
    this->BusyCursorOff();

    QMessageBox::warning( NULL, "Basic Image Processing", "Input image is broken or not initialized. Returning.", QMessageBox::Ok, QMessageBox::NoButton );
    return;
  }

  // check if operation is done on 4D a image time step
  if(newImage->GetDimension() > 3)
  {
    mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
    timeSelector->SetInput(newImage);
    timeSelector->SetTimeNr( ((QmitkSliderNavigatorWidget*)m_Controls->sliceNavigatorTime)->GetPos() );
    timeSelector->Update();
    newImage = timeSelector->GetOutput();
  }



  // check if image or vector image
  ImageType::Pointer itkImage = ImageType::New();
  VectorImageType::Pointer itkVecImage = VectorImageType::New();

  int isVectorImage = newImage->GetPixelType().GetNumberOfComponents();

  if(isVectorImage > 1)
  {
    CastToItkImage( newImage, itkVecImage );
  }
  else
  {
    CastToItkImage( newImage, itkImage );
  }

  std::stringstream nameAddition("");

  int param1 = m_Controls->sbParam1->value();
  int param2 = m_Controls->sbParam2->value();
  double dparam1 = m_Controls->dsbParam1->value();
  double dparam2 = m_Controls->dsbParam2->value();
  double dparam3 = m_Controls->dsbParam3->value();

  try{

  switch (m_SelectedAction)
  {

  case GAUSSIAN:
    {
      GaussianFilterType::Pointer gaussianFilter = GaussianFilterType::New();
      gaussianFilter->SetInput( itkImage );
      gaussianFilter->SetVariance( param1 );
      gaussianFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(gaussianFilter->GetOutput())->Clone();
      nameAddition << "_Gaussian_var_" << param1;
      std::cout << "Gaussian filtering successful." << std::endl;
      break;
    }

  case MEDIAN:
    {
      MedianFilterType::Pointer medianFilter = MedianFilterType::New();
      MedianFilterType::InputSizeType size;
      size.Fill(param1);
      medianFilter->SetRadius( size );
      medianFilter->SetInput(itkImage);
      medianFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(medianFilter->GetOutput())->Clone();
      nameAddition << "_Median_radius_" << param1;
      std::cout << "Median Filtering successful." << std::endl;
      break;
    }

  case TOTALVARIATION:
    {
      if(isVectorImage > 1)
      {
        VectorTotalVariationFilterType::Pointer TVFilter
          = VectorTotalVariationFilterType::New();
        TVFilter->SetInput( itkVecImage.GetPointer() );
        TVFilter->SetNumberIterations(param1);
        TVFilter->SetLambda(double(param2)/1000.);
        TVFilter->UpdateLargestPossibleRegion();

        newImage = mitk::ImportItkImage(TVFilter->GetOutput())->Clone();
      }
      else
      {
        ImagePTypeToFloatPTypeCasterType::Pointer floatCaster = ImagePTypeToFloatPTypeCasterType::New();
        floatCaster->SetInput( itkImage );
        floatCaster->Update();
        FloatImageType::Pointer fImage = floatCaster->GetOutput();

        TotalVariationFilterType::Pointer TVFilter
          = TotalVariationFilterType::New();
        TVFilter->SetInput( fImage.GetPointer() );
        TVFilter->SetNumberIterations(param1);
        TVFilter->SetLambda(double(param2)/1000.);
        TVFilter->UpdateLargestPossibleRegion();

        newImage = mitk::ImportItkImage(TVFilter->GetOutput())->Clone();
      }

      nameAddition << "_TV_Iter_" << param1 << "_L_" << param2;
      std::cout << "Total Variation Filtering successful." << std::endl;
      break;
    }

  case DILATION:
    {
      BallType binaryBall;
      binaryBall.SetRadius( param1 );
      binaryBall.CreateStructuringElement();

      DilationFilterType::Pointer dilationFilter = DilationFilterType::New();
      dilationFilter->SetInput( itkImage );
      dilationFilter->SetKernel( binaryBall );
      dilationFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(dilationFilter->GetOutput())->Clone();
      nameAddition << "_Dilated_by_" << param1;
      std::cout << "Dilation successful." << std::endl;
      break;
    }

  case EROSION:
    {
      BallType binaryBall;
      binaryBall.SetRadius( param1 );
      binaryBall.CreateStructuringElement();

      ErosionFilterType::Pointer erosionFilter = ErosionFilterType::New();
      erosionFilter->SetInput( itkImage );
      erosionFilter->SetKernel( binaryBall );
      erosionFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(erosionFilter->GetOutput())->Clone();
      nameAddition << "_Eroded_by_" << param1;
      std::cout << "Erosion successful." << std::endl;
      break;
    }

  case OPENING:
    {
      BallType binaryBall;
      binaryBall.SetRadius( param1 );
      binaryBall.CreateStructuringElement();

      OpeningFilterType::Pointer openFilter = OpeningFilterType::New();
      openFilter->SetInput( itkImage );
      openFilter->SetKernel( binaryBall );
      openFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(openFilter->GetOutput())->Clone();
      nameAddition << "_Opened_by_" << param1;
      std::cout << "Opening successful." << std::endl;
      break;
    }

  case CLOSING:
    {
      BallType binaryBall;
      binaryBall.SetRadius( param1 );
      binaryBall.CreateStructuringElement();

      ClosingFilterType::Pointer closeFilter = ClosingFilterType::New();
      closeFilter->SetInput( itkImage );
      closeFilter->SetKernel( binaryBall );
      closeFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(closeFilter->GetOutput())->Clone();
      nameAddition << "_Closed_by_" << param1;
      std::cout << "Closing successful." << std::endl;
      break;
    }

  case GRADIENT:
    {
      GradientFilterType::Pointer gradientFilter = GradientFilterType::New();
      gradientFilter->SetInput( itkImage );
      gradientFilter->SetSigma( param1 );
      gradientFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(gradientFilter->GetOutput())->Clone();
      nameAddition << "_Gradient_sigma_" << param1;
      std::cout << "Gradient calculation successful." << std::endl;
      break;
    }

  case LAPLACIAN:
    {
      // the laplace filter requires a float type image as input, we need to cast the itkImage
      // to correct type
      ImagePTypeToFloatPTypeCasterType::Pointer caster = ImagePTypeToFloatPTypeCasterType::New();
      caster->SetInput( itkImage );
      caster->Update();
      FloatImageType::Pointer fImage = caster->GetOutput();

      LaplacianFilterType::Pointer laplacianFilter = LaplacianFilterType::New();
      laplacianFilter->SetInput( fImage );
      laplacianFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(laplacianFilter->GetOutput())->Clone();
      nameAddition << "_Second_Derivative";
      std::cout << "Laplacian filtering successful." << std::endl;
      break;
    }

  case SOBEL:
    {
      // the sobel filter requires a float type image as input, we need to cast the itkImage
      // to correct type
      ImagePTypeToFloatPTypeCasterType::Pointer caster = ImagePTypeToFloatPTypeCasterType::New();
      caster->SetInput( itkImage );
      caster->Update();
      FloatImageType::Pointer fImage = caster->GetOutput();

      SobelFilterType::Pointer sobelFilter = SobelFilterType::New();
      sobelFilter->SetInput( fImage );
      sobelFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(sobelFilter->GetOutput())->Clone();
      nameAddition << "_Sobel";
      std::cout << "Edge Detection successful." << std::endl;
      break;
    }

  case THRESHOLD:
    {
      ThresholdFilterType::Pointer thFilter = ThresholdFilterType::New();
      thFilter->SetLowerThreshold(param1 < param2 ? param1 : param2);
      thFilter->SetUpperThreshold(param2 > param1 ? param2 : param1);
      thFilter->SetInsideValue(1);
      thFilter->SetOutsideValue(0);
      thFilter->SetInput(itkImage);
      thFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(thFilter->GetOutput())->Clone();
      nameAddition << "_Threshold";
      std::cout << "Thresholding successful." << std::endl;
      break;
    }

  case INVERSION:
    {
      InversionFilterType::Pointer invFilter = InversionFilterType::New();
      mitk::ScalarType min = newImage->GetScalarValueMin();
      mitk::ScalarType max = newImage->GetScalarValueMax();
      invFilter->SetMaximum( max + min );
      invFilter->SetInput(itkImage);
      invFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(invFilter->GetOutput())->Clone();
      nameAddition << "_Inverted";
      std::cout << "Image inversion successful." << std::endl;
      break;
    }

  case DOWNSAMPLING:
    {
      ResampleImageFilterType::Pointer downsampler = ResampleImageFilterType::New();
      downsampler->SetInput( itkImage );

      NearestInterpolatorType::Pointer interpolator = NearestInterpolatorType::New();
      downsampler->SetInterpolator( interpolator );

      downsampler->SetDefaultPixelValue( 0 );

      ResampleImageFilterType::SpacingType spacing = itkImage->GetSpacing();
      spacing *= (double) param1;
      downsampler->SetOutputSpacing( spacing );

      downsampler->SetOutputOrigin( itkImage->GetOrigin() );
      downsampler->SetOutputDirection( itkImage->GetDirection() );

      ResampleImageFilterType::SizeType size = itkImage->GetLargestPossibleRegion().GetSize();
      for ( int i = 0; i < 3; ++i )
      {
        size[i] /= param1;
      }
      downsampler->SetSize( size );
      downsampler->UpdateLargestPossibleRegion();

      newImage = mitk::ImportItkImage(downsampler->GetOutput())->Clone();
      nameAddition << "_Downsampled_by_" << param1;
      std::cout << "Downsampling successful." << std::endl;
      break;
    }

  case FLIPPING:
    {
      FlipImageFilterType::Pointer flipper = FlipImageFilterType::New();
      flipper->SetInput( itkImage );
      itk::FixedArray<bool, 3> flipAxes;
      for(int i=0; i<3; ++i)
      {
        if(i == param1)
        {
          flipAxes[i] = true;
        }
        else
        {
          flipAxes[i] = false;
        }
      }
      flipper->SetFlipAxes(flipAxes);
      flipper->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(flipper->GetOutput())->Clone();
      std::cout << "Image flipping successful." << std::endl;
      break;
    }

  case RESAMPLING:
    {
      std::string selectedInterpolator;
      ResampleImageFilterType::Pointer resampler = ResampleImageFilterType::New();
      switch (m_SelectedInterpolation)
      {
      case LINEAR:
        {
          LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New();
          resampler->SetInterpolator(interpolator);
          selectedInterpolator = "Linear";
          break;
        }
      case NEAREST:
        {
          NearestInterpolatorType::Pointer interpolator = NearestInterpolatorType::New();
          resampler->SetInterpolator(interpolator);
          selectedInterpolator = "Nearest";
          break;
        }
      default:
        {
          LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New();
          resampler->SetInterpolator(interpolator);
          selectedInterpolator = "Linear";
          break;
        }
      }
      resampler->SetInput( itkImage );
      resampler->SetOutputOrigin( itkImage->GetOrigin() );

      ImageType::SizeType input_size = itkImage->GetLargestPossibleRegion().GetSize();
      ImageType::SpacingType input_spacing = itkImage->GetSpacing();

      ImageType::SizeType output_size;
      ImageType::SpacingType output_spacing;

      output_size[0] = input_size[0] * (input_spacing[0] / dparam1);
      output_size[1] = input_size[1] * (input_spacing[1] / dparam2);
      output_size[2] = input_size[2] * (input_spacing[2] / dparam3);
      output_spacing [0] = dparam1;
      output_spacing [1] = dparam2;
      output_spacing [2] = dparam3;

      resampler->SetSize( output_size );
      resampler->SetOutputSpacing( output_spacing );
      resampler->SetOutputDirection( itkImage->GetDirection() );

      resampler->UpdateLargestPossibleRegion();

      ImageType::Pointer resampledImage = resampler->GetOutput();

      newImage = mitk::ImportItkImage( resampledImage );
      nameAddition << "_Resampled_" << selectedInterpolator;
      std::cout << "Resampling successful." << std::endl;
      break;
    }


  case RESCALE:
    {
      FloatImageType::Pointer floatImage = FloatImageType::New();
      CastToItkImage( newImage, floatImage );
      itk::RescaleIntensityImageFilter<FloatImageType,FloatImageType>::Pointer filter = itk::RescaleIntensityImageFilter<FloatImageType,FloatImageType>::New();
      filter->SetInput(0, floatImage);
      filter->SetOutputMinimum(dparam1);
      filter->SetOutputMaximum(dparam2);
      filter->Update();
      floatImage = filter->GetOutput();

      newImage = mitk::Image::New();
      newImage->InitializeByItk(floatImage.GetPointer());
      newImage->SetVolume(floatImage->GetBufferPointer());
      nameAddition << "_Rescaled";
      std::cout << "Rescaling successful." << std::endl;

      break;
    }

  default:
    this->BusyCursorOff();
    return;
  }
  }
  catch (...)
  {
    this->BusyCursorOff();
    QMessageBox::warning(NULL, "Warning", "Problem when applying filter operation. Check your input...");
    return;
  }

  newImage->DisconnectPipeline();

  // adjust level/window to new image
  mitk::LevelWindow levelwindow;
  levelwindow.SetAuto( newImage );
  mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New();
  levWinProp->SetLevelWindow( levelwindow );

  // compose new image name
  std::string name = m_SelectedImageNode->GetNode()->GetName();
  if (name.find(".pic.gz") == name.size() -7 )
  {
    name = name.substr(0,name.size() -7);
  }
  name.append( nameAddition.str() );

  // create final result MITK data storage node
  mitk::DataNode::Pointer result = mitk::DataNode::New();
  result->SetProperty( "levelwindow", levWinProp );
  result->SetProperty( "name", mitk::StringProperty::New( name.c_str() ) );
  result->SetData( newImage );

  // for vector images, a different mapper is needed
  if(isVectorImage > 1)
  {
    mitk::VectorImageMapper2D::Pointer mapper =
      mitk::VectorImageMapper2D::New();
    result->SetMapper(1,mapper);
  }

  // reset GUI to ease further processing
//  this->ResetOneImageOpPanel();

  // add new image to data storage and set as active to ease further processing
  GetDefaultDataStorage()->Add( result, m_SelectedImageNode->GetNode() );
  if ( m_Controls->cbHideOrig->isChecked() == true )
    m_SelectedImageNode->GetNode()->SetProperty( "visible", mitk::BoolProperty::New(false) );
  // TODO!! m_Controls->m_ImageSelector1->SetSelectedNode(result);

  // show the results
  mitk::RenderingManager::GetInstance()->RequestUpdateAll();
  this->BusyCursorOff();
}
Ejemplo n.º 9
0
void QmitkDenoisingView::StartDenoising()
{
  if (!m_ThreadIsRunning)
  {
    if (m_ImageNode.IsNotNull())
    {
      m_LastProgressCount = 0;
      switch (m_SelectedFilter)
      {
        case NOFILTERSELECTED:
        {
          break;
        }
        case NLM:
        {
          // initialize NLM
          m_InputImage = dynamic_cast<DiffusionImageType*> (m_ImageNode->GetData());
          m_NonLocalMeansFilter = NonLocalMeansDenoisingFilterType::New();

          if (m_BrainMaskNode.IsNotNull())
          {
            // use brainmask if set
            m_ImageMask = dynamic_cast<mitk::Image*>(m_BrainMaskNode->GetData());
            itk::Image<DiffusionPixelType, 3>::Pointer itkMask;
            mitk::CastToItkImage(m_ImageMask, itkMask);
            m_NonLocalMeansFilter->SetInputMask(itkMask);

            itk::ImageRegionIterator< itk::Image<DiffusionPixelType, 3> > mit(itkMask, itkMask->GetLargestPossibleRegion());
            mit.GoToBegin();
            itk::Image<DiffusionPixelType, 3>::IndexType minIndex;
            itk::Image<DiffusionPixelType, 3>::IndexType maxIndex;
            minIndex.Fill(10000);
            maxIndex.Fill(0);
            while (!mit.IsAtEnd())
            {
              if (mit.Get())
              {
                // calculation of the start & end index of the smallest masked region
                minIndex[0] = minIndex[0] < mit.GetIndex()[0] ? minIndex[0] : mit.GetIndex()[0];
                minIndex[1] = minIndex[1] < mit.GetIndex()[1] ? minIndex[1] : mit.GetIndex()[1];
                minIndex[2] = minIndex[2] < mit.GetIndex()[2] ? minIndex[2] : mit.GetIndex()[2];

                maxIndex[0] = maxIndex[0] > mit.GetIndex()[0] ? maxIndex[0] : mit.GetIndex()[0];
                maxIndex[1] = maxIndex[1] > mit.GetIndex()[1] ? maxIndex[1] : mit.GetIndex()[1];
                maxIndex[2] = maxIndex[2] > mit.GetIndex()[2] ? maxIndex[2] : mit.GetIndex()[2];
              }
              ++mit;
            }
            itk::Image<DiffusionPixelType, 3>::SizeType size;
            size[0] = maxIndex[0] - minIndex[0] + 1;
            size[1] = maxIndex[1] - minIndex[1] + 1;
            size[2] = maxIndex[2] - minIndex[2] + 1;

            m_MaxProgressCount = size[0] * size[1] * size[2];
          }
          else
          {
            // initialize the progressbar
            m_MaxProgressCount = m_InputImage->GetDimension(0) * m_InputImage->GetDimension(1) * m_InputImage->GetDimension(2);
          }


          mitk::ProgressBar::GetInstance()->AddStepsToDo(m_MaxProgressCount);


          m_NonLocalMeansFilter->SetInputImage(m_InputImage->GetVectorImage());
          m_NonLocalMeansFilter->SetUseRicianAdaption(m_Controls->m_RicianCheckbox->isChecked());
          m_NonLocalMeansFilter->SetUseJointInformation(m_Controls->m_JointInformationCheckbox->isChecked());
          m_NonLocalMeansFilter->SetSearchRadius(m_Controls->m_SpinBoxParameter1->value());
          m_NonLocalMeansFilter->SetComparisonRadius(m_Controls->m_SpinBoxParameter2->value());
          m_NonLocalMeansFilter->SetVariance(m_Controls->m_DoubleSpinBoxParameter3->value());





          // start denoising in detached thread
          m_DenoisingThread.start(QThread::HighestPriority);

          break;
        }
        case GAUSS:
        {
          // initialize GAUSS and run
          m_InputImage = dynamic_cast<DiffusionImageType*> (m_ImageNode->GetData());

          ExtractFilterType::Pointer extractor = ExtractFilterType::New();
          extractor->SetInput(m_InputImage->GetVectorImage());
          ComposeFilterType::Pointer composer = ComposeFilterType::New();

          for (unsigned int i = 0; i < m_InputImage->GetVectorImage()->GetVectorLength(); ++i)
          {
            extractor->SetIndex(i);
            extractor->Update();

            m_GaussianFilter = GaussianFilterType::New();
            m_GaussianFilter->SetVariance(m_Controls->m_SpinBoxParameter1->value());

            if (m_BrainMaskNode.IsNotNull())
            {
              m_ImageMask = dynamic_cast<mitk::Image*>(m_BrainMaskNode->GetData());
              itk::Image<DiffusionPixelType, 3>::Pointer itkMask = itk::Image<DiffusionPixelType, 3>::New();
              mitk::CastToItkImage(m_ImageMask, itkMask);

              itk::MaskImageFilter<itk::Image<DiffusionPixelType, 3> , itk::Image<DiffusionPixelType, 3> >::Pointer maskImageFilter = itk::MaskImageFilter<itk::Image<DiffusionPixelType, 3> , itk::Image<DiffusionPixelType, 3> >::New();
              maskImageFilter->SetInput(extractor->GetOutput());
              maskImageFilter->SetMaskImage(itkMask);
              maskImageFilter->Update();
              m_GaussianFilter->SetInput(maskImageFilter->GetOutput());
            }
            else
            {
              m_GaussianFilter->SetInput(extractor->GetOutput());
            }
            m_GaussianFilter->Update();

            composer->SetInput(i, m_GaussianFilter->GetOutput());
          }
          composer->Update();


          DiffusionImageType::Pointer image = DiffusionImageType::New();
          image->SetVectorImage(composer->GetOutput());
          image->SetReferenceBValue(m_InputImage->GetReferenceBValue());
          image->SetDirections(m_InputImage->GetDirections());
          image->InitializeFromVectorImage();
          mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
          imageNode->SetData( image );
          QString name = m_ImageNode->GetName().c_str();

          imageNode->SetName((name+"_gauss_"+QString::number(m_Controls->m_SpinBoxParameter1->value())).toStdString().c_str());
          GetDefaultDataStorage()->Add(imageNode);

          break;
        }
      }
    }
  }

  else
  {
    m_NonLocalMeansFilter->AbortGenerateDataOn();
    m_CompletedCalculation = false;
  }
}