Пример #1
0
/**
 * Calculate indices derived from Qball or tensor images
 */
int DiffusionIndices(int argc, char* argv[])
{
    ctkCommandLineParser parser;
    parser.setArgumentPrefix("--", "-");
    parser.addArgument("input", "i", ctkCommandLineParser::String, "input image (tensor, Q-ball or FSL/MRTrix SH-coefficient image)", us::Any(), false);
    parser.addArgument("index", "idx", ctkCommandLineParser::String, "index (fa, gfa, ra, ad, rd, ca, l2, l3, md)", us::Any(), false);
    parser.addArgument("outFile", "o", ctkCommandLineParser::String, "output file", us::Any(), false);

    map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
    if (parsedArgs.size()==0)
        return EXIT_FAILURE;

    string inFileName = us::any_cast<string>(parsedArgs["input"]);
    string index = us::any_cast<string>(parsedArgs["index"]);
    string outFileName = us::any_cast<string>(parsedArgs["outFile"]);

    string ext = itksys::SystemTools::GetFilenameLastExtension(outFileName);
    if (ext.empty())
        outFileName += ".nrrd";

    try
    {
        // load input image
        const std::string s1="", s2="";
        std::vector<mitk::BaseData::Pointer> infile = mitk::BaseDataIO::LoadBaseDataFromFile( inFileName, s1, s2, false );

        if( boost::algorithm::ends_with(inFileName, ".qbi") && index=="gfa" )
        {
            typedef itk::Vector<float, QBALL_ODFSIZE>   OdfVectorType;
            typedef itk::Image<OdfVectorType,3>         ItkQballImageType;
            mitk::QBallImage::Pointer mitkQballImage = dynamic_cast<mitk::QBallImage*>(infile.at(0).GetPointer());
            ItkQballImageType::Pointer itk_qbi = ItkQballImageType::New();
            mitk::CastToItkImage<ItkQballImageType>(mitkQballImage, itk_qbi);


            typedef itk::DiffusionQballGeneralizedFaImageFilter<float,float,QBALL_ODFSIZE> GfaFilterType;
            GfaFilterType::Pointer gfaFilter = GfaFilterType::New();
            gfaFilter->SetInput(itk_qbi);
            gfaFilter->SetComputationMethod(GfaFilterType::GFA_STANDARD);
            gfaFilter->Update();

            MITK_INFO << "Writing " << outFileName;

            itk::ImageFileWriter< itk::Image<float,3> >::Pointer fileWriter = itk::ImageFileWriter< itk::Image<float,3> >::New();
            fileWriter->SetInput(gfaFilter->GetOutput());
            fileWriter->SetFileName(outFileName);
            fileWriter->Update();
        }
        else if( boost::algorithm::ends_with(inFileName, ".dti") )
        {
            typedef itk::Image< itk::DiffusionTensor3D<float>, 3 >    ItkTensorImage;
            mitk::TensorImage::Pointer mitkTensorImage = dynamic_cast<mitk::TensorImage*>(infile.at(0).GetPointer());
            ItkTensorImage::Pointer itk_dti = ItkTensorImage::New();
            mitk::CastToItkImage<ItkTensorImage>(mitkTensorImage, itk_dti);

            typedef itk::TensorDerivedMeasurementsFilter<float> MeasurementsType;
            MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
            measurementsCalculator->SetInput(itk_dti.GetPointer() );

            if(index=="fa")
                measurementsCalculator->SetMeasure(MeasurementsType::FA);
            else if(index=="ra")
                measurementsCalculator->SetMeasure(MeasurementsType::RA);
            else if(index=="ad")
                measurementsCalculator->SetMeasure(MeasurementsType::AD);
            else if(index=="rd")
                measurementsCalculator->SetMeasure(MeasurementsType::RD);
            else if(index=="ca")
                measurementsCalculator->SetMeasure(MeasurementsType::CA);
            else if(index=="l2")
                measurementsCalculator->SetMeasure(MeasurementsType::L2);
            else if(index=="l3")
                measurementsCalculator->SetMeasure(MeasurementsType::L3);
            else if(index=="md")
                measurementsCalculator->SetMeasure(MeasurementsType::MD);
            else
            {
                MITK_WARN << "No valid diffusion index for input image (tensor image) defined";
                return EXIT_FAILURE;
            }

            measurementsCalculator->Update();

            MITK_INFO << "Writing " << outFileName;

            itk::ImageFileWriter< itk::Image<float,3> >::Pointer fileWriter = itk::ImageFileWriter< itk::Image<float,3> >::New();
            fileWriter->SetInput(measurementsCalculator->GetOutput());
            fileWriter->SetFileName(outFileName);
            fileWriter->Update();
        }
        else
            MITK_INFO << "Diffusion index " << index << " not supported for supplied file type.";
    }
    catch (itk::ExceptionObject e)
    {
        MITK_INFO << e;
        return EXIT_FAILURE;
    }
    catch (std::exception e)
    {
        MITK_INFO << e.what();
        return EXIT_FAILURE;
    }
    catch (...)
    {
        MITK_INFO << "ERROR!?!";
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}
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();

}