Beispiel #1
0
void VglPlus::generateBox(const vgl_point_3d<double> & center, const vnl_vector_fixed<double, 3> & xyz_size, vcl_vector<vgl_point_3d<double> > & vertex)
{
    
    int sign[][3] = {-1, -1, -1,
        1, -1, -1,
        1, 1, -1,
        -1, 1, -1,
        -1, -1, 1,
        1, -1, 1,
        1, 1, 1,
        -1, 1, 1};
    double x_s = xyz_size[0];
    double y_s = xyz_size[1];
    double z_s = xyz_size[2];
    for (int i = 0; i<8; i++) {
        double x = center.x() + sign[i][0] * 0.5 * x_s;
        double y = center.y() + sign[i][1] * 0.5 * y_s;
        double z = center.z() + sign[i][2] * 0.5 * z_s;
        vertex.push_back(vgl_point_3d<double>(x, y, z));
    }
    assert(vertex.size() == 8);
}
vnl_vector_fixed<float,3> TrackingHandlerPeaks::GetMatchingDirection(itk::Index<3> idx3, vnl_vector_fixed<float,3>& oldDir)
{
  vnl_vector_fixed<float,3> out_dir; out_dir.fill(0);
  float angle = 0;
  float mag = oldDir.magnitude();
  if (mag<mitk::eps)
  {
    bool found = false;

    if (m_Random)
    {
      // try m_NumDirs times to get a non-zero random direction
      for (int j=0; j<m_NumDirs; j++)
      {
        int i = 0;
#pragma omp critical
        i = m_RngItk->GetIntegerVariate(m_NumDirs-1);
        out_dir = GetDirection(idx3, i);

        if (out_dir.magnitude()>mitk::eps)
        {
          oldDir[0] = out_dir[0];
          oldDir[1] = out_dir[1];
          oldDir[2] = out_dir[2];
          found = true;
          break;
        }
      }
    }

    if (!found)
    {
      // if you didn't find a non-zero random direction, take first non-zero direction you find
      for (int i=0; i<m_NumDirs; i++)
      {
        out_dir = GetDirection(idx3, i);
        if (out_dir.magnitude()>mitk::eps)
        {
          oldDir[0] = out_dir[0];
          oldDir[1] = out_dir[1];
          oldDir[2] = out_dir[2];
          break;
        }
      }
    }
  }
  else
  {
    for (int i=0; i<m_NumDirs; i++)
    {
      vnl_vector_fixed<float,3> dir = GetDirection(idx3, i);
      mag = dir.magnitude();
      if (mag>mitk::eps)
        dir.normalize();
      float a = dot_product(dir, oldDir);
      if (fabs(a)>angle)
      {
        angle = fabs(a);
        if (a<0)
          out_dir = -dir;
        else
          out_dir = dir;
        out_dir *= mag;
        out_dir *= angle; // shrink contribution of direction if is less parallel to previous direction
      }
    }
  }

  return out_dir;
}
static bool CompareVectors(const vnl_vector_fixed< double, 3 >& v1, const vnl_vector_fixed< double, 3 >& v2)
{
  return (v1.magnitude()>v2.magnitude());
}
double MLBSTrackingFilter< NumImageFeatures >::FollowStreamline(ThreadIdType threadId, itk::Point<double, 3> pos, vnl_vector_fixed<double,3> dir, FiberType* fib, double tractLength, bool front)
{
    vnl_vector_fixed<double,3> dirOld = dir;
    dirOld = dir;

    for (int step=0; step< m_MaxLength/2; step++)
    {
        while (m_PauseTracking){}
        if (m_DemoMode)
        {
            m_Mutex.Lock();
            m_BuildFibersReady++;
            m_Tractogram.push_back(*fib);
            BuildFibers(true);
            m_Stop = true;
            m_Mutex.Unlock();
            while (m_Stop){}
        }

        // get new position
        CalculateNewPosition(pos, dir);

        // is new position inside of image and mask
        if (!IsValidPosition(pos) || m_AbortTracking)   // if not end streamline
        {
            return tractLength;
        }
        else    // if yes, add new point to streamline
        {
            tractLength +=  m_StepSize;
            if (front)
                fib->push_front(pos);
            else
                fib->push_back(pos);

            if (m_AposterioriCurvCheck)
            {
                int curv = CheckCurvature(fib, front);  // TODO: Move into classification ???
                if (curv>0)
                {
                    tractLength -= m_StepSize*curv;
                    while (curv>0)
                    {
                        if (front)
                            fib->pop_front();
                        else
                            fib->pop_back();
                        curv--;
                    }
                    return tractLength;
                }
            }

            if (tractLength>m_MaxTractLength)
                return tractLength;
        }

        dir = GetNewDirection(pos, dirOld);

        if (dir.magnitude()<0.0001)
            return tractLength;
    }
    return tractLength;
}
vnl_vector_fixed<double,3> MLBSTrackingFilter< NumImageFeatures >::GetNewDirection(itk::Point<double, 3> &pos, vnl_vector_fixed<double, 3>& olddir)
{
    vnl_vector_fixed<double,3> direction; direction.fill(0);

    ItkUcharImgType::IndexType idx;
    m_StoppingRegions->TransformPhysicalPointToIndex(pos, idx);
    if (m_StoppingRegions->GetPixel(idx)>0)
        return direction;

    if (olddir.magnitude()>0)
        olddir.normalize();

    int candidates = 0; // number of directions with probability > 0
    double prob = 0;
    direction = Classify(pos, candidates, olddir, m_AngularThreshold, prob); // sample neighborhood
    direction *= prob;


    itk::OrientationDistributionFunction< double, 50 >  probeVecs;

    for (int i=0; i<m_NumberOfSamples; i++)
    {
        vnl_vector_fixed<double,3> d;
//        probe[0] = GetRandDouble()*m_SamplingDistance;
//        probe[1] = GetRandDouble()*m_SamplingDistance;
//        probe[2] = GetRandDouble()*m_SamplingDistance;

        d = probeVecs.GetDirection(i)*m_SamplingDistance;

        itk::Point<double, 3> sample_pos;
        sample_pos[0] = pos[0] + d[0];
        sample_pos[1] = pos[1] + d[1];
        sample_pos[2] = pos[2] + d[2];

        candidates = 0;
        vnl_vector_fixed<double,3> tempDir = Classify(sample_pos, candidates, olddir, m_AngularThreshold, prob); // sample neighborhood
        if (candidates>0 && tempDir.magnitude()>0.001)
        {
            direction += tempDir*prob;
        }
        else if (m_AvoidStop && candidates==0 && olddir.magnitude()>0) // out of white matter
        {
            double dot = dot_product(d, olddir);
            if (dot >= 0.0) // in front of plane defined by pos and olddir
                d = -d + 2*dot*olddir; // reflect
            else
                d = -d; // invert

            // look a bit further into the other direction
            sample_pos[0] = pos[0] + d[0]*2;
            sample_pos[1] = pos[1] + d[1]*2;
            sample_pos[2] = pos[2] + d[2]*2;
            candidates = 0;
            vnl_vector_fixed<double,3> tempDir = Classify(sample_pos, candidates, olddir, m_AngularThreshold, prob, true); // sample neighborhood

            if (candidates>0 && tempDir.magnitude()>0.001)  // are we back in the white matter?
            {
                direction += d;         // go into the direction of the white matter
                direction += tempDir*prob;  // go into the direction of the white matter direction at this location
            }
        }
    }

    if (direction.magnitude()>0.001)
    {
        direction.normalize();
        olddir[0] = direction[0];
        olddir[1] = direction[1];
        olddir[2] = direction[2];
    }
    else
        direction.fill(0);

    return direction;
}
vnl_vector_fixed<double,3> MLBSTrackingFilter< NumImageFeatures >::Classify(itk::Point<double, 3>& pos, int& candidates, vnl_vector_fixed<double,3>& olddir, double angularThreshold, double& prob, bool avoidStop)
{
    vnl_vector_fixed<double,3> direction; direction.fill(0);

    vigra::MultiArray<2, double> featureData;
    if(m_UseDirection)
        featureData = vigra::MultiArray<2, double>( vigra::Shape2(1,NumImageFeatures+3) );
    else
        featureData = vigra::MultiArray<2, double>( vigra::Shape2(1,NumImageFeatures) );

    typename FeatureImageType::PixelType featurePixel = GetImageValues(pos);

    // pixel values
    for (unsigned int f=0; f<NumImageFeatures; f++)
        featureData(0,f) = featurePixel[f];

    // direction features
    int c = 0;
    if (m_UseDirection)
    {
        vnl_vector_fixed<double,3> ref; ref.fill(0); ref[0]=1;
        for (unsigned int f=NumImageFeatures; f<NumImageFeatures+3; f++)
        {
            if (dot_product(ref, olddir)<0)
                featureData(0,f) = -olddir[c];
            else
                featureData(0,f) = olddir[c];
            c++;
        }
    }

    vigra::MultiArray<2, double> probs(vigra::Shape2(1, m_DecisionForest->class_count()));
    m_DecisionForest->predictProbabilities(featureData, probs);

    double outProb = 0;
    prob = 0;
    candidates = 0; // directions with probability > 0
    for (int i=0; i<m_DecisionForest->class_count(); i++)
    {
        if (probs(0,i)>0)
        {
            int classLabel = 0;
            m_DecisionForest->ext_param_.to_classlabel(i, classLabel);

            if (classLabel<m_DirectionIndices.size())
            {
                candidates++;

                vnl_vector_fixed<double,3> d = m_ODF.GetDirection(m_DirectionIndices.at(classLabel));
                double dot = dot_product(d, olddir);

                if (olddir.magnitude()>0)
                {
                    if (fabs(dot)>angularThreshold)
                    {
                        if (dot<0)
                            d *= -1;
                        dot = fabs(dot);
                        direction += probs(0,i)*dot*d;
                        prob += probs(0,i)*dot;
                    }
                }
                else
                {
                    direction += probs(0,i)*d;
                    prob += probs(0,i);
                }
            }
            else
                outProb += probs(0,i);
        }
    }

    ItkDoubleImgType::IndexType idx;
    m_NotWmImage->TransformPhysicalPointToIndex(pos, idx);
    if (m_NotWmImage->GetLargestPossibleRegion().IsInside(idx))
    {
        m_NotWmImage->SetPixel(idx, m_NotWmImage->GetPixel(idx)+outProb);
        m_WmImage->SetPixel(idx, m_WmImage->GetPixel(idx)+prob);
    }
    if (outProb>prob && prob>0)
    {
        candidates = 0;
        prob = 0;
        direction.fill(0.0);
    }
    if (avoidStop && m_AvoidStopImage->GetLargestPossibleRegion().IsInside(idx) && candidates>0 && direction.magnitude()>0.001)
        m_AvoidStopImage->SetPixel(idx, m_AvoidStopImage->GetPixel(idx)+0.1);

    return direction;
}
vnl_vector_fixed<double,3> MLBSTrackingFilter<  ShOrder, NumImageFeatures >::GetNewDirection(itk::Point<double, 3> &pos, vnl_vector_fixed<double, 3>& olddir)
{
    if (m_DemoMode)
    {
        m_SamplingPointset->Clear();
        m_AlternativePointset->Clear();
    }
    vnl_vector_fixed<double,3> direction; direction.fill(0);

    ItkUcharImgType::IndexType idx;
    m_StoppingRegions->TransformPhysicalPointToIndex(pos, idx);
    if (m_StoppingRegions->GetLargestPossibleRegion().IsInside(idx) && m_StoppingRegions->GetPixel(idx)>0)
        return direction;

    if (m_MaskImage.IsNotNull() && ((m_MaskImage->GetLargestPossibleRegion().IsInside(idx) && m_MaskImage->GetPixel(idx)<=0) || !m_MaskImage->GetLargestPossibleRegion().IsInside(idx)) )
        return direction;

    if (olddir.magnitude()>0)
        olddir.normalize();

    int candidates = 0; // number of directions with probability > 0
    double w = 0;       // weight of the direction predicted at each sampling point
    if (IsValidPosition(pos))
    {
        direction = m_ForestHandler.Classify(pos, candidates, olddir, m_AngularThreshold, w, m_MaskImage); // get direction proposal at current streamline position
        direction *= w;  // HERE WE ARE WEIGHTING AGAIN EVEN THOUGH THE OUTPUT DIRECTIONS ARE ALREADY WEIGHTED!!! THE EFFECT OF THIS HAS YET TO BE EVALUATED.
    }

    itk::OrientationDistributionFunction< double, 50 >  probeVecs;
    itk::Point<double, 3> sample_pos;
    int alternatives = 1;
    for (int i=0; i<m_NumberOfSamples; i++)
    {
        vnl_vector_fixed<double,3> d;

        if (m_RandomSampling)
        {
            d[0] = GetRandDouble();
            d[1] = GetRandDouble();
            d[2] = GetRandDouble();
            d.normalize();
            d *= GetRandDouble(0,m_SamplingDistance);
        }
        else
        {
            d = probeVecs.GetDirection(i)*m_SamplingDistance;
        }

        sample_pos[0] = pos[0] + d[0];
        sample_pos[1] = pos[1] + d[1];
        sample_pos[2] = pos[2] + d[2];
        if(m_DemoMode)
            m_SamplingPointset->InsertPoint(i, sample_pos);

        candidates = 0;
        vnl_vector_fixed<double,3> tempDir; tempDir.fill(0.0);
        if (IsValidPosition(sample_pos))
            tempDir = m_ForestHandler.Classify(sample_pos, candidates, olddir, m_AngularThreshold, w, m_MaskImage); // sample neighborhood
        if (candidates>0 && tempDir.magnitude()>0.001)
        {
            direction += tempDir*w;
        }
        else if (m_AvoidStop && candidates==0 && olddir.magnitude()>0) // out of white matter
        {
            double dot = dot_product(d, olddir);
            if (dot >= 0.0) // in front of plane defined by pos and olddir
                d = -d + 2*dot*olddir; // reflect
            else
                d = -d; // invert

            // look a bit further into the other direction
            sample_pos[0] = pos[0] + d[0];
            sample_pos[1] = pos[1] + d[1];
            sample_pos[2] = pos[2] + d[2];
            if(m_DemoMode)
                m_AlternativePointset->InsertPoint(alternatives, sample_pos);
            alternatives++;
            candidates = 0;
            vnl_vector_fixed<double,3> tempDir; tempDir.fill(0.0);
            if (IsValidPosition(sample_pos))
                tempDir = m_ForestHandler.Classify(sample_pos, candidates, olddir, m_AngularThreshold, w, m_MaskImage); // sample neighborhood

            if (candidates>0 && tempDir.magnitude()>0.001)  // are we back in the white matter?
            {
                direction += d;         // go into the direction of the white matter
                direction += tempDir*w;  // go into the direction of the white matter direction at this location
            }
        }
    }

    if (direction.magnitude()>0.001)
    {
        direction.normalize();
        olddir[0] = direction[0];
        olddir[1] = direction[1];
        olddir[2] = direction[2];
    }
    else
        direction.fill(0);

    return direction;
}