int mitkLocalFiberPlausibilityTest(int argc, char* argv[])
{
    MITK_TEST_BEGIN("mitkLocalFiberPlausibilityTest");
    MITK_TEST_CONDITION_REQUIRED(argc==8,"check for input data")

    string fibFile = argv[1];
    vector< string > referenceImages;
    referenceImages.push_back(argv[2]);
    referenceImages.push_back(argv[3]);
    string LDFP_ERROR_IMAGE = argv[4];
    string LDFP_NUM_DIRECTIONS = argv[5];
    string LDFP_VECTOR_FIELD = argv[6];
    string LDFP_ERROR_IMAGE_IGNORE = argv[7];

    float angularThreshold = 25;

    try
    {
        typedef itk::Image<unsigned char, 3>                                    ItkUcharImgType;
        typedef itk::Image< itk::Vector< float, 3>, 3 >                         ItkDirectionImage3DType;
        typedef itk::VectorContainer< unsigned int, ItkDirectionImage3DType::Pointer >   ItkDirectionImageContainerType;
        typedef itk::EvaluateDirectionImagesFilter< float >                     EvaluationFilterType;

        // load fiber bundle
        mitk::FiberBundleX::Pointer inputTractogram = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(fibFile)->GetData());

        // load reference directions
        ItkDirectionImageContainerType::Pointer referenceImageContainer = ItkDirectionImageContainerType::New();
        for (unsigned int i=0; i<referenceImages.size(); i++)
        {
            try
            {
                mitk::Image::Pointer img = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(referenceImages.at(i))->GetData());
                typedef mitk::ImageToItk< ItkDirectionImage3DType > CasterType;
                CasterType::Pointer caster = CasterType::New();
                caster->SetInput(img);
                caster->Update();
                ItkDirectionImage3DType::Pointer itkImg = caster->GetOutput();
                referenceImageContainer->InsertElement(referenceImageContainer->Size(),itkImg);
            }
            catch(...) {
                MITK_INFO << "could not load: " << referenceImages.at(i);
            }
        }

        ItkUcharImgType::Pointer itkMaskImage = ItkUcharImgType::New();
        ItkDirectionImage3DType::Pointer dirImg = referenceImageContainer->GetElement(0);
        itkMaskImage->SetSpacing( dirImg->GetSpacing() );
        itkMaskImage->SetOrigin( dirImg->GetOrigin() );
        itkMaskImage->SetDirection( dirImg->GetDirection() );
        itkMaskImage->SetLargestPossibleRegion( dirImg->GetLargestPossibleRegion() );
        itkMaskImage->SetBufferedRegion( dirImg->GetLargestPossibleRegion() );
        itkMaskImage->SetRequestedRegion( dirImg->GetLargestPossibleRegion() );
        itkMaskImage->Allocate();
        itkMaskImage->FillBuffer(1);

        // extract directions from fiber bundle
        itk::TractsToVectorImageFilter<float>::Pointer fOdfFilter = itk::TractsToVectorImageFilter<float>::New();
        fOdfFilter->SetFiberBundle(inputTractogram);
        fOdfFilter->SetMaskImage(itkMaskImage);
        fOdfFilter->SetAngularThreshold(cos(angularThreshold*M_PI/180));
        fOdfFilter->SetNormalizeVectors(true);
        fOdfFilter->SetUseWorkingCopy(false);
        fOdfFilter->SetNumberOfThreads(1);
        fOdfFilter->Update();
        ItkDirectionImageContainerType::Pointer directionImageContainer = fOdfFilter->GetDirectionImageContainer();

        // Get directions and num directions image
        ItkUcharImgType::Pointer numDirImage = fOdfFilter->GetNumDirectionsImage();
        mitk::Image::Pointer mitkNumDirImage = mitk::Image::New();
        mitkNumDirImage->InitializeByItk( numDirImage.GetPointer() );
        mitkNumDirImage->SetVolume( numDirImage->GetBufferPointer() );
        mitk::FiberBundleX::Pointer testDirections = fOdfFilter->GetOutputFiberBundle();

        // evaluate directions with missing directions
        EvaluationFilterType::Pointer evaluationFilter = EvaluationFilterType::New();
        evaluationFilter->SetImageSet(directionImageContainer);
        evaluationFilter->SetReferenceImageSet(referenceImageContainer);
        evaluationFilter->SetMaskImage(itkMaskImage);
        evaluationFilter->SetIgnoreMissingDirections(false);
        evaluationFilter->Update();

        EvaluationFilterType::OutputImageType::Pointer angularErrorImage = evaluationFilter->GetOutput(0);
        mitk::Image::Pointer mitkAngularErrorImage = mitk::Image::New();
        mitkAngularErrorImage->InitializeByItk( angularErrorImage.GetPointer() );
        mitkAngularErrorImage->SetVolume( angularErrorImage->GetBufferPointer() );

        // evaluate directions without missing directions
        evaluationFilter->SetIgnoreMissingDirections(true);
        evaluationFilter->Update();

        EvaluationFilterType::OutputImageType::Pointer angularErrorImageIgnore = evaluationFilter->GetOutput(0);
        mitk::Image::Pointer mitkAngularErrorImageIgnore = mitk::Image::New();
        mitkAngularErrorImageIgnore->InitializeByItk( angularErrorImageIgnore.GetPointer() );
        mitkAngularErrorImageIgnore->SetVolume( angularErrorImageIgnore->GetBufferPointer() );

        mitk::Image::Pointer gtAngularErrorImageIgnore = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(LDFP_ERROR_IMAGE_IGNORE)->GetData());
        mitk::Image::Pointer gtAngularErrorImage = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(LDFP_ERROR_IMAGE)->GetData());
        mitk::Image::Pointer gtNumTestDirImage = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(LDFP_NUM_DIRECTIONS)->GetData());
        mitk::FiberBundleX::Pointer gtTestDirections = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(LDFP_VECTOR_FIELD)->GetData());

        MITK_TEST_CONDITION_REQUIRED(mitk::Equal(gtAngularErrorImageIgnore, mitkAngularErrorImageIgnore, 0.0001, true), "Check if error images are equal (ignored missing directions).");
        MITK_TEST_CONDITION_REQUIRED(mitk::Equal(gtAngularErrorImage, mitkAngularErrorImage, 0.0001, true), "Check if error images are equal.");
        MITK_TEST_CONDITION_REQUIRED(testDirections->Equals(gtTestDirections), "Check if vector fields are equal.");
        MITK_TEST_CONDITION_REQUIRED(mitk::Equal(gtNumTestDirImage, mitkNumDirImage, 0.0001, true), "Check if num direction images 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();
}
예제 #2
0
int StartPeakExtraction(int argc, char* argv[])
{
    mitkCommandLineParser parser;
    parser.setArgumentPrefix("--", "-");
    parser.addArgument("image", "i", mitkCommandLineParser::InputFile, "Input image", "sh coefficient image", us::Any(), false);
    parser.addArgument("outroot", "o", mitkCommandLineParser::OutputDirectory, "Output directory", "output root", us::Any(), false);
    parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask", "mask image");
    parser.addArgument("normalization", "n", mitkCommandLineParser::Int, "Normalization", "0=no norm, 1=max norm, 2=single vec norm", 1, true);
    parser.addArgument("numpeaks", "p", mitkCommandLineParser::Int, "Max. number of peaks", "maximum number of extracted peaks", 2, true);
    parser.addArgument("peakthres", "r", mitkCommandLineParser::Float, "Peak threshold", "peak threshold relative to largest peak", 0.4, true);
    parser.addArgument("abspeakthres", "a", mitkCommandLineParser::Float, "Absolute peak threshold", "absolute peak threshold weighted with local GFA value", 0.06, true);
    parser.addArgument("shConvention", "s", mitkCommandLineParser::String, "Use specified SH-basis", "use specified SH-basis (MITK, FSL, MRtrix)", string("MITK"), true);
    parser.addArgument("noFlip", "f", mitkCommandLineParser::Bool, "No flip", "do not flip input image to match MITK coordinate convention");
    parser.addArgument("clusterThres", "c", mitkCommandLineParser::Float, "Clustering threshold", "directions closer together than the specified angular threshold will be clustered (in rad)", 0.9);
    parser.addArgument("flipX", "fx", mitkCommandLineParser::Bool, "Flip X", "Flip peaks in x direction");
    parser.addArgument("flipY", "fy", mitkCommandLineParser::Bool, "Flip Y", "Flip peaks in y direction");
    parser.addArgument("flipZ", "fz", mitkCommandLineParser::Bool, "Flip Z", "Flip peaks in z direction");


    parser.setCategory("Preprocessing Tools");
    parser.setTitle("Peak Extraction");
    parser.setDescription("");
    parser.setContributor("MIC");

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

    // mandatory arguments
    string imageName = us::any_cast<string>(parsedArgs["image"]);
    string outRoot = us::any_cast<string>(parsedArgs["outroot"]);

    // optional arguments
    string maskImageName("");
    if (parsedArgs.count("mask"))
        maskImageName = us::any_cast<string>(parsedArgs["mask"]);

    int normalization = 1;
    if (parsedArgs.count("normalization"))
        normalization = us::any_cast<int>(parsedArgs["normalization"]);

    int numPeaks = 2;
    if (parsedArgs.count("numpeaks"))
        numPeaks = us::any_cast<int>(parsedArgs["numpeaks"]);

    float peakThres = 0.4;
    if (parsedArgs.count("peakthres"))
        peakThres = us::any_cast<float>(parsedArgs["peakthres"]);

    float absPeakThres = 0.06;
    if (parsedArgs.count("abspeakthres"))
        absPeakThres = us::any_cast<float>(parsedArgs["abspeakthres"]);

    float clusterThres = 0.9;
    if (parsedArgs.count("clusterThres"))
        clusterThres = us::any_cast<float>(parsedArgs["clusterThres"]);

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

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

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

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

    std::cout << "image: " << imageName;
    std::cout << "outroot: " << outRoot;
    if (!maskImageName.empty())
        std::cout << "mask: " << maskImageName;
    else
        std::cout << "no mask image selected";
    std::cout << "numpeaks: " << numPeaks;
    std::cout << "peakthres: " << peakThres;
    std::cout << "abspeakthres: " << absPeakThres;
    std::cout << "shOrder: " << shOrder;

    try
    {
        mitk::Image::Pointer image = dynamic_cast<mitk::Image*>(mitk::IOUtil::Load(imageName)[0].GetPointer());
        mitk::Image::Pointer mask = dynamic_cast<mitk::Image*>(mitk::IOUtil::Load(maskImageName)[0].GetPointer());

        typedef itk::Image<unsigned char, 3>  ItkUcharImgType;
        typedef itk::FiniteDiffOdfMaximaExtractionFilter< float, shOrder, 20242 > MaximaExtractionFilterType;
        typename MaximaExtractionFilterType::Pointer filter = MaximaExtractionFilterType::New();

        int toolkitConvention = 0;

        if (parsedArgs.count("shConvention"))
        {
            string convention = us::any_cast<string>(parsedArgs["shConvention"]).c_str();
            if ( boost::algorithm::equals(convention, "FSL") )
            {
                toolkitConvention = 1;
                std::cout << "Using FSL SH-basis";
            }
            else if ( boost::algorithm::equals(convention, "MRtrix") )
            {
                toolkitConvention = 2;
                std::cout << "Using MRtrix SH-basis";
            }
            else
                std::cout << "Using MITK SH-basis";
        }
        else
            std::cout << "Using MITK SH-basis";

        ItkUcharImgType::Pointer itkMaskImage = nullptr;
        if (mask.IsNotNull())
        {
            try{
                itkMaskImage = ItkUcharImgType::New();
                mitk::CastToItkImage(mask, itkMaskImage);
                filter->SetMaskImage(itkMaskImage);
            }
            catch(...)
            {

            }
        }

        if (toolkitConvention>0)
        {
            std::cout << "Converting coefficient image to MITK format";
            typedef itk::ShCoefficientImageImporter< float, shOrder > ConverterType;
            typedef mitk::ImageToItk< itk::Image< float, 4 > > CasterType;
            CasterType::Pointer caster = CasterType::New();
            caster->SetInput(image);
            caster->Update();
            itk::Image< float, 4 >::Pointer itkImage = caster->GetOutput();

            typename ConverterType::Pointer converter = ConverterType::New();

            if (noFlip)
            {
                converter->SetInputImage(itkImage);
            }
            else
            {
                std::cout << "Flipping image";
                itk::FixedArray<bool, 4> flipAxes;
                flipAxes[0] = true;
                flipAxes[1] = true;
                flipAxes[2] = false;
                flipAxes[3] = false;
                itk::FlipImageFilter< itk::Image< float, 4 > >::Pointer flipper = itk::FlipImageFilter< itk::Image< float, 4 > >::New();
                flipper->SetInput(itkImage);
                flipper->SetFlipAxes(flipAxes);
                flipper->Update();
                itk::Image< float, 4 >::Pointer flipped = flipper->GetOutput();
                itk::Matrix< double,4,4 > m = itkImage->GetDirection(); m[0][0] *= -1; m[1][1] *= -1;
                flipped->SetDirection(m);

                itk::Point< float, 4 > o = itkImage->GetOrigin();
                o[0] -= (flipped->GetLargestPossibleRegion().GetSize(0)-1);
                o[1] -= (flipped->GetLargestPossibleRegion().GetSize(1)-1);
                flipped->SetOrigin(o);
                converter->SetInputImage(flipped);
            }

            std::cout << "Starting conversion";
            switch (toolkitConvention)
            {
            case 1:
                converter->SetToolkit(ConverterType::FSL);
                filter->SetToolkit(MaximaExtractionFilterType::FSL);
                break;
            case 2:
                converter->SetToolkit(ConverterType::MRTRIX);
                filter->SetToolkit(MaximaExtractionFilterType::MRTRIX);
                break;
            default:
                converter->SetToolkit(ConverterType::FSL);
                filter->SetToolkit(MaximaExtractionFilterType::FSL);
                break;
            }
            converter->GenerateData();
            filter->SetInput(converter->GetCoefficientImage());
        }
        else
        {
            try{
                typedef mitk::ImageToItk< typename MaximaExtractionFilterType::CoefficientImageType > CasterType;
                typename CasterType::Pointer caster = CasterType::New();
                caster->SetInput(image);
                caster->Update();
                filter->SetInput(caster->GetOutput());
            }
            catch(...)
            {
                std::cout << "wrong image type";
                return EXIT_FAILURE;
            }
        }

        filter->SetMaxNumPeaks(numPeaks);
        filter->SetPeakThreshold(peakThres);
        filter->SetAbsolutePeakThreshold(absPeakThres);
        filter->SetAngularThreshold(1);
        filter->SetClusteringThreshold(clusterThres);
        filter->SetFlipX(flipX);
        filter->SetFlipY(flipY);
        filter->SetFlipZ(flipZ);

        switch (normalization)
        {
        case 0:
            filter->SetNormalizationMethod(MaximaExtractionFilterType::NO_NORM);
            break;
        case 1:
            filter->SetNormalizationMethod(MaximaExtractionFilterType::MAX_VEC_NORM);
            break;
        case 2:
            filter->SetNormalizationMethod(MaximaExtractionFilterType::SINGLE_VEC_NORM);
            break;
        }

        std::cout << "Starting extraction";
        filter->Update();

        // write direction image
        {
            typename MaximaExtractionFilterType::PeakImageType::Pointer itkImg = filter->GetPeakImage();
            string outfilename = outRoot;
            outfilename.append("_PEAKS.nrrd");

            typedef itk::ImageFileWriter< typename MaximaExtractionFilterType::PeakImageType > WriterType;
            typename WriterType::Pointer writer = WriterType::New();
            writer->SetFileName(outfilename);
            writer->SetInput(itkImg);
            writer->Update();
        }

        // write num directions image
        {
            ItkUcharImgType::Pointer numDirImage = filter->GetNumDirectionsImage();

            if (itkMaskImage.IsNotNull())
            {
                numDirImage->SetDirection(itkMaskImage->GetDirection());
                numDirImage->SetOrigin(itkMaskImage->GetOrigin());
            }

            string outfilename = outRoot.c_str();
            outfilename.append("_NUM_PEAKS.nrrd");
            typedef itk::ImageFileWriter< ItkUcharImgType > WriterType;
            WriterType::Pointer writer = WriterType::New();
            writer->SetFileName(outfilename);
            writer->SetInput(numDirImage);
            writer->Update();
        }
    }
    catch (itk::ExceptionObject e)
    {
        std::cout << e;
        return EXIT_FAILURE;
    }
    catch (std::exception e)
    {
        std::cout << e.what();
        return EXIT_FAILURE;
    }
    catch (...)
    {
        std::cout << "ERROR!?!";
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}
int LocalDirectionalFiberPlausibility(int argc, char* argv[])
{
    ctkCommandLineParser parser;
    parser.setArgumentPrefix("--", "-");
    parser.addArgument("input", "i", ctkCommandLineParser::String, "input tractogram (.fib, vtk ascii file format)", us::Any(), false);
    parser.addArgument("reference", "r", ctkCommandLineParser::StringList, "reference direction images", us::Any(), false);
    parser.addArgument("out", "o", ctkCommandLineParser::String, "output root", us::Any(), false);
    parser.addArgument("mask", "m", ctkCommandLineParser::StringList, "mask images");
    parser.addArgument("athresh", "a", ctkCommandLineParser::Float, "angular threshold in degrees. closer fiber directions are regarded as one direction and clustered together.", 25, true);
    parser.addArgument("verbose", "v", ctkCommandLineParser::Bool, "output optional and intermediate calculation results");
    parser.addArgument("ignore", "n", ctkCommandLineParser::Bool, "don't increase error for missing or too many directions");

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

    ctkCommandLineParser::StringContainerType referenceImages = us::any_cast<ctkCommandLineParser::StringContainerType>(parsedArgs["reference"]);
    ctkCommandLineParser::StringContainerType maskImages;
    if (parsedArgs.count("mask"))
        maskImages = us::any_cast<ctkCommandLineParser::StringContainerType>(parsedArgs["mask"]);

    string fibFile = us::any_cast<string>(parsedArgs["input"]);

    float angularThreshold = 25;
    if (parsedArgs.count("athresh"))
        angularThreshold = us::any_cast<float>(parsedArgs["athresh"]);

    string outRoot = us::any_cast<string>(parsedArgs["out"]);

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

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

    try
    {
        RegisterDiffusionCoreObjectFactory();
        RegisterFiberTrackingObjectFactory();

        typedef itk::Image<unsigned char, 3>                                    ItkUcharImgType;
        typedef itk::Image< itk::Vector< float, 3>, 3 >                         ItkDirectionImage3DType;
        typedef itk::VectorContainer< int, ItkDirectionImage3DType::Pointer >   ItkDirectionImageContainerType;
        typedef itk::EvaluateDirectionImagesFilter< float >                     EvaluationFilterType;

        // load fiber bundle
        mitk::FiberBundleX::Pointer inputTractogram = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(fibFile)->GetData());

        // load reference directions
        ItkDirectionImageContainerType::Pointer referenceImageContainer = ItkDirectionImageContainerType::New();
        for (int i=0; i<referenceImages.size(); i++)
        {
            try
            {
                mitk::Image::Pointer img = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(referenceImages.at(i))->GetData());
                typedef mitk::ImageToItk< ItkDirectionImage3DType > CasterType;
                CasterType::Pointer caster = CasterType::New();
                caster->SetInput(img);
                caster->Update();
                ItkDirectionImage3DType::Pointer itkImg = caster->GetOutput();
                referenceImageContainer->InsertElement(referenceImageContainer->Size(),itkImg);
            }
            catch(...){ MITK_INFO << "could not load: " << referenceImages.at(i); }
        }

        ItkUcharImgType::Pointer itkMaskImage = ItkUcharImgType::New();
        ItkDirectionImage3DType::Pointer dirImg = referenceImageContainer->GetElement(0);
        itkMaskImage->SetSpacing( dirImg->GetSpacing() );
        itkMaskImage->SetOrigin( dirImg->GetOrigin() );
        itkMaskImage->SetDirection( dirImg->GetDirection() );
        itkMaskImage->SetLargestPossibleRegion( dirImg->GetLargestPossibleRegion() );
        itkMaskImage->SetBufferedRegion( dirImg->GetLargestPossibleRegion() );
        itkMaskImage->SetRequestedRegion( dirImg->GetLargestPossibleRegion() );
        itkMaskImage->Allocate();
        itkMaskImage->FillBuffer(1);

        // extract directions from fiber bundle
        itk::TractsToVectorImageFilter<float>::Pointer fOdfFilter = itk::TractsToVectorImageFilter<float>::New();
        fOdfFilter->SetFiberBundle(inputTractogram);
        fOdfFilter->SetMaskImage(itkMaskImage);
        fOdfFilter->SetAngularThreshold(cos(angularThreshold*M_PI/180));
        fOdfFilter->SetNormalizeVectors(true);
        fOdfFilter->SetUseWorkingCopy(false);
        fOdfFilter->Update();
        ItkDirectionImageContainerType::Pointer directionImageContainer = fOdfFilter->GetDirectionImageContainer();

        if (verbose)
        {
            // write vector field
            mitk::FiberBundleX::Pointer directions = fOdfFilter->GetOutputFiberBundle();
            mitk::CoreObjectFactory::FileWriterList fileWriters = mitk::CoreObjectFactory::GetInstance()->GetFileWriters();
            for (mitk::CoreObjectFactory::FileWriterList::iterator it = fileWriters.begin() ; it != fileWriters.end() ; ++it)
            {
                if ( (*it)->CanWriteBaseDataType(directions.GetPointer()) ) {
                    string outfilename = outRoot;
                    outfilename.append("_VECTOR_FIELD.fib");
                    (*it)->SetFileName( outfilename.c_str() );
                    (*it)->DoWrite( directions.GetPointer() );
                }
            }

            // write direction images
            for (int i=0; i<directionImageContainer->Size(); i++)
            {
                itk::TractsToVectorImageFilter<float>::ItkDirectionImageType::Pointer itkImg = directionImageContainer->GetElement(i);
                typedef itk::ImageFileWriter< itk::TractsToVectorImageFilter<float>::ItkDirectionImageType > WriterType;
                WriterType::Pointer writer = WriterType::New();

                string outfilename = outRoot;
                outfilename.append("_DIRECTION_");
                outfilename.append(boost::lexical_cast<string>(i));
                outfilename.append(".nrrd");

                MITK_INFO << "writing " << outfilename;
                writer->SetFileName(outfilename.c_str());
                writer->SetInput(itkImg);
                writer->Update();
            }

            // write num direction image
            {
                ItkUcharImgType::Pointer numDirImage = fOdfFilter->GetNumDirectionsImage();
                typedef itk::ImageFileWriter< ItkUcharImgType > WriterType;
                WriterType::Pointer writer = WriterType::New();

                string outfilename = outRoot;
                outfilename.append("_NUM_DIRECTIONS.nrrd");

                MITK_INFO << "writing " << outfilename;
                writer->SetFileName(outfilename.c_str());
                writer->SetInput(numDirImage);
                writer->Update();
            }
        }

        string logFile = outRoot;
        logFile.append("_ANGULAR_ERROR.csv");
        ofstream file;
        file.open (logFile.c_str());

        if (maskImages.size()>0)
        {
            for (int i=0; i<maskImages.size(); i++)
            {
                mitk::Image::Pointer mitkMaskImage = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(maskImages.at(i))->GetData());
                mitk::CastToItkImage<ItkUcharImgType>(mitkMaskImage, itkMaskImage);

                // evaluate directions
                EvaluationFilterType::Pointer evaluationFilter = EvaluationFilterType::New();
                evaluationFilter->SetImageSet(directionImageContainer);
                evaluationFilter->SetReferenceImageSet(referenceImageContainer);
                evaluationFilter->SetMaskImage(itkMaskImage);
                evaluationFilter->SetIgnoreMissingDirections(ignore);
                evaluationFilter->Update();

                if (verbose)
                {
                    EvaluationFilterType::OutputImageType::Pointer angularErrorImage = evaluationFilter->GetOutput(0);
                    typedef itk::ImageFileWriter< EvaluationFilterType::OutputImageType > WriterType;
                    WriterType::Pointer writer = WriterType::New();

                    string outfilename = outRoot;
                    outfilename.append("_ERROR_IMAGE.nrrd");

                    MITK_INFO << "writing " << outfilename;
                    writer->SetFileName(outfilename.c_str());
                    writer->SetInput(angularErrorImage);
                    writer->Update();
                }

                string sens = itksys::SystemTools::GetFilenameWithoutExtension(itksys::SystemTools::GetFilenameName(fibFile));
                sens.append(",");

                sens.append(itksys::SystemTools::GetFilenameWithoutExtension(itksys::SystemTools::GetFilenameName(maskImages.at(i))));
                sens.append(",");

                sens.append(boost::lexical_cast<string>(evaluationFilter->GetMeanAngularError()));
                sens.append(",");

                sens.append(boost::lexical_cast<string>(evaluationFilter->GetMedianAngularError()));
                sens.append(",");

                sens.append(boost::lexical_cast<string>(evaluationFilter->GetMaxAngularError()));
                sens.append(",");

                sens.append(boost::lexical_cast<string>(evaluationFilter->GetMinAngularError()));
                sens.append(",");

                sens.append(boost::lexical_cast<string>(std::sqrt(evaluationFilter->GetVarAngularError())));
                sens.append(";\n");
                file << sens;
            }
        }
        else
        {
            // evaluate directions
            EvaluationFilterType::Pointer evaluationFilter = EvaluationFilterType::New();
            evaluationFilter->SetImageSet(directionImageContainer);
            evaluationFilter->SetReferenceImageSet(referenceImageContainer);
            evaluationFilter->SetMaskImage(itkMaskImage);
            evaluationFilter->SetIgnoreMissingDirections(ignore);
            evaluationFilter->Update();

            if (verbose)
            {
                EvaluationFilterType::OutputImageType::Pointer angularErrorImage = evaluationFilter->GetOutput(0);
                typedef itk::ImageFileWriter< EvaluationFilterType::OutputImageType > WriterType;
                WriterType::Pointer writer = WriterType::New();

                string outfilename = outRoot;
                outfilename.append("_ERROR_IMAGE.nrrd");

                MITK_INFO << "writing " << outfilename;
                writer->SetFileName(outfilename.c_str());
                writer->SetInput(angularErrorImage);
                writer->Update();
            }

            string sens = itksys::SystemTools::GetFilenameWithoutExtension(itksys::SystemTools::GetFilenameName(fibFile));
            sens.append(",");

            sens.append("FULL");
            sens.append(",");

            sens.append(boost::lexical_cast<string>(evaluationFilter->GetMeanAngularError()));
            sens.append(",");

            sens.append(boost::lexical_cast<string>(evaluationFilter->GetMedianAngularError()));
            sens.append(",");

            sens.append(boost::lexical_cast<string>(evaluationFilter->GetMaxAngularError()));
            sens.append(",");

            sens.append(boost::lexical_cast<string>(evaluationFilter->GetMinAngularError()));
            sens.append(",");

            sens.append(boost::lexical_cast<string>(std::sqrt(evaluationFilter->GetVarAngularError())));
            sens.append(";\n");
            file << sens;
        }
        file.close();

        MITK_INFO << "DONE";
    }
    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;
}
예제 #4
0
int TractogramAngularError(int argc, char* argv[])
{
    ctkCommandLineParser parser;
    parser.setArgumentPrefix("--", "-");
    parser.addArgument("input", "i", ctkCommandLineParser::String, "input tractogram (.fib, vtk ascii file format)", us::Any(), false);
    parser.addArgument("reference", "r", ctkCommandLineParser::StringList, "reference direction images", us::Any(), false);
    parser.addArgument("out", "o", ctkCommandLineParser::String, "output root", us::Any(), false);
    parser.addArgument("mask", "m", ctkCommandLineParser::String, "mask image");
    parser.addArgument("verbose", "v", ctkCommandLineParser::Bool, "output optional and intermediate calculation results");
    parser.addArgument("ignore", "n", ctkCommandLineParser::Bool, "don't increase error for missing or too many directions");
    parser.addArgument("trilinear", "t", ctkCommandLineParser::Bool, "use trilinear instead of nearest neighbor interpolation");

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

    ctkCommandLineParser::StringContainerType referenceImages = us::any_cast<ctkCommandLineParser::StringContainerType>(parsedArgs["reference"]);

    string fibFile = us::any_cast<string>(parsedArgs["input"]);

    string maskImage("");
    if (parsedArgs.count("mask"))
        maskImage = us::any_cast<string>(parsedArgs["mask"]);

    string outRoot = us::any_cast<string>(parsedArgs["out"]);

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

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

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

    try
    {
        RegisterDiffusionCoreObjectFactory();
        RegisterFiberTrackingObjectFactory();

        typedef itk::Image<unsigned char, 3>                                    ItkUcharImgType;
        typedef itk::Image< itk::Vector< float, 3>, 3 >                         ItkDirectionImage3DType;
        typedef itk::VectorContainer< int, ItkDirectionImage3DType::Pointer >   ItkDirectionImageContainerType;
        typedef itk::EvaluateTractogramDirectionsFilter< float >                EvaluationFilterType;

        // load fiber bundle
        mitk::FiberBundleX::Pointer inputTractogram = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(fibFile)->GetData());
        if (!inputTractogram)
            return EXIT_FAILURE;

        // load reference directions
        ItkDirectionImageContainerType::Pointer referenceImageContainer = ItkDirectionImageContainerType::New();
        for (int i=0; i<referenceImages.size(); i++)
        {
            try
            {
                mitk::Image::Pointer img = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(referenceImages.at(i))->GetData());
                typedef mitk::ImageToItk< ItkDirectionImage3DType > CasterType;
                CasterType::Pointer caster = CasterType::New();
                caster->SetInput(img);
                caster->Update();
                ItkDirectionImage3DType::Pointer itkImg = caster->GetOutput();
                referenceImageContainer->InsertElement(referenceImageContainer->Size(),itkImg);
            }
            catch(...) {
                MITK_INFO << "could not load: " << referenceImages.at(i);
            }
        }

        // load/create mask image
        ItkUcharImgType::Pointer itkMaskImage = ItkUcharImgType::New();
        if (maskImage.compare("")==0)
        {
            ItkDirectionImage3DType::Pointer dirImg = referenceImageContainer->GetElement(0);
            itkMaskImage->SetSpacing( dirImg->GetSpacing() );
            itkMaskImage->SetOrigin( dirImg->GetOrigin() );
            itkMaskImage->SetDirection( dirImg->GetDirection() );
            itkMaskImage->SetLargestPossibleRegion( dirImg->GetLargestPossibleRegion() );
            itkMaskImage->SetBufferedRegion( dirImg->GetLargestPossibleRegion() );
            itkMaskImage->SetRequestedRegion( dirImg->GetLargestPossibleRegion() );
            itkMaskImage->Allocate();
            itkMaskImage->FillBuffer(1);
        }
        else
        {
            mitk::Image::Pointer mitkMaskImage = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(maskImage)->GetData());
            mitk::CastToItkImage<ItkUcharImgType>(mitkMaskImage, itkMaskImage);
        }

        // evaluate directions
        EvaluationFilterType::Pointer evaluationFilter = EvaluationFilterType::New();
        evaluationFilter->SetTractogram(inputTractogram);
        evaluationFilter->SetReferenceImageSet(referenceImageContainer);
        evaluationFilter->SetMaskImage(itkMaskImage);
        evaluationFilter->SetIgnoreMissingDirections(ignore);
        evaluationFilter->SetUseInterpolation(interpolate);
        evaluationFilter->Update();

        if (verbose)
        {
            EvaluationFilterType::OutputImageType::Pointer angularErrorImage = evaluationFilter->GetOutput(0);
            typedef itk::ImageFileWriter< EvaluationFilterType::OutputImageType > WriterType;
            WriterType::Pointer writer = WriterType::New();

            string outfilename = outRoot;
            outfilename.append("_ERROR_IMAGE.nrrd");

            MITK_INFO << "writing " << outfilename;
            writer->SetFileName(outfilename.c_str());
            writer->SetInput(angularErrorImage);
            writer->Update();
        }

        string logFile = outRoot;
        logFile.append("_ANGULAR_ERROR.csv");

        ofstream file;
        file.open (logFile.c_str());

        string sens = "Mean:";
        sens.append(",");
        sens.append(boost::lexical_cast<string>(evaluationFilter->GetMeanAngularError()));
        sens.append(";\n");

        sens.append("Median:");
        sens.append(",");
        sens.append(boost::lexical_cast<string>(evaluationFilter->GetMedianAngularError()));
        sens.append(";\n");

        sens.append("Maximum:");
        sens.append(",");
        sens.append(boost::lexical_cast<string>(evaluationFilter->GetMaxAngularError()));
        sens.append(";\n");

        sens.append("Minimum:");
        sens.append(",");
        sens.append(boost::lexical_cast<string>(evaluationFilter->GetMinAngularError()));
        sens.append(";\n");

        sens.append("STDEV:");
        sens.append(",");
        sens.append(boost::lexical_cast<string>(std::sqrt(evaluationFilter->GetVarAngularError())));
        sens.append(";\n");

        file << sens;

        file.close();

        MITK_INFO << "DONE";
    }
    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 QmitkDwiSoftwarePhantomView::GeneratePhantom()
{
    typedef itk::DwiPhantomGenerationFilter< short > FilterType;
    FilterType::GradientListType gradientList;

    m_SignalRegions.clear();
    for (int i=0; i<m_SignalRegionNodes.size(); i++)
    {
        mitk::Image::Pointer mitkBinaryImg = dynamic_cast<mitk::Image*>(m_SignalRegionNodes.at(i)->GetData());
        ItkUcharImgType::Pointer signalRegion = ItkUcharImgType::New();
        mitk::CastToItkImage<ItkUcharImgType>(mitkBinaryImg, signalRegion);
        m_SignalRegions.push_back(signalRegion);
    }

    switch(m_Controls->m_TensorsToDWINumDirsSelect->currentIndex())
    {
    case 0:
        gradientList = MakeGradientList<12>();
        break;
    case 1:
        gradientList = MakeGradientList<42>();
        break;
    case 2:
        gradientList = MakeGradientList<92>();
        break;
    case 3:
        gradientList = MakeGradientList<162>();
        break;
    case 4:
        gradientList = MakeGradientList<252>();
        break;
    case 5:
        gradientList = MakeGradientList<362>();
        break;
    case 6:
        gradientList = MakeGradientList<492>();
        break;
    case 7:
        gradientList = MakeGradientList<642>();
        break;
    case 8:
        gradientList = MakeGradientList<812>();
        break;
    case 9:
        gradientList = MakeGradientList<1002>();
        break;
    default:
        gradientList = MakeGradientList<92>();
    }
    double bVal = m_Controls->m_TensorsToDWIBValueEdit->value();
    itk::ImageRegion<3> imageRegion;
    imageRegion.SetSize(0, m_Controls->m_SizeX->value());
    imageRegion.SetSize(1, m_Controls->m_SizeY->value());
    imageRegion.SetSize(2, m_Controls->m_SizeZ->value());
    mitk::Vector3D spacing;
    spacing[0] = m_Controls->m_SpacingX->value();
    spacing[1] = m_Controls->m_SpacingY->value();
    spacing[2] = m_Controls->m_SpacingZ->value();

    FilterType::Pointer filter = FilterType::New();
    filter->SetGradientList(gradientList);
    filter->SetBValue(bVal);
    filter->SetSNR(m_Controls->m_NoiseLevel->value());
    filter->SetSignalScale(m_Controls->m_SignalScale->value());
    filter->SetImageRegion(imageRegion);
    filter->SetSpacing(spacing);
    filter->SetSignalRegions(m_SignalRegions);
    filter->SetGreyMatterAdc(m_Controls->m_GmAdc->value());

    std::vector< float >                            tensorFA;
    std::vector< float >                            tensorADC;
    std::vector< float >                            tensorWeight;
    std::vector< vnl_vector_fixed<double, 3> >      tensorDirection;
    for (int i=0; i<m_SpinFa.size(); i++)
    {
        tensorFA.push_back(m_SpinFa.at(i)->value());
        tensorADC.push_back(m_SpinAdc.at(i)->value());
        vnl_vector_fixed<double, 3> dir;
        dir[0] = m_SpinX.at(i)->value();
        dir[1] = m_SpinY.at(i)->value();
        dir[2] = m_SpinZ.at(i)->value();
        dir.normalize();
        tensorDirection.push_back(dir);
        tensorWeight.push_back(m_SpinWeight.at(i)->value());
    }
    filter->SetTensorFA(tensorFA);
    filter->SetTensorADC(tensorADC);
    filter->SetTensorWeight(tensorWeight);
    filter->SetTensorDirection(tensorDirection);
    filter->Update();

    mitk::DiffusionImage<short>::Pointer image = mitk::DiffusionImage<short>::New();
    image->SetVectorImage( filter->GetOutput() );
    image->SetB_Value(bVal);
    image->SetDirections(gradientList);
    image->InitializeFromVectorImage();
    mitk::DataNode::Pointer node = mitk::DataNode::New();
    node->SetData( image );
    node->SetName(m_Controls->m_ImageName->text().toStdString());
    GetDataStorage()->Add(node);

    if (m_Controls->m_OutputNumDirectionsBox->isChecked())
    {
        ItkUcharImgType::Pointer numDirImage = filter->GetNumDirectionsImage();
        mitk::Image::Pointer image2 = mitk::Image::New();
        image2->InitializeByItk( numDirImage.GetPointer() );
        image2->SetVolume( numDirImage->GetBufferPointer() );
        mitk::DataNode::Pointer node2 = mitk::DataNode::New();
        node2->SetData(image2);
        QString name(m_Controls->m_ImageName->text());
        name += "_NumDirections";
        node2->SetName(name.toStdString().c_str());
        GetDataStorage()->Add(node2);
    }

    if (m_SignalRegionNodes.size()==0)
        return;

    if (m_Controls->m_OutputDirectionImagesBox->isChecked())
    {
        typedef FilterType::ItkDirectionImageContainer ItkDirectionImageContainer;
        ItkDirectionImageContainer::Pointer container = filter->GetDirectionImageContainer();
        for (int i=0; i<container->Size(); i++)
        {
            FilterType::ItkDirectionImage::Pointer itkImg = container->GetElement(i);
            mitk::Image::Pointer img = mitk::Image::New();
            img->InitializeByItk( itkImg.GetPointer() );
            img->SetVolume( itkImg->GetBufferPointer() );
            mitk::DataNode::Pointer node = mitk::DataNode::New();
            node->SetData(img);
            QString name(m_Controls->m_ImageName->text());
            name += "_Direction";
            name += QString::number(i+1);
            node->SetName(name.toStdString().c_str());
            GetDataStorage()->Add(node);
        }
    }

    if (m_Controls->m_OutputVectorFieldBox->isChecked())
    {
        mitk::Geometry3D::Pointer geometry = image->GetGeometry();
        mitk::Vector3D outImageSpacing = geometry->GetSpacing();
        float minSpacing = 1;
        if(outImageSpacing[0]<outImageSpacing[1] && outImageSpacing[0]<outImageSpacing[2])
            minSpacing = outImageSpacing[0];
        else if (outImageSpacing[1] < outImageSpacing[2])
            minSpacing = outImageSpacing[1];
        else
            minSpacing = outImageSpacing[2];

        mitk::FiberBundleX::Pointer directions = filter->GetOutputFiberBundle();
        directions->SetGeometry(geometry);
        mitk::DataNode::Pointer node = mitk::DataNode::New();
        node->SetData(directions);
        QString name(m_Controls->m_ImageName->text());
        name += "_VectorField";
        node->SetName(name.toStdString().c_str());
        node->SetProperty("Fiber2DSliceThickness", mitk::FloatProperty::New(minSpacing));
        node->SetProperty("Fiber2DfadeEFX", mitk::BoolProperty::New(false));
        GetDataStorage()->Add(node);
    }
}
예제 #6
0
void QmitkOdfMaximaExtractionView::GenerateDataFromDwi()
{
    typedef itk::OdfMaximaExtractionFilter< float > MaximaExtractionFilterType;
    MaximaExtractionFilterType::Pointer filter = MaximaExtractionFilterType::New();

    mitk::Geometry3D::Pointer geometry;
    if (!m_ImageNodes.empty())
    {
        try{
            Image::Pointer img = dynamic_cast<Image*>(m_ImageNodes.at(0)->GetData());
            typedef ImageToItk< MaximaExtractionFilterType::CoefficientImageType > CasterType;
            CasterType::Pointer caster = CasterType::New();
            caster->SetInput(img);
            caster->Update();
            filter->SetShCoeffImage(caster->GetOutput());
            geometry = img->GetGeometry();
        }
        catch(itk::ExceptionObject &e)
        {
            MITK_INFO << "wrong image type: " << e.what();
            return;
        }
    }
    else
        return;

    filter->SetMaxNumPeaks(m_Controls->m_MaxNumPeaksBox->value());
    filter->SetPeakThreshold(m_Controls->m_PeakThresholdBox->value());

    if (!m_BinaryImageNodes.empty())
    {
        ItkUcharImgType::Pointer itkMaskImage = ItkUcharImgType::New();
        Image::Pointer mitkMaskImg = dynamic_cast<Image*>(m_BinaryImageNodes.at(0)->GetData());
        CastToItkImage<ItkUcharImgType>(mitkMaskImg, itkMaskImage);
        filter->SetMaskImage(itkMaskImage);
    }

    switch (m_Controls->m_NormalizationBox->currentIndex())
    {
    case 0:
        filter->SetNormalizationMethod(MaximaExtractionFilterType::NO_NORM);
        break;
    case 1:
        filter->SetNormalizationMethod(MaximaExtractionFilterType::MAX_VEC_NORM);
        break;
    case 2:
        filter->SetNormalizationMethod(MaximaExtractionFilterType::SINGLE_VEC_NORM);
        break;
    }

    filter->GenerateData();

    ItkUcharImgType::Pointer numDirImage = filter->GetNumDirectionsImage();

    if (m_Controls->m_OutputDirectionImagesBox->isChecked())
    {
        typedef MaximaExtractionFilterType::ItkDirectionImageContainer ItkDirectionImageContainer;
        ItkDirectionImageContainer::Pointer container = filter->GetDirectionImageContainer();
        for (int i=0; i<container->Size(); i++)
        {
            MaximaExtractionFilterType::ItkDirectionImage::Pointer itkImg = container->GetElement(i);
            mitk::Image::Pointer img = mitk::Image::New();
            img->InitializeByItk( itkImg.GetPointer() );
            img->SetVolume( itkImg->GetBufferPointer() );
            DataNode::Pointer node = DataNode::New();
            node->SetData(img);
            QString name(m_ImageNodes.at(0)->GetName().c_str());
            name += "_Direction";
            name += QString::number(i+1);
            node->SetName(name.toStdString().c_str());
            GetDataStorage()->Add(node);
        }
    }

    if (m_Controls->m_OutputNumDirectionsBox->isChecked())
    {
        mitk::Image::Pointer image2 = mitk::Image::New();
        image2->InitializeByItk( numDirImage.GetPointer() );
        image2->SetVolume( numDirImage->GetBufferPointer() );
        DataNode::Pointer node = DataNode::New();
        node->SetData(image2);
        QString name(m_ImageNodes.at(0)->GetName().c_str());
        name += "_NumDirections";
        node->SetName(name.toStdString().c_str());
        GetDataStorage()->Add(node);
    }

    if (m_Controls->m_OutputVectorFieldBox->isChecked())
    {
        mitk::Vector3D outImageSpacing = geometry->GetSpacing();
        float minSpacing = 1;
        if(outImageSpacing[0]<outImageSpacing[1] && outImageSpacing[0]<outImageSpacing[2])
            minSpacing = outImageSpacing[0];
        else if (outImageSpacing[1] < outImageSpacing[2])
            minSpacing = outImageSpacing[1];
        else
            minSpacing = outImageSpacing[2];

        mitk::FiberBundleX::Pointer directions = filter->GetOutputFiberBundle();
        directions->SetGeometry(geometry);
        DataNode::Pointer node = DataNode::New();
        node->SetData(directions);
        QString name(m_ImageNodes.at(0)->GetName().c_str());
        name += "_VectorField";
        node->SetName(name.toStdString().c_str());
        node->SetProperty("Fiber2DSliceThickness", mitk::FloatProperty::New(minSpacing));
        node->SetProperty("Fiber2DfadeEFX", mitk::BoolProperty::New(false));
        GetDataStorage()->Add(node);
    }
}
예제 #7
0
void QmitkOdfMaximaExtractionView::StartTensor()
{
    if (m_TensorImageNodes.empty())
        return;

    typedef itk::DiffusionTensorPrincipalDirectionImageFilter< float, float > MaximaExtractionFilterType;
    MaximaExtractionFilterType::Pointer filter = MaximaExtractionFilterType::New();

    mitk::Geometry3D::Pointer geometry;
    try{
        TensorImage::Pointer img = dynamic_cast<TensorImage*>(m_TensorImageNodes.at(0)->GetData());
        ItkTensorImage::Pointer itkImage = ItkTensorImage::New();
        CastToItkImage<ItkTensorImage>(img, itkImage);
        filter->SetInput(itkImage);
        geometry = img->GetGeometry();
    }
    catch(itk::ExceptionObject &e)
    {
        MITK_INFO << "wrong image type: " << e.what();
        throw e;
    }

    if (!m_BinaryImageNodes.empty())
    {
        ItkUcharImgType::Pointer itkMaskImage = ItkUcharImgType::New();
        Image::Pointer mitkMaskImg = dynamic_cast<Image*>(m_BinaryImageNodes.at(0)->GetData());
        CastToItkImage<ItkUcharImgType>(mitkMaskImg, itkMaskImage);
        filter->SetMaskImage(itkMaskImage);
    }

    if (m_Controls->m_NormalizationBox->currentIndex()==0)
        filter->SetNormalizeVectors(false);

    filter->Update();

    if (m_Controls->m_OutputDirectionImagesBox->isChecked())
    {
        MaximaExtractionFilterType::OutputImageType::Pointer itkImg = filter->GetOutput();
        mitk::Image::Pointer img = mitk::Image::New();
        img->InitializeByItk( itkImg.GetPointer() );
        img->SetVolume( itkImg->GetBufferPointer() );
        DataNode::Pointer node = DataNode::New();
        node->SetData(img);
        QString name(m_TensorImageNodes.at(0)->GetName().c_str());
        name += "_PrincipalDirection";
        node->SetName(name.toStdString().c_str());
        GetDataStorage()->Add(node);
    }

    if (m_Controls->m_OutputNumDirectionsBox->isChecked())
    {
        ItkUcharImgType::Pointer numDirImage = filter->GetNumDirectionsImage();
        mitk::Image::Pointer image2 = mitk::Image::New();
        image2->InitializeByItk( numDirImage.GetPointer() );
        image2->SetVolume( numDirImage->GetBufferPointer() );
        DataNode::Pointer node2 = DataNode::New();
        node2->SetData(image2);
        QString name(m_TensorImageNodes.at(0)->GetName().c_str());
        name += "_NumDirections";
        node2->SetName(name.toStdString().c_str());
        GetDataStorage()->Add(node2);
    }

    if (m_Controls->m_OutputVectorFieldBox->isChecked())
    {
        mitk::Vector3D outImageSpacing = geometry->GetSpacing();
        float minSpacing = 1;
        if(outImageSpacing[0]<outImageSpacing[1] && outImageSpacing[0]<outImageSpacing[2])
            minSpacing = outImageSpacing[0];
        else if (outImageSpacing[1] < outImageSpacing[2])
            minSpacing = outImageSpacing[1];
        else
            minSpacing = outImageSpacing[2];

        mitk::FiberBundleX::Pointer directions = filter->GetOutputFiberBundle();
        directions->SetGeometry(geometry);
        DataNode::Pointer node = DataNode::New();
        node->SetData(directions);
        QString name(m_TensorImageNodes.at(0)->GetName().c_str());
        name += "_VectorField";
        node->SetName(name.toStdString().c_str());
        node->SetProperty("Fiber2DSliceThickness", mitk::FloatProperty::New(minSpacing));
        node->SetProperty("Fiber2DfadeEFX", mitk::BoolProperty::New(false));
        GetDataStorage()->Add(node);
    }
}
예제 #8
0
void DwiPhantomGenerationFilter< TOutputScalarType >
::GenerateData()
{
    if (m_NoiseVariance < 0)
        m_NoiseVariance = 0.001;

    if (!m_SimulateBaseline)
    {
        MITK_INFO << "Baseline image values are set to default. Noise variance value is treated as SNR!";
        if (m_NoiseVariance <= 0)
            m_NoiseVariance = 0.0001;
        if (m_NoiseVariance>99)
            m_NoiseVariance = 0;
        else
        {
            m_NoiseVariance = m_DefaultBaseline/(m_NoiseVariance*m_SignalScale);
            m_NoiseVariance *= m_NoiseVariance;
        }
    }

    m_RandGen = Statistics::MersenneTwisterRandomVariateGenerator::New();
    m_RandGen->SetSeed();

    typename OutputImageType::Pointer outImage = OutputImageType::New();
    outImage->SetSpacing( m_Spacing );
    outImage->SetOrigin( m_Origin );
    outImage->SetDirection( m_DirectionMatrix );
    outImage->SetLargestPossibleRegion( m_ImageRegion );
    outImage->SetBufferedRegion( m_ImageRegion );
    outImage->SetRequestedRegion( m_ImageRegion );
    outImage->SetVectorLength(m_GradientList.size());
    outImage->Allocate();
    typename OutputImageType::PixelType pix;
    pix.SetSize(m_GradientList.size());
    pix.Fill(0.0);
    outImage->FillBuffer(pix);
    this->SetNthOutput (0, outImage);

    double minSpacing = m_Spacing[0];
    if (m_Spacing[1]<minSpacing)
        minSpacing = m_Spacing[1];
    if (m_Spacing[2]<minSpacing)
        minSpacing = m_Spacing[2];

    m_DirectionImageContainer = ItkDirectionImageContainer::New();
    for (int i=0; i<m_SignalRegions.size(); i++)
    {
        itk::Vector< float, 3 > nullVec; nullVec.Fill(0.0);
        ItkDirectionImage::Pointer img = ItkDirectionImage::New();
        img->SetSpacing( m_Spacing );
        img->SetOrigin( m_Origin );
        img->SetDirection( m_DirectionMatrix );
        img->SetRegions( m_ImageRegion );
        img->Allocate();
        img->FillBuffer(nullVec);
        m_DirectionImageContainer->InsertElement(m_DirectionImageContainer->Size(), img);
    }
    m_NumDirectionsImage = ItkUcharImgType::New();
    m_NumDirectionsImage->SetSpacing( m_Spacing );
    m_NumDirectionsImage->SetOrigin( m_Origin );
    m_NumDirectionsImage->SetDirection( m_DirectionMatrix );
    m_NumDirectionsImage->SetRegions( m_ImageRegion );
    m_NumDirectionsImage->Allocate();
    m_NumDirectionsImage->FillBuffer(0);

    m_SNRImage = ItkFloatImgType::New();
    m_SNRImage->SetSpacing( m_Spacing );
    m_SNRImage->SetOrigin( m_Origin );
    m_SNRImage->SetDirection( m_DirectionMatrix );
    m_SNRImage->SetRegions( m_ImageRegion );
    m_SNRImage->Allocate();
    m_SNRImage->FillBuffer(0);

    vtkSmartPointer<vtkCellArray> m_VtkCellArray = vtkSmartPointer<vtkCellArray>::New();
    vtkSmartPointer<vtkPoints>    m_VtkPoints = vtkSmartPointer<vtkPoints>::New();

    m_BaselineImages = 0;
    for( unsigned int i=0; i<m_GradientList.size(); i++)
        if (m_GradientList[i].GetNorm()<=0.0001)
            m_BaselineImages++;

    typedef ImageRegionIterator<OutputImageType>      IteratorOutputType;
    IteratorOutputType it (outImage, m_ImageRegion);

    // isotropic tensor
    itk::DiffusionTensor3D<float> isoTensor;
    isoTensor.Fill(0);
    float e1 = m_GreyMatterAdc;
    float e2 = m_GreyMatterAdc;
    float e3 = m_GreyMatterAdc;
    isoTensor.SetElement(0,e1);
    isoTensor.SetElement(3,e2);
    isoTensor.SetElement(5,e3);
    m_MaxBaseline = GetTensorL2Norm(isoTensor);

    GenerateTensors();

    // simulate measurement
    m_MeanBaseline = 0;
    double noiseStdev = sqrt(m_NoiseVariance);
    while(!it.IsAtEnd())
    {
        pix = it.Get();
        typename OutputImageType::IndexType index = it.GetIndex();

        int numDirs = 0;
        for (int i=0; i<m_SignalRegions.size(); i++)
        {
            ItkUcharImgType::Pointer region = m_SignalRegions.at(i);

            if (region->GetPixel(index)!=0)
            {
                numDirs++;
                pix += SimulateMeasurement(m_TensorList[i], m_TensorWeight[i]);

                // set direction image pixel
                ItkDirectionImage::Pointer img = m_DirectionImageContainer->GetElement(i);
                itk::Vector< float, 3 > pixel = img->GetPixel(index);
                vnl_vector_fixed<double, 3> dir = m_TensorDirection.at(i);
                dir.normalize();
                dir *= m_TensorWeight.at(i);
                pixel.SetElement(0, dir[0]);
                pixel.SetElement(1, dir[1]);
                pixel.SetElement(2, dir[2]);
                img->SetPixel(index, pixel);

                vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
                itk::ContinuousIndex<double, 3> center;
                center[0] = index[0];
                center[1] = index[1];
                center[2] = index[2];
                itk::Point<double> worldCenter;
                outImage->TransformContinuousIndexToPhysicalPoint( center, worldCenter );
                itk::Point<double> worldStart;
                worldStart[0] = worldCenter[0]-dir[0]/2 * minSpacing;
                worldStart[1] = worldCenter[1]-dir[1]/2 * minSpacing;
                worldStart[2] = worldCenter[2]-dir[2]/2 * minSpacing;
                vtkIdType id = m_VtkPoints->InsertNextPoint(worldStart.GetDataPointer());
                container->GetPointIds()->InsertNextId(id);
                itk::Point<double> worldEnd;
                worldEnd[0] = worldCenter[0]+dir[0]/2 * minSpacing;
                worldEnd[1] = worldCenter[1]+dir[1]/2 * minSpacing;
                worldEnd[2] = worldCenter[2]+dir[2]/2 * minSpacing;
                id = m_VtkPoints->InsertNextPoint(worldEnd.GetDataPointer());
                container->GetPointIds()->InsertNextId(id);
                m_VtkCellArray->InsertNextCell(container);
            }
        }

        if (numDirs>1)
        {
            for (int i=0; i<m_GradientList.size(); i++)
                pix[i] /= numDirs;
        }
        else if (numDirs==0)
        {
            if (m_SimulateBaseline)
                pix = SimulateMeasurement(isoTensor, 1.0);
            else
                pix.Fill(0.0);
        }

        m_MeanBaseline += pix[0];
        it.Set(pix);
        m_NumDirectionsImage->SetPixel(index, numDirs);
        if (m_NoiseVariance>0)
            m_SNRImage->SetPixel(index, pix[0]/(noiseStdev*m_SignalScale));
        ++it;
    }
    m_MeanBaseline /= m_ImageRegion.GetNumberOfPixels();
    if (m_NoiseVariance>0)
        MITK_INFO << "Mean SNR: " << m_MeanBaseline/(noiseStdev*m_SignalScale);
    else
        MITK_INFO << "No noise added";

    // add rician noise
    it.GoToBegin();
    while(!it.IsAtEnd())
    {
        pix = it.Get();
        AddNoise(pix);
        it.Set(pix);
        ++it;
    }

    // generate fiber bundle
    vtkSmartPointer<vtkPolyData> directionsPolyData = vtkSmartPointer<vtkPolyData>::New();
    directionsPolyData->SetPoints(m_VtkPoints);
    directionsPolyData->SetLines(m_VtkCellArray);
    m_OutputFiberBundle = mitk::FiberBundleX::New(directionsPolyData);
}