void FibersFromPlanarFiguresFilter::GeneratePoints()
{
    Statistics::MersenneTwisterRandomVariateGenerator::Pointer randGen = Statistics::MersenneTwisterRandomVariateGenerator::New();
    randGen->SetSeed((unsigned int)0);
    m_2DPoints.clear();
    unsigned int count = 0;

    while (count < m_Parameters.m_Density)
    {
        mitk::Vector2D p;
        switch (m_Parameters.m_Distribution) {
            case FiberGenerationParameters::DISTRIBUTE_GAUSSIAN:
                p[0] = randGen->GetNormalVariate(0, m_Parameters.m_Variance);
                p[1] = randGen->GetNormalVariate(0, m_Parameters.m_Variance);
                break;
            default:
                p[0] = randGen->GetUniformVariate(-1, 1);
                p[1] = randGen->GetUniformVariate(-1, 1);
        }

        if (sqrt(p[0]*p[0]+p[1]*p[1]) <= 1)
        {
            m_2DPoints.push_back(p);
            count++;
        }
    }
}
예제 #2
0
void
GibbsTrackingFilter< ItkQBallImageType >
::EstimateParticleWeight()
{
    MITK_INFO << "GibbsTrackingFilter: estimating particle weight";

    float minSpacing;
    if(m_QBallImage->GetSpacing()[0]<m_QBallImage->GetSpacing()[1] && m_QBallImage->GetSpacing()[0]<m_QBallImage->GetSpacing()[2])
        minSpacing = m_QBallImage->GetSpacing()[0];
    else if (m_QBallImage->GetSpacing()[1] < m_QBallImage->GetSpacing()[2])
        minSpacing = m_QBallImage->GetSpacing()[1];
    else
        minSpacing = m_QBallImage->GetSpacing()[2];
    float m_ParticleLength = 1.5*minSpacing;
    float m_ParticleWidth = 0.5*minSpacing;

    // seed random generators
    Statistics::MersenneTwisterRandomVariateGenerator::Pointer randGen = Statistics::MersenneTwisterRandomVariateGenerator::New();
    if (m_RandomSeed>-1)
        randGen->SetSeed(m_RandomSeed);
    else
        randGen->SetSeed();

    // instantiate all necessary components
    SphereInterpolator* interpolator = new SphereInterpolator(m_LutPath);
    // handle lookup table not found cases
    if( !interpolator->IsInValidState() )
    {
      m_IsInValidState = false;
      m_AbortTracking = true;
      m_BuildFibers = false;
      mitkThrow() << "Unable to load lookup tables.";
    }
    ParticleGrid* particleGrid = new ParticleGrid(m_MaskImage, m_ParticleLength, m_ParticleGridCellCapacity);
    GibbsEnergyComputer* encomp = new GibbsEnergyComputer(m_QBallImage, m_MaskImage, particleGrid, interpolator, randGen);

    //    EnergyComputer* encomp = new EnergyComputer(m_QBallImage, m_MaskImage, particleGrid, interpolator, randGen);
    MetropolisHastingsSampler* sampler = new MetropolisHastingsSampler(particleGrid, encomp, randGen, m_CurvatureThreshold);

    float alpha = log(m_EndTemperature/m_StartTemperature);
    m_ParticleWeight = 0.01;
    int ppv = 0;
    // main loop
    int neededParts = 3000;
    while (ppv<neededParts)
    {
        if (ppv<1000)
            m_ParticleWeight /= 2;
        else
            m_ParticleWeight = ppv*m_ParticleWeight/neededParts;

        encomp->SetParameters(m_ParticleWeight,m_ParticleWidth,m_ConnectionPotential*m_ParticleLength*m_ParticleLength,m_CurvatureThreshold,m_InexBalance,m_ParticlePotential);
        for( int step = 0; step < 10; step++ )
        {
            // update temperatur for simulated annealing process
            float temperature = m_StartTemperature * exp(alpha*(((1.0)*step)/((1.0)*10)));
            sampler->SetTemperature(temperature);

            for (unsigned long i=0; i<10000; i++)
                sampler->MakeProposal();
        }
        ppv = particleGrid->m_NumParticles;
        particleGrid->ResetGrid();
    }
    delete sampler;
    delete encomp;
    delete particleGrid;
    delete interpolator;

    MITK_INFO << "GibbsTrackingFilter: finished estimating particle weight";
}
예제 #3
0
void GibbsTrackingFilter< ItkQBallImageType >::GenerateData()
{
    TimeProbe preClock; preClock.Start();
    // check if input is qball or tensor image and generate qball if necessary
    if (m_QBallImage.IsNull() && m_TensorImage.IsNotNull())
    {
        TensorImageToQBallImageFilter<float,float>::Pointer filter = TensorImageToQBallImageFilter<float,float>::New();
        filter->SetInput( m_TensorImage );
        filter->Update();
        m_QBallImage = filter->GetOutput();
    }
    else if (m_DuplicateImage) // generate local working copy of QBall image (if not disabled)
    {
        typedef itk::ImageDuplicator< ItkQBallImageType > DuplicateFilterType;
        typename DuplicateFilterType::Pointer duplicator = DuplicateFilterType::New();
        duplicator->SetInputImage( m_QBallImage );
        duplicator->Update();
        m_QBallImage = duplicator->GetOutput();
    }

    // perform mean subtraction on odfs
    typedef ImageRegionIterator< ItkQBallImageType > InputIteratorType;
    InputIteratorType it(m_QBallImage, m_QBallImage->GetLargestPossibleRegion() );
    it.GoToBegin();
    while (!it.IsAtEnd())
    {
        itk::OrientationDistributionFunction<float, QBALL_ODFSIZE> odf(it.Get().GetDataPointer());
        float mean = odf.GetMeanValue();
        odf -= mean;
        it.Set(odf.GetDataPointer());
        ++it;
    }

    // check if mask image is given if it needs resampling
    PrepareMaskImage();

    // load parameter file
    LoadParameters();

    // prepare parameters
    float minSpacing;
    if(m_QBallImage->GetSpacing()[0]<m_QBallImage->GetSpacing()[1] && m_QBallImage->GetSpacing()[0]<m_QBallImage->GetSpacing()[2])
        minSpacing = m_QBallImage->GetSpacing()[0];
    else if (m_QBallImage->GetSpacing()[1] < m_QBallImage->GetSpacing()[2])
        minSpacing = m_QBallImage->GetSpacing()[1];
    else
        minSpacing = m_QBallImage->GetSpacing()[2];

    if(m_ParticleLength == 0)
        m_ParticleLength = 1.5*minSpacing;
    if(m_ParticleWidth == 0)
        m_ParticleWidth = 0.5*minSpacing;

    if(m_ParticleWeight == 0)
        EstimateParticleWeight();

    float alpha = log(m_EndTemperature/m_StartTemperature);
    m_Steps = m_Iterations/10000;
    if (m_Steps<10)
        m_Steps = 10;
    if (m_Steps>m_Iterations)
    {
        MITK_INFO << "GibbsTrackingFilter: not enough iterations!";
        m_AbortTracking = true;
    }
    if (m_CurvatureThreshold < mitk::eps)
        m_CurvatureThreshold = 0;
    unsigned long singleIts = (unsigned long)((1.0*m_Iterations) / (1.0*m_Steps));

    // seed random generators
    Statistics::MersenneTwisterRandomVariateGenerator::Pointer randGen = Statistics::MersenneTwisterRandomVariateGenerator::New();
    if (m_RandomSeed>-1)
        randGen->SetSeed(m_RandomSeed);
    else
        randGen->SetSeed();

    // load sphere interpolator to evaluate the ODFs
    SphereInterpolator* interpolator = new SphereInterpolator(m_LutPath);

    // handle lookup table not found cases
    if( !interpolator->IsInValidState() )
    {
      m_IsInValidState = false;
      m_AbortTracking = true;
      m_BuildFibers = false;
      mitkThrow() << "Unable to load lookup tables.";
    }
    // initialize the actual tracking components (ParticleGrid, Metropolis Hastings Sampler and Energy Computer)
    ParticleGrid* particleGrid;
    GibbsEnergyComputer* encomp;
    MetropolisHastingsSampler* sampler;
    try{
        particleGrid = new ParticleGrid(m_MaskImage, m_ParticleLength, m_ParticleGridCellCapacity);
        encomp = new GibbsEnergyComputer(m_QBallImage, m_MaskImage, particleGrid, interpolator, randGen);
        encomp->SetParameters(m_ParticleWeight,m_ParticleWidth,m_ConnectionPotential*m_ParticleLength*m_ParticleLength,m_CurvatureThreshold,m_InexBalance,m_ParticlePotential);
        sampler = new MetropolisHastingsSampler(particleGrid, encomp, randGen, m_CurvatureThreshold);
    }
    catch(...)
    {
        MITK_ERROR  << "Particle grid allocation failed. Not enough memory? Try to increase the particle length.";
        m_IsInValidState = false;
        m_AbortTracking = true;
        m_BuildFibers = false;
        return;
    }

    MITK_INFO << "----------------------------------------";
    MITK_INFO << "Iterations: " << m_Iterations;
    MITK_INFO << "Steps: " << m_Steps;
    MITK_INFO << "Particle length: " << m_ParticleLength;
    MITK_INFO << "Particle width: " << m_ParticleWidth;
    MITK_INFO << "Particle weight: " << m_ParticleWeight;
    MITK_INFO << "Start temperature: " << m_StartTemperature;
    MITK_INFO << "End temperature: " << m_EndTemperature;
    MITK_INFO << "In/Ex balance: " << m_InexBalance;
    MITK_INFO << "Min. fiber length: " << m_MinFiberLength;
    MITK_INFO << "Curvature threshold: " << m_CurvatureThreshold;
    MITK_INFO << "Random seed: " << m_RandomSeed;
    MITK_INFO << "----------------------------------------";

    // main loop
    preClock.Stop();
    TimeProbe clock; clock.Start();
    m_NumAcceptedFibers = 0;
    unsigned long counter = 1;

    boost::progress_display disp(m_Steps*singleIts);
    if (!m_AbortTracking)
    for( m_CurrentStep = 1; m_CurrentStep <= m_Steps; m_CurrentStep++ )
    {
        // update temperatur for simulated annealing process
        float temperature = m_StartTemperature * exp(alpha*(((1.0)*m_CurrentStep)/((1.0)*m_Steps)));
        sampler->SetTemperature(temperature);

        for (unsigned long i=0; i<singleIts; i++)
        {
            ++disp;
            if (m_AbortTracking)
                break;

            sampler->MakeProposal();

            if (m_BuildFibers || (i==singleIts-1 && m_CurrentStep==m_Steps))
            {
                m_ProposalAcceptance = (float)sampler->GetNumAcceptedProposals()/counter;
                m_NumParticles = particleGrid->m_NumParticles;
                m_NumConnections = particleGrid->m_NumConnections;

                FiberBuilder fiberBuilder(particleGrid, m_MaskImage);
                m_FiberPolyData = fiberBuilder.iterate(m_MinFiberLength);
                m_NumAcceptedFibers = m_FiberPolyData->GetNumberOfLines();
                m_BuildFibers = false;
            }
            counter++;
        }

        m_ProposalAcceptance = (float)sampler->GetNumAcceptedProposals()/counter;
        m_NumParticles = particleGrid->m_NumParticles;
        m_NumConnections = particleGrid->m_NumConnections;

        if (m_AbortTracking)
            break;
    }
    if (m_AbortTracking)
    {
        FiberBuilder fiberBuilder(particleGrid, m_MaskImage);
        m_FiberPolyData = fiberBuilder.iterate(m_MinFiberLength);
        m_NumAcceptedFibers = m_FiberPolyData->GetNumberOfLines();
    }
    clock.Stop();

    delete sampler;
    delete encomp;
    delete interpolator;
    delete particleGrid;
    m_AbortTracking = true;
    m_BuildFibers = false;

    int h = clock.GetTotal()/3600;
    int m = ((int)clock.GetTotal()%3600)/60;
    int s = (int)clock.GetTotal()%60;
    MITK_INFO << "GibbsTrackingFilter: finished gibbs tracking in " << h << "h, " << m << "m and " << s << "s";
    m = (int)preClock.GetTotal()/60;
    s = (int)preClock.GetTotal()%60;
    MITK_INFO << "GibbsTrackingFilter: preparation of the data took " << m << "m and " << s << "s";
    MITK_INFO << "GibbsTrackingFilter: " << m_NumAcceptedFibers << " fibers accepted";

//    sampler->PrintProposalTimes();

    SaveParameters();
}