Beispiel #1
0
int StreamlineTracking(int argc, char* argv[])
{
    ctkCommandLineParser parser;
    parser.setArgumentPrefix("--", "-");
    parser.addArgument("input", "i", ctkCommandLineParser::StringList, "input tensor image (.dti)", us::Any(), false);
    parser.addArgument("seed", "si", ctkCommandLineParser::String, "binary seed image", us::Any(), true);
    parser.addArgument("mask", "mi", ctkCommandLineParser::String, "binary mask image", us::Any(), true);
    parser.addArgument("faImage", "fai", ctkCommandLineParser::String, "FA image", us::Any(), true);
    parser.addArgument("minFA", "fa", ctkCommandLineParser::Float, "minimum fractional anisotropy threshold", 0.15, true);
    parser.addArgument("minCurv", "c", ctkCommandLineParser::Float, "minimum curvature radius in mm (default = 0.5*minimum-spacing)");
    parser.addArgument("stepSize", "s", ctkCommandLineParser::Float, "stepsize in mm (default = 0.1*minimum-spacing)");
    parser.addArgument("tendf", "f", ctkCommandLineParser::Float, "Weighting factor between first eigenvector (f=1 equals FACT tracking) and input vector dependent direction (f=0).", 1.0, true);
    parser.addArgument("tendg", "g", ctkCommandLineParser::Float, "Weighting factor between input vector (g=0) and tensor deflection (g=1 equals TEND tracking)", 0.0, true);
    parser.addArgument("numSeeds", "n", ctkCommandLineParser::Int, "Number of seeds per voxel.", 1, true);
    parser.addArgument("minLength", "l", ctkCommandLineParser::Float, "minimum fiber length in mm", 20, true);

    parser.addArgument("interpolate", "ip", ctkCommandLineParser::Bool, "Use linear interpolation", false, true);
    parser.addArgument("outFile", "o", ctkCommandLineParser::String, "output fiber bundle (.fib)", us::Any(), false);

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

    ctkCommandLineParser::StringContainerType inputImages = us::any_cast<ctkCommandLineParser::StringContainerType>(parsedArgs["input"]);
    string dtiFileName;
    string outFileName = us::any_cast<string>(parsedArgs["outFile"]);

    float minFA = 0.15;
    float minCurv = -1;
    float stepSize = -1;
    float tendf = 1;
    float tendg = 0;
    float minLength = 20;
    int numSeeds = 1;
    bool interpolate = false;

    if (parsedArgs.count("minCurv"))
        minCurv = us::any_cast<float>(parsedArgs["minCurv"]);
    if (parsedArgs.count("minFA"))
        minFA = us::any_cast<float>(parsedArgs["minFA"]);
    if (parsedArgs.count("stepSize"))
        stepSize = us::any_cast<float>(parsedArgs["stepSize"]);
    if (parsedArgs.count("tendf"))
        tendf = us::any_cast<float>(parsedArgs["tendf"]);
    if (parsedArgs.count("tendg"))
        tendg = us::any_cast<float>(parsedArgs["tendg"]);
    if (parsedArgs.count("minLength"))
        minLength = us::any_cast<float>(parsedArgs["minLength"]);
    if (parsedArgs.count("numSeeds"))
        numSeeds = us::any_cast<int>(parsedArgs["numSeeds"]);


    if (parsedArgs.count("interpolate"))
        interpolate = us::any_cast<bool>(parsedArgs["interpolate"]);



    try
    {
        typedef itk::StreamlineTrackingFilter< float > FilterType;
        FilterType::Pointer filter = FilterType::New();

        MITK_INFO << "Loading tensor images ...";
        typedef itk::Image< itk::DiffusionTensor3D<float>, 3 >    ItkTensorImage;
        dtiFileName = inputImages.at(0);
        for (unsigned int i=0; i<inputImages.size(); i++)
        {
            try
            {
                mitk::TensorImage::Pointer img = dynamic_cast<mitk::TensorImage*>(mitk::IOUtil::LoadDataNode(inputImages.at(i))->GetData());
                ItkTensorImage::Pointer itk_dti = ItkTensorImage::New();
                mitk::CastToItkImage<ItkTensorImage>(img, itk_dti);
                filter->SetInput(i, itk_dti);
            }
            catch(...){ MITK_INFO << "could not load: " << inputImages.at(i); }
        }

        MITK_INFO << "Loading seed image ...";
        typedef itk::Image< unsigned char, 3 >    ItkUCharImageType;
        mitk::Image::Pointer mitkSeedImage = NULL;
        if (parsedArgs.count("seed"))
            mitkSeedImage = mitk::IOUtil::LoadImage(us::any_cast<string>(parsedArgs["seed"]));

        MITK_INFO << "Loading mask image ...";
        mitk::Image::Pointer mitkMaskImage = NULL;
        if (parsedArgs.count("mask"))
            mitkMaskImage = mitk::IOUtil::LoadImage(us::any_cast<string>(parsedArgs["mask"]));

        // instantiate tracker
        filter->SetSeedsPerVoxel(numSeeds);
        filter->SetFaThreshold(minFA);
        filter->SetMinCurvatureRadius(minCurv);
        filter->SetStepSize(stepSize);
        filter->SetF(tendf);
        filter->SetG(tendg);
        filter->SetInterpolate(interpolate);
        filter->SetMinTractLength(minLength);

        if (mitkSeedImage.IsNotNull())
        {
            ItkUCharImageType::Pointer mask = ItkUCharImageType::New();
            mitk::CastToItkImage<ItkUCharImageType>(mitkSeedImage, mask);
            filter->SetSeedImage(mask);
        }

        if (mitkMaskImage.IsNotNull())
        {
            ItkUCharImageType::Pointer mask = ItkUCharImageType::New();
            mitk::CastToItkImage<ItkUCharImageType>(mitkMaskImage, mask);
            filter->SetMaskImage(mask);
        }

        filter->Update();

        vtkSmartPointer<vtkPolyData> fiberBundle = filter->GetFiberPolyData();
        if ( fiberBundle->GetNumberOfLines()==0 )
        {
            MITK_INFO << "No fibers reconstructed. Check parametrization.";
            return EXIT_FAILURE;
        }
        mitk::FiberBundleX::Pointer fib = mitk::FiberBundleX::New(fiberBundle);

        mitk::CoreObjectFactory::FileWriterList fileWriters = mitk::CoreObjectFactory::GetInstance()->GetFileWriters();
        for (mitk::CoreObjectFactory::FileWriterList::iterator it = fileWriters.begin() ; it != fileWriters.end() ; ++it)
        {
            if ( (*it)->CanWriteBaseDataType(fib.GetPointer()) ) {
                (*it)->SetFileName( outFileName.c_str() );
                (*it)->DoWrite( fib.GetPointer() );
            }
        }
    }
    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;
    }
    MITK_INFO << "DONE";
    return EXIT_SUCCESS;
}
int mitkStreamlineTrackingTest(int argc, char* argv[])
{
    MITK_TEST_BEGIN("mitkStreamlineTrackingTest");

    MITK_TEST_CONDITION_REQUIRED(argc>3,"check for input data")

    string dtiFileName = argv[1];
    string maskFileName = argv[2];
    string referenceFileName = argv[3];

    MITK_INFO << "DTI file: " << dtiFileName;
    MITK_INFO << "Mask file: " << maskFileName;
    MITK_INFO << "Reference fiber file: " << referenceFileName;

    float minFA = 0.05;
    float minCurv = -1;
    float stepSize = -1;
    float tendf = 1;
    float tendg = 0;
    float minLength = 20;
    int numSeeds = 1;
    bool interpolate = true;

    try
    {
        MITK_INFO << "Loading tensor image ...";
        typedef itk::Image< itk::DiffusionTensor3D<float>, 3 >    ItkTensorImage;
        mitk::TensorImage::Pointer mitkTensorImage = dynamic_cast<mitk::TensorImage*>(mitk::IOUtil::LoadDataNode(dtiFileName)->GetData());
        ItkTensorImage::Pointer itk_dti = ItkTensorImage::New();
        mitk::CastToItkImage(mitkTensorImage, itk_dti);

        MITK_INFO << "Loading seed image ...";
        typedef itk::Image< unsigned char, 3 >    ItkUCharImageType;
        mitk::Image::Pointer mitkSeedImage = mitk::IOUtil::LoadImage(maskFileName);

        MITK_INFO << "Loading mask image ...";
        mitk::Image::Pointer mitkMaskImage = mitk::IOUtil::LoadImage(maskFileName);

        // instantiate tracker
        typedef itk::StreamlineTrackingFilter< float > FilterType;
        FilterType::Pointer filter = FilterType::New();
        filter->SetInput(itk_dti);
        filter->SetSeedsPerVoxel(numSeeds);
        filter->SetFaThreshold(minFA);
        filter->SetMinCurvatureRadius(minCurv);
        filter->SetStepSize(stepSize);
        filter->SetF(tendf);
        filter->SetG(tendg);
        filter->SetInterpolate(interpolate);
        filter->SetMinTractLength(minLength);
        filter->SetNumberOfThreads(1);

        if (mitkSeedImage.IsNotNull())
        {
            ItkUCharImageType::Pointer mask = ItkUCharImageType::New();
            mitk::CastToItkImage(mitkSeedImage, mask);
            filter->SetSeedImage(mask);
        }

        if (mitkMaskImage.IsNotNull())
        {
            ItkUCharImageType::Pointer mask = ItkUCharImageType::New();
            mitk::CastToItkImage(mitkMaskImage, mask);
            filter->SetMaskImage(mask);
        }

        filter->Update();

        vtkSmartPointer<vtkPolyData> fiberBundle = filter->GetFiberPolyData();
        mitk::FiberBundleX::Pointer fib1 = mitk::FiberBundleX::New(fiberBundle);

        mitk::FiberBundleX::Pointer fib2 = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(referenceFileName)->GetData());
        MITK_TEST_CONDITION_REQUIRED(fib2.IsNotNull(), "Check if reference tractogram is not null.");
        bool ok = fib1->Equals(fib2);
        if (!ok)
        {
            MITK_WARN << "TEST FAILED. TRACTOGRAMS ARE NOT EQUAL!";
            mitk::IOUtil::SaveBaseData(fib1, mitk::IOUtil::GetTempPath()+"testBundle.fib");
            mitk::IOUtil::SaveBaseData(fib2, mitk::IOUtil::GetTempPath()+"refBundle.fib");
            MITK_INFO << "OUTPUT: " << mitk::IOUtil::GetTempPath();
        }
        MITK_TEST_CONDITION_REQUIRED(ok, "Check if tractograms are equal.");
    }
    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;
    }

    MITK_TEST_END();
}