Public Types | Public Member Functions | Static Public Member Functions

itk::OrientationDistributionFunction< TComponent, NOdfDirections > Class Template Reference

Represents an ODF for Q-Ball imaging. More...

#include <itkOrientationDistributionFunction.h>

List of all members.

Public Types

enum  InterpolationMethods { ODF_NEAREST_NEIGHBOR_INTERP, ODF_TRILINEAR_BARYCENTRIC_INTERP, ODF_SPHERICAL_GAUSSIAN_BASIS_FUNCTIONS }
typedef
OrientationDistributionFunction 
Self
typedef FixedArray< TComponent,
NOdfDirections > 
Superclass
typedef FixedArray< TComponent,
itkGetStaticConstMacro(InternalDimension)> 
BaseArray
typedef TComponent ComponentType
typedef Superclass::ValueType ValueType
typedef NumericTraits
< ValueType >::RealType 
AccumulateValueType
typedef NumericTraits
< ValueType >::RealType 
RealValueType
typedef Matrix< TComponent,
NOdfDirections, NOdfDirections > 
MatrixType
typedef vnl_matrix_fixed
< double, 3, NOdfDirections > 
DirectionsType
typedef ComponentType ComponentArrayType [itkGetStaticConstMacro(InternalDimension)]

Public Member Functions

 itkStaticConstMacro (InternalDimension, unsigned int, NOdfDirections)
 OrientationDistributionFunction ()
 OrientationDistributionFunction (const ComponentType &r)
 OrientationDistributionFunction (const Self &r)
 OrientationDistributionFunction (const ComponentArrayType r)
Selfoperator= (const Self &r)
Selfoperator= (const ComponentType &r)
Selfoperator= (const ComponentArrayType r)
Self operator+ (const Self &vec) const
Self operator- (const Self &vec) const
const Selfoperator+= (const Self &vec)
const Selfoperator-= (const Self &vec)
Self operator* (const RealValueType &scalar) const
Self operator/ (const RealValueType &scalar) const
const Selfoperator*= (const RealValueType &scalar)
const Selfoperator/= (const RealValueType &scalar)
ComponentType GetNthComponent (int c) const
ComponentType GetInterpolatedComponent (vnl_vector_fixed< double, 3 > dir, InterpolationMethods method) const
void SetNthComponent (int c, const ComponentType &v)
ValueTypeoperator() (unsigned int row, unsigned int col)
const ValueTypeoperator() (unsigned int row, unsigned int col) const
void SetIsotropic ()
void InitFromTensor (itk::DiffusionTensor3D< TComponent > tensor)
Self PreMultiply (const MatrixType &m) const
Self PostMultiply (const MatrixType &m) const
void Normalize ()
Self MinMaxNormalize () const
Self MaxNormalize () const
int GetPrincipleDiffusionDirection () const
int GetNthDiffusionDirection (int n, vnl_vector_fixed< double, 3 > rndVec) const
TComponent GetGeneralizedFractionalAnisotropy () const
TComponent GetGeneralizedGFA (int k, int p) const
TComponent GetNormalizedEntropy () const
TComponent GetNematicOrderParameter () const
TComponent GetStdDevByMaxValue () const
TComponent GetPrincipleCurvature (double alphaMinDegree, double alphaMaxDegree, int invert) const

Static Public Member Functions

static DirectionsTypeGetDirections ()
static unsigned int GetNumberOfComponents ()
static std::vector< int > GetNeighbors (int idx)
static vtkPolyData * GetBaseMesh ()
static void ComputeBaseMesh ()
static double GetMaxChordLength ()
static vnl_vector_fixed
< double, 3 > 
GetDirection (int i)

Detailed Description

template<typename TComponent, unsigned int NOdfDirections>
class itk::OrientationDistributionFunction< TComponent, NOdfDirections >

Represents an ODF for Q-Ball imaging.

Reference: David S. Tuch, Q-ball imaging, Magnetic Resonance in Medicine Volume 52 Issue 6, Pages 1358 - 1372

Author:
Klaus Fritzsche, MBI

Definition at line 56 of file itkOrientationDistributionFunction.h.


Member Typedef Documentation

template<typename TComponent, unsigned int NOdfDirections>
typedef NumericTraits<ValueType>::RealType itk::OrientationDistributionFunction< TComponent, NOdfDirections >::AccumulateValueType

Definition at line 81 of file itkOrientationDistributionFunction.h.

template<typename TComponent, unsigned int NOdfDirections>
typedef FixedArray<TComponent, itkGetStaticConstMacro(InternalDimension)> itk::OrientationDistributionFunction< TComponent, NOdfDirections >::BaseArray

Convenience typedefs.

Definition at line 76 of file itkOrientationDistributionFunction.h.

template<typename TComponent, unsigned int NOdfDirections>
typedef ComponentType itk::OrientationDistributionFunction< TComponent, NOdfDirections >::ComponentArrayType[itkGetStaticConstMacro(InternalDimension)]

Definition at line 93 of file itkOrientationDistributionFunction.h.

template<typename TComponent, unsigned int NOdfDirections>
typedef TComponent itk::OrientationDistributionFunction< TComponent, NOdfDirections >::ComponentType

Define the component type.

Definition at line 79 of file itkOrientationDistributionFunction.h.

template<typename TComponent, unsigned int NOdfDirections>
typedef vnl_matrix_fixed<double, 3, NOdfDirections> itk::OrientationDistributionFunction< TComponent, NOdfDirections >::DirectionsType

Definition at line 86 of file itkOrientationDistributionFunction.h.

template<typename TComponent, unsigned int NOdfDirections>
typedef Matrix<TComponent, NOdfDirections, NOdfDirections> itk::OrientationDistributionFunction< TComponent, NOdfDirections >::MatrixType

Definition at line 84 of file itkOrientationDistributionFunction.h.

template<typename TComponent, unsigned int NOdfDirections>
typedef NumericTraits<ValueType>::RealType itk::OrientationDistributionFunction< TComponent, NOdfDirections >::RealValueType

Definition at line 82 of file itkOrientationDistributionFunction.h.

template<typename TComponent, unsigned int NOdfDirections>
typedef OrientationDistributionFunction itk::OrientationDistributionFunction< TComponent, NOdfDirections >::Self

Standard class typedefs.

Definition at line 68 of file itkOrientationDistributionFunction.h.

template<typename TComponent, unsigned int NOdfDirections>
typedef FixedArray<TComponent,NOdfDirections> itk::OrientationDistributionFunction< TComponent, NOdfDirections >::Superclass

Definition at line 69 of file itkOrientationDistributionFunction.h.

template<typename TComponent, unsigned int NOdfDirections>
typedef Superclass::ValueType itk::OrientationDistributionFunction< TComponent, NOdfDirections >::ValueType

Definition at line 80 of file itkOrientationDistributionFunction.h.


Member Enumeration Documentation

template<typename TComponent, unsigned int NOdfDirections>
enum itk::OrientationDistributionFunction::InterpolationMethods
Enumerator:
ODF_NEAREST_NEIGHBOR_INTERP 
ODF_TRILINEAR_BARYCENTRIC_INTERP 
ODF_SPHERICAL_GAUSSIAN_BASIS_FUNCTIONS 

Definition at line 61 of file itkOrientationDistributionFunction.h.


Constructor & Destructor Documentation

template<typename TComponent, unsigned int NOdfDirections>
itk::OrientationDistributionFunction< TComponent, NOdfDirections >::OrientationDistributionFunction (  ) [inline]

Default constructor has nothing to do.

Definition at line 89 of file itkOrientationDistributionFunction.h.

{this->Fill(0);}
template<typename TComponent, unsigned int NOdfDirections>
itk::OrientationDistributionFunction< TComponent, NOdfDirections >::OrientationDistributionFunction ( const ComponentType r ) [inline]

Definition at line 91 of file itkOrientationDistributionFunction.h.

{ this->Fill(r); }
template<typename TComponent, unsigned int NOdfDirections>
itk::OrientationDistributionFunction< TComponent, NOdfDirections >::OrientationDistributionFunction ( const Self r ) [inline]

Pass-through constructor for the Array base class.

Definition at line 96 of file itkOrientationDistributionFunction.h.

: BaseArray(r) {}
template<typename TComponent, unsigned int NOdfDirections>
itk::OrientationDistributionFunction< TComponent, NOdfDirections >::OrientationDistributionFunction ( const ComponentArrayType  r ) [inline]

Definition at line 97 of file itkOrientationDistributionFunction.h.

: BaseArray(r) {}    

Member Function Documentation

template<class T , unsigned int NOdfDirections>
void itk::OrientationDistributionFunction< T, NOdfDirections >::ComputeBaseMesh (  ) [static]

Definition at line 473 of file itkOrientationDistributionFunction.txx.

References QuadProgPP::abs(), ODF_PI, and QuadProgPP::sqrt().

Referenced by itk::OrientationDistributionFunction< TComponent, NOdfDirections >::GetBaseMesh().

  {

    m_MutexBaseMesh.Lock();
    if(m_BaseMesh == NULL)
    {

      vtkPoints* points = vtkPoints::New();
      for(unsigned int j=0; j<NOdfDirections; j++){
        double x = (*m_Directions)(0,j);
        double y = (*m_Directions)(1,j);
        double z = (*m_Directions)(2,j);
        double az = atan2(y,x);
        double elev = atan2(z,sqrt(x*x+y*y));
        double r = sqrt(x*x+y*y+z*z);
        points->InsertNextPoint(az,elev,r);
      }

      vtkPolyData* polydata = vtkPolyData::New();
      polydata->SetPoints( points );
      vtkDelaunay2D *delaunay = vtkDelaunay2D::New();
      delaunay->SetInput( polydata );
      delaunay->Update();

      vtkCellArray* vtkpolys = delaunay->GetOutput()->GetPolys();
      vtkCellArray* vtknewpolys = vtkCellArray::New();
      vtkIdType npts; vtkIdType *pts;
      while(vtkpolys->GetNextCell(npts,pts))
      {
        bool insert = true;
        for(int i=0; i<npts; i++)
        {
          double *tmpPoint = points->GetPoint(pts[i]);
          double az = tmpPoint[0];
          double elev = tmpPoint[1];
          if((abs(az)>ODF_PI-0.5) || (abs(elev)>ODF_PI/2-0.5)) 
            insert = false;
        }
        if(insert)
          vtknewpolys->InsertNextCell(npts, pts);
      }

      vtkPoints* points2 = vtkPoints::New();
      for(unsigned int j=0; j<NOdfDirections; j++){
        double x = -(*m_Directions)(0,j);
        double y = -(*m_Directions)(2,j);
        double z = -(*m_Directions)(1,j);
        double az = atan2(y,x);
        double elev = atan2(z,sqrt(x*x+y*y));
        double r = sqrt(x*x+y*y+z*z);
        points2->InsertNextPoint(az,elev,r);
      }

      vtkPolyData* polydata2 = vtkPolyData::New();
      polydata2->SetPoints( points2 );
      vtkDelaunay2D *delaunay2 = vtkDelaunay2D::New();
      delaunay2->SetInput( polydata2 );
      delaunay2->Update();

      vtkpolys = delaunay2->GetOutput()->GetPolys();
      while(vtkpolys->GetNextCell(npts,pts))
      {
        bool insert = true;
        for(int i=0; i<npts; i++)
        {
          double *tmpPoint = points2->GetPoint(pts[i]);
          double az = tmpPoint[0];
          double elev = tmpPoint[1];
          if((abs(az)>ODF_PI-0.5) || (abs(elev)>ODF_PI/2-0.5)) 
            insert = false;
        }
        if(insert)
          vtknewpolys->InsertNextCell(npts, pts);
      }

      polydata->SetPolys(vtknewpolys);

      for (vtkIdType p = 0; p < NOdfDirections; p++)
      {
        points->SetPoint(p,m_Directions->get_column(p).data_block());
      }
      polydata->SetPoints( points );

      //vtkCleanPolyData* cleaner = vtkCleanPolyData::New();
      //cleaner->SetInput( polydata );
      //cleaner->SetAbsoluteTolerance( 0.0 );
      //cleaner->Update();

      //vtkAppendPolyData* append = vtkAppendPolyData::New();
      //append->AddInput(cleaner->GetOutput());
      //append->Update();
      //m_BaseMesh = append->GetOutput();

      m_BaseMesh = polydata;
    }
    m_MutexBaseMesh.Unlock();
  }
template<typename TComponent, unsigned int NOdfDirections>
static vtkPolyData* itk::OrientationDistributionFunction< TComponent, NOdfDirections >::GetBaseMesh (  ) [inline, static]
template<typename TComponent , unsigned int NOdfDirections>
vnl_vector_fixed< double, 3 > itk::OrientationDistributionFunction< TComponent, NOdfDirections >::GetDirection ( int  i ) [static]

Definition at line 721 of file itkOrientationDistributionFunction.txx.

  {
    return m_Directions->get_column(i);
  }
template<typename TComponent, unsigned int NOdfDirections>
static DirectionsType* itk::OrientationDistributionFunction< TComponent, NOdfDirections >::GetDirections (  ) [inline, static]

Return the number of components.

Definition at line 117 of file itkOrientationDistributionFunction.h.

  { 
    return itkGetStaticConstMacro(m_Directions);
  }
template<class T , unsigned int NOdfDirections>
T itk::OrientationDistributionFunction< T, NOdfDirections >::GetGeneralizedFractionalAnisotropy (  ) const

Definition at line 873 of file itkOrientationDistributionFunction.txx.

References QuadProgPP::mean(), and QuadProgPP::sqrt().

  {
    double mean = 0;
    double std = 0;
    double rms = 0;
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      T val = (*this)[i];
      mean += val;
    }
    mean /= NOdfDirections;
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      T val = (*this)[i];
      std += (val - mean) * (val - mean);
      rms += val*val;
    }
    std *= NOdfDirections;
    rms *= NOdfDirections - 1;

    if(rms == 0)
    {
      return 0;
    }
    else
    {
      return sqrt(std/rms);
    }
  }
template<typename T , unsigned int N>
T itk::OrientationDistributionFunction< T, N >::GetGeneralizedGFA ( int  k,
int  p 
) const

Definition at line 906 of file itkOrientationDistributionFunction.txx.

References QuadProgPP::max(), QuadProgPP::mean(), QuadProgPP::pow(), and QuadProgPP::sqrt().

  {
    double mean = 0;
    double std = 0;
    double rms = 0;
    double max = NumericTraits<double>::NonpositiveMin();
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      double val = (double)(*this)[i];
      mean += pow(val,(double)p);
      max = val > max ? val : max;
    }
    max = pow(max,(double)p);
    mean /= N;
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      double val = (double)(*this)[i];
      std += (pow(val,(double)p) - mean) * (pow(val,(double)p) - mean);
      if(k>0)
      {
        rms += pow(val,(double)(p*k));
      }
    }
    std /= N - 1;
    std = sqrt(std);

    if(k>0)
    {
      rms /= N;
      rms = pow(rms,(double)(1.0/k));
    }
    else if(k<0) // lim k->inf gives us the maximum
    {
      rms = max;
    }
    else // k==0 undefined, we define zeros root from 1 as 1
    {
      rms = 1;
    }

    if(rms == 0)
    {
      return 0;
    }
    else
    {
      return (T)(std/rms);
    }
  }
template<class T , unsigned int NOdfDirections>
T itk::OrientationDistributionFunction< T, NOdfDirections >::GetInterpolatedComponent ( vnl_vector_fixed< double, 3 >  dir,
InterpolationMethods  method 
) const

Return the value for the Nth component.

Definition at line 732 of file itkOrientationDistributionFunction.txx.

References QuadProgPP::dist(), QuadProgPP::exp(), QuadProgPP::max(), ODF_PI, QuadProgPP::sqrt(), and QuadProgPP::sum().

  {

    ComputeBaseMesh();
    double retval = -1.0;

    switch(method)
    {
    case ODF_NEAREST_NEIGHBOR_INTERP:
      {

        vtkPoints* points = m_BaseMesh->GetPoints();
        double current_min = NumericTraits<double>::max();
        int current_min_idx = -1;
        for(int i=0; i<NOdfDirections; i++)
        {
          vnl_vector_fixed<double,3> P(points->GetPoint(i));
          double dist = (dir-P).two_norm();
          current_min_idx = dist<current_min ? i : current_min_idx;
          current_min = dist<current_min ? dist : current_min;
        }
        retval = this->GetNthComponent(current_min_idx);
        break;

      }
    case ODF_TRILINEAR_BARYCENTRIC_INTERP:
      {

        double maxChordLength = GetMaxChordLength();
        vtkCellArray* polys = m_BaseMesh->GetPolys();
        vtkPoints* points = m_BaseMesh->GetPoints();
        vtkIdType npts; vtkIdType *pts;
        double current_min = NumericTraits<double>::max();
        polys->InitTraversal();
        while(polys->GetNextCell(npts,pts))
        {
          vnl_vector_fixed<double,3> A(points->GetPoint(pts[0]));
          vnl_vector_fixed<double,3> B(points->GetPoint(pts[1]));
          vnl_vector_fixed<double,3> C(points->GetPoint(pts[2]));

          vnl_vector_fixed<double,3> d1;
          d1.put(0,(dir-A).two_norm());
          d1.put(1,(dir-B).two_norm());
          d1.put(2,(dir-C).two_norm());
          double maxval = d1.max_value();
          if(maxval>maxChordLength)
          {
            continue;
          }

          // Compute vectors
          vnl_vector_fixed<double,3> v0 = C - A;
          vnl_vector_fixed<double,3> v1 = B - A;

          // Project direction to plane ABC
          vnl_vector_fixed<double,3> v6 = dir;
          vnl_vector_fixed<double,3> cross = vnl_cross_3d(v0, v1);
          cross = cross.normalize();
          vtkPlane::ProjectPoint(v6.data_block(),A.data_block(),cross.data_block(),v6.data_block());
          v6 = v6-A;

          // Calculate barycentric coords
          vnl_matrix_fixed<double,3,2> mat;
          mat.set_column(0, v0);
          mat.set_column(1, v1);
          vnl_matrix_inverse<double> inv(mat);
          vnl_matrix_fixed<double,2,3> inver = inv.pinverse();
          vnl_vector<double> uv = inv.pinverse()*v6;

          // Check if point is in triangle
          double eps = 0.01;
          if( (uv(0) >= 0-eps) && (uv(1) >= 0-eps) && (uv(0) + uv(1) <= 1+eps) )
          {
            // check if minimum angle is the max so far
            if(d1.two_norm() < current_min)
            {
              current_min = d1.two_norm();
              vnl_vector<double> barycentricCoords(3);
              barycentricCoords[2] = uv[0]<0 ? 0 : (uv[0]>1?1:uv[0]);
              barycentricCoords[1] = uv[1]<0 ? 0 : (uv[1]>1?1:uv[1]);
              barycentricCoords[0] = 1-(barycentricCoords[1]+barycentricCoords[2]);
              retval =  barycentricCoords[0]*this->GetNthComponent(pts[0]) + 
                barycentricCoords[1]*this->GetNthComponent(pts[1]) + 
                barycentricCoords[2]*this->GetNthComponent(pts[2]);
            }
          }
        }

        break;
      }
    case ODF_SPHERICAL_GAUSSIAN_BASIS_FUNCTIONS:
      {
        double maxChordLength = GetMaxChordLength();
        double sigma = asin(maxChordLength/2);

        // this is the contribution of each kernel to each sampling point on the
        // equator
        vnl_vector<double> contrib;
        contrib.set_size(NOdfDirections);

        vtkPoints* points = m_BaseMesh->GetPoints();
        double sum = 0;
        for(int i=0; i<NOdfDirections; i++)
        {
          vnl_vector_fixed<double,3> P(points->GetPoint(i));
          double stv =  dir[0]*P[0]
          + dir[1]*P[1]
          + dir[2]*P[2];
          stv = (stv<-1.0) ? -1.0 : ( (stv>1.0) ? 1.0 : stv);
          double x = acos(stv);
          contrib[i] = (1.0/(sigma*sqrt(2.0*ODF_PI)))
            *exp((-x*x)/(2*sigma*sigma));
          sum += contrib[i];
        }

        retval = 0;
        for(int i=0; i<NOdfDirections; i++)
        {
          retval += (contrib[i] / sum)*this->GetNthComponent(i);
        }
        break;
      }

    }

    if(retval==-1)
    {
      std::cout << "Interpolation failed" << std::endl;
      return 0;
    }

    return retval;

  }
template<class T , unsigned int NOdfDirections>
double itk::OrientationDistributionFunction< T, NOdfDirections >::GetMaxChordLength (  ) [static]

Definition at line 442 of file itkOrientationDistributionFunction.txx.

References QuadProgPP::sqrt().

  {
    if(m_MaxChordLength<0.0)
    {
      ComputeBaseMesh();
      double max_dist = -1;
      vtkPoints* points = m_BaseMesh->GetPoints();
      for(int i=0; i<NOdfDirections; i++)
      {
        double p[3];
        points->GetPoint(i,p);
        std::vector<int> neighbors = GetNeighbors(i);
        for(int j=0; j<neighbors.size(); j++)
        {
          double n[3];
          points->GetPoint(neighbors[j],n);
          double d = sqrt(
            (p[0]-n[0])*(p[0]-n[0]) +
            (p[1]-n[1])*(p[1]-n[1]) +
            (p[2]-n[2])*(p[2]-n[2]));
          max_dist = d>max_dist ? d : max_dist;
        }
      }
      m_MaxChordLength = max_dist;
    }
    return m_MaxChordLength;
  }
template<class T , unsigned int NOdfDirections>
std::vector< int > itk::OrientationDistributionFunction< T, NOdfDirections >::GetNeighbors ( int  idx ) [static]

Definition at line 597 of file itkOrientationDistributionFunction.txx.

References QuadProgPP::sort().

  {
    ComputeBaseMesh();

    m_MutexNeighbors.Lock();
    if(m_NeighborIdxs == NULL)
    {
      m_NeighborIdxs = new std::vector< std::vector<int>* >();
      vtkCellArray* polys = m_BaseMesh->GetPolys();

      for(unsigned int i=0; i<NOdfDirections; i++)
      {
        std::vector<int> *idxs = new std::vector<int>();
        polys->InitTraversal();
        vtkIdType npts; vtkIdType *pts;
        while(polys->GetNextCell(npts,pts))
        {
          if( pts[0] == i )
          {
            idxs->push_back(pts[1]);
            idxs->push_back(pts[2]);
          }
          else if( pts[1] == i )
          {
            idxs->push_back(pts[0]);
            idxs->push_back(pts[2]);
          }
          else if( pts[2] == i )
          {
            idxs->push_back(pts[0]);
            idxs->push_back(pts[1]);
          }
        }
        std::sort(idxs->begin(), idxs->end());
        std::vector< int >::iterator endLocation;
        endLocation = std::unique( idxs->begin(), idxs->end() );
        idxs->erase(endLocation, idxs->end());
        m_NeighborIdxs->push_back(idxs);
      }
    }
    m_MutexNeighbors.Unlock();

    return *m_NeighborIdxs->at(idx);
  }
template<typename T , unsigned int N>
T itk::OrientationDistributionFunction< T, N >::GetNematicOrderParameter (  ) const

Definition at line 961 of file itkOrientationDistributionFunction.txx.

  {
    // not yet implemented
    return 0;
  }
template<typename T , unsigned int N>
T itk::OrientationDistributionFunction< T, N >::GetNormalizedEntropy (  ) const

Definition at line 1107 of file itkOrientationDistributionFunction.txx.

References QuadProgPP::log(), and QuadProgPP::mean().

  {
    double mean = 0;
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      T val = (*this)[i];
      if( val != 0 )
      {
        val = log(val);
      }
      else
      {
        val = log(0.0000001);
      }
      mean += val;
    }
    double _n = (double) InternalDimension;
    mean /= _n;
    return (T) (-_n / log(_n) * mean);
  }
template<typename TComponent, unsigned int NOdfDirections>
ComponentType itk::OrientationDistributionFunction< TComponent, NOdfDirections >::GetNthComponent ( int  c ) const [inline]

Return the value for the Nth component.

Definition at line 129 of file itkOrientationDistributionFunction.h.

  { return this->operator[](c); }
template<class T , unsigned int NOdfDirections>
int itk::OrientationDistributionFunction< T, NOdfDirections >::GetNthDiffusionDirection ( int  n,
vnl_vector_fixed< double, 3 >  rndVec 
) const

Definition at line 648 of file itkOrientationDistributionFunction.txx.

References QuadProgPP::max().

  {

    if( n == 0 )
      return GetPrincipleDiffusionDirection();

    m_MutexHalfSphereIdxs.Lock();
    if( !m_HalfSphereIdxs )
    {
      m_HalfSphereIdxs = new std::vector<int>();
      for( unsigned int i=0; i<InternalDimension; i++) 
      {
        if(dot_product(m_Directions->get_column(i),rndVec) > 0.0)
        {
          m_HalfSphereIdxs->push_back(i);
        }
      }
    }
    m_MutexHalfSphereIdxs.Unlock();

    // collect indices of directions
    // that are local maxima
    std::vector<int> localMaxima;
    std::vector<int>::iterator it;
    for( it=m_HalfSphereIdxs->begin(); 
      it!=m_HalfSphereIdxs->end(); 
      it++) 
    {
      std::vector<int> nbs = GetNeighbors(*it);
      std::vector<int>::iterator it2;
      bool max = true;
      for(it2 = nbs.begin(); 
        it2 != nbs.end();
        it2++)
      {
        if((*this)[*it2] > (*this)[*it])
        {
          max = false;
          break;
        }
      }
      if(max)
        localMaxima.push_back(*it);
    }

    // delete n highest local maxima from list
    // and return remaining highest
    int maxidx = -1;
    std::vector<int>::iterator itMax;
    for( int i=0; i<=n; i++ )
    {
      maxidx = -1;
      T max = NumericTraits<T>::NonpositiveMin();
      for(it = localMaxima.begin(); 
        it != localMaxima.end();
        it++)
      {
        if((*this)[*it]>max)
        {
          max = (*this)[*it];
          maxidx = *it;
        }
      }
      it = find(localMaxima.begin(), localMaxima.end(), maxidx);
      if(it!=localMaxima.end())
        localMaxima.erase(it);
    }

    return maxidx;
  }
template<typename TComponent, unsigned int NOdfDirections>
static unsigned int itk::OrientationDistributionFunction< TComponent, NOdfDirections >::GetNumberOfComponents (  ) [inline, static]

Return the number of components.

Definition at line 123 of file itkOrientationDistributionFunction.h.

Referenced by itk::operator>>().

  { 
    return itkGetStaticConstMacro(InternalDimension);
  }
template<typename T , unsigned int N>
T itk::OrientationDistributionFunction< T, N >::GetPrincipleCurvature ( double  alphaMinDegree,
double  alphaMaxDegree,
int  invert 
) const

Definition at line 1003 of file itkOrientationDistributionFunction.txx.

References QuadProgPP::max(), QuadProgPP::median(), ODF_PI, and QuadProgPP::sort().

  {
    // following loop only performed once
    // (computing indices of each angular range)
    m_MutexAngularRange.Lock();
    if(m_AngularRangeIdxs == NULL)
    {
      m_AngularRangeIdxs = new std::vector< std::vector<int>* >();
      for(unsigned int i=0; i<N; i++)
      {
        vnl_vector_fixed<double,3> pDir = GetDirection(i);
        std::vector<int> *idxs = new std::vector<int>();
        for(unsigned int j=0; j<N; j++)
        {
          vnl_vector_fixed<double,3> cDir = GetDirection(j);
          double angle = ( 180 / ODF_PI ) * acos( dot_product(pDir, cDir) );
          if( (angle < alphaMaxDegree) && (angle > alphaMinDegree) )
          {
            idxs->push_back(j);
          }
        }
        m_AngularRangeIdxs->push_back(idxs);
      }
    }
    m_MutexAngularRange.Unlock();

    // find the maximum (or minimum) direction (remember index and value)
    T mode;
    int pIdx = -1;
    if(invert == 0)
    {
      pIdx = GetPrincipleDiffusionDirection();
      mode = (*this)[pIdx];
    }
    else
    {
      mode = NumericTraits<T>::max();
      for( unsigned int i=0; i<N; i++) 
      {
        if((*this)[i] < mode )
        {
          mode = (*this)[i];
          pIdx = i;
        }
      }
    }




    // computing a quantile of the angular range 

    // define quantile
    double quantile = 0.00;

    // collect all values in angular range of mode
    std::vector<T> odfValuesInAngularRange;
    int numInRange = m_AngularRangeIdxs->at(pIdx)->size();
    for(int i=0; i<numInRange; i++)
    {
      odfValuesInAngularRange.push_back((*this)[(*m_AngularRangeIdxs->at(pIdx))[i] ]);
    }

    // sort them by value
    std::sort( odfValuesInAngularRange.begin(), odfValuesInAngularRange.end() );

    // median of angular range
    T median = odfValuesInAngularRange[floor(quantile*(double)numInRange+0.5)];

    // compute and return final value
    if(mode > median)
    {
      return mode/median - 1.0;
    }
    else
    {
      return median/mode - 1.0;
    }
  }
template<class T , unsigned int NOdfDirections>
int itk::OrientationDistributionFunction< T, NOdfDirections >::GetPrincipleDiffusionDirection (  ) const

Definition at line 578 of file itkOrientationDistributionFunction.txx.

References QuadProgPP::max().

Referenced by itk::QBallToRgbImageFilter< TInputImage, TOutputImage >::GenerateData().

  {
    T max = NumericTraits<T>::NonpositiveMin();
    int maxidx = -1;
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      if((*this)[i] > max )
      {
        max = (*this)[i];
        maxidx = i;
      }
    }

    return maxidx;
  }
template<typename T , unsigned int N>
T itk::OrientationDistributionFunction< T, N >::GetStdDevByMaxValue (  ) const

Definition at line 972 of file itkOrientationDistributionFunction.txx.

References QuadProgPP::max(), QuadProgPP::mean(), and QuadProgPP::sqrt().

  {
    double mean = 0;
    double std = 0;
    T max = NumericTraits<T>::NonpositiveMin();
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      T val = (*this)[i];
      mean += val;
      max = (*this)[i] > max ? (*this)[i] : max;
    }
    mean /= InternalDimension;
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      T val = (*this)[i];
      std += (val - mean) * (val - mean);
    }
    std /= InternalDimension-1;

    if(max == 0)
    {
      return 0;
    }
    else
    {
      return (sqrt(std)/max);
    }
  }
template<typename TComponent, unsigned int NOdfDirections>
void itk::OrientationDistributionFunction< TComponent, NOdfDirections >::InitFromTensor ( itk::DiffusionTensor3D< TComponent >  tensor )
template<typename TComponent, unsigned int NOdfDirections>
itk::OrientationDistributionFunction< TComponent, NOdfDirections >::itkStaticConstMacro ( InternalDimension  ,
unsigned  int,
NOdfDirections   
)

Dimension of the vector space.

template<class T , unsigned int NOdfDirections>
OrientationDistributionFunction< T, NOdfDirections > itk::OrientationDistributionFunction< T, NOdfDirections >::MaxNormalize (  ) const

Definition at line 424 of file itkOrientationDistributionFunction.txx.

References QuadProgPP::max().

  {
    T max = NumericTraits<T>::NonpositiveMin();
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      max = (*this)[i] > max ? (*this)[i] : max;
    }
    Self retval;
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      retval[i] = (*this)[i] / max;
    }
    return retval;
  }
template<class T , unsigned int NOdfDirections>
OrientationDistributionFunction< T, NOdfDirections > itk::OrientationDistributionFunction< T, NOdfDirections >::MinMaxNormalize (  ) const

Definition at line 401 of file itkOrientationDistributionFunction.txx.

References QuadProgPP::max(), and min.

  {
    T max = NumericTraits<T>::NonpositiveMin();
    T min = NumericTraits<T>::max();
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      max = (*this)[i] > max ? (*this)[i] : max;
      min = (*this)[i] < min ? (*this)[i] : min;
    }
    Self retval;
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      retval[i] = ((*this)[i] - min) / (max - min);
    }
    return retval;
  }
template<class T , unsigned int NOdfDirections>
void itk::OrientationDistributionFunction< T, NOdfDirections >::Normalize (  )

Definition at line 382 of file itkOrientationDistributionFunction.txx.

References QuadProgPP::sum().

  {
    T sum = 0;
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      sum += (*this)[i];
    }
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      (*this)[i] = (*this)[i] / sum;
    }
  }
template<class T , unsigned int NOdfDirections>
OrientationDistributionFunction< T, NOdfDirections >::ValueType & itk::OrientationDistributionFunction< T, NOdfDirections >::operator() ( unsigned int  row,
unsigned int  col 
)

Matrix notation, in const and non-const forms.

Definition at line 304 of file itkOrientationDistributionFunction.txx.

  {
    unsigned int k; 

    if( row < col ) 
    {
      k = row * InternalDimension + col - row * ( row + 1 ) / 2; 
    }
    else
    {
      k = col * InternalDimension + row - col * ( col + 1 ) / 2; 
    }


    if( k >= InternalDimension )
    {
      k = 0;
    }

    return (*this)[k];
  }
template<class T , unsigned int NOdfDirections>
const OrientationDistributionFunction< T, NOdfDirections >::ValueType & itk::OrientationDistributionFunction< T, NOdfDirections >::operator() ( unsigned int  row,
unsigned int  col 
) const

Definition at line 274 of file itkOrientationDistributionFunction.txx.

  {
    unsigned int k; 

    if( row < col ) 
    {
      k = row * InternalDimension + col - row * ( row + 1 ) / 2; 
    }
    else
    {
      k = col * InternalDimension + row - col * ( col + 1 ) / 2; 
    }


    if( k >= InternalDimension )
    {
      k = 0;
    }

    return (*this)[k];
  }
template<class T , unsigned int NOdfDirections>
OrientationDistributionFunction< T, NOdfDirections > itk::OrientationDistributionFunction< T, NOdfDirections >::operator* ( const RealValueType r ) const

Arithmetic operations between ODFs and scalars

Performs multiplication with a scalar

Definition at line 240 of file itkOrientationDistributionFunction.txx.

  {
    Self result;
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      result[i] = (*this)[i] * r;
    }
    return result;
  }
template<class T , unsigned int NOdfDirections>
const OrientationDistributionFunction< T, NOdfDirections > & itk::OrientationDistributionFunction< T, NOdfDirections >::operator*= ( const RealValueType r )

Performs multiplication by a scalar, in place

Definition at line 205 of file itkOrientationDistributionFunction.txx.

  {
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      (*this)[i] *= r;
    }
    return *this;
  }
template<class T , unsigned int NOdfDirections>
OrientationDistributionFunction< T, NOdfDirections > itk::OrientationDistributionFunction< T, NOdfDirections >::operator+ ( const Self r ) const

Aritmetic operations between pixels. Return a new OrientationDistributionFunction.

Returns a temporary copy of a vector

Definition at line 133 of file itkOrientationDistributionFunction.txx.

  {
    Self result;
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      result[i] = (*this)[i] + r[i];
    }
    return result;
  }
template<class T , unsigned int NOdfDirections>
const OrientationDistributionFunction< T, NOdfDirections > & itk::OrientationDistributionFunction< T, NOdfDirections >::operator+= ( const Self r )

Performs addition in place

Definition at line 170 of file itkOrientationDistributionFunction.txx.

  {
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      (*this)[i] += r[i];
    }
    return *this;
  }
template<class T , unsigned int NOdfDirections>
OrientationDistributionFunction< T, NOdfDirections > itk::OrientationDistributionFunction< T, NOdfDirections >::operator- ( const Self r ) const

Returns a temporary copy of a vector

Definition at line 152 of file itkOrientationDistributionFunction.txx.

  {
    Self result;
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      result[i] = (*this)[i] - r[i];
    }
    return result;
  }
template<class T , unsigned int NOdfDirections>
const OrientationDistributionFunction< T, NOdfDirections > & itk::OrientationDistributionFunction< T, NOdfDirections >::operator-= ( const Self r )

Performs subtraction in place

Definition at line 188 of file itkOrientationDistributionFunction.txx.

  {
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      (*this)[i] -= r[i];
    }
    return *this;
  }
template<class T , unsigned int NOdfDirections>
OrientationDistributionFunction< T, NOdfDirections > itk::OrientationDistributionFunction< T, NOdfDirections >::operator/ ( const RealValueType r ) const

Performs division by a scalar

Definition at line 257 of file itkOrientationDistributionFunction.txx.

  {
    Self result;
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      result[i] = (*this)[i] / r;
    }
    return result;
  }
template<class T , unsigned int NOdfDirections>
const OrientationDistributionFunction< T, NOdfDirections > & itk::OrientationDistributionFunction< T, NOdfDirections >::operator/= ( const RealValueType r )

Performs division by a scalar, in place

Definition at line 222 of file itkOrientationDistributionFunction.txx.

  {
    for( unsigned int i=0; i<InternalDimension; i++) 
    {
      (*this)[i] /= r;
    }
    return *this;
  }
template<class T , unsigned int NOdfDirections>
OrientationDistributionFunction< T, NOdfDirections > & itk::OrientationDistributionFunction< T, NOdfDirections >::operator= ( const ComponentType r )

Definition at line 106 of file itkOrientationDistributionFunction.txx.

  {
    BaseArray::operator=(&r);
    return *this;
  }
template<class T , unsigned int NOdfDirections>
OrientationDistributionFunction< T, NOdfDirections > & itk::OrientationDistributionFunction< T, NOdfDirections >::operator= ( const ComponentArrayType  r )

Definition at line 119 of file itkOrientationDistributionFunction.txx.

  {
    BaseArray::operator=(r);
    return *this;
  }
template<class T , unsigned int NOdfDirections>
OrientationDistributionFunction< T, NOdfDirections > & itk::OrientationDistributionFunction< T, NOdfDirections >::operator= ( const Self r )

Pass-through assignment operator for the Array base class.

Definition at line 93 of file itkOrientationDistributionFunction.txx.

  {
    BaseArray::operator=(r);
    return *this;
  }
template<class T , unsigned int NOdfDirections>
OrientationDistributionFunction< T, NOdfDirections > itk::OrientationDistributionFunction< T, NOdfDirections >::PostMultiply ( const MatrixType m ) const

Post-Multiply by a Matrix as ResultingTensor = ThisTensor * Matrix.

Definition at line 1159 of file itkOrientationDistributionFunction.txx.

References QuadProgPP::sum(), and QuadProgPP::t().

  {
    Self result;
    typedef typename NumericTraits<T>::AccumulateType  AccumulateType;
    for(unsigned int r=0; r<NOdfDirections; r++)
    {
      for(unsigned int c=0; c<NOdfDirections; c++)
      {
        AccumulateType sum = NumericTraits<AccumulateType>::ZeroValue();
        for(unsigned int t=0; t<NOdfDirections; t++)
        {
          sum += (*this)(r,t) * m(t,c);
        }
        result(r,c) = static_cast<T>( sum );
      }
    }
    return result;
  }
template<class T , unsigned int NOdfDirections>
OrientationDistributionFunction< T, NOdfDirections > itk::OrientationDistributionFunction< T, NOdfDirections >::PreMultiply ( const MatrixType m ) const

Pre-Multiply by a Matrix as ResultingTensor = Matrix * ThisTensor.

Definition at line 1134 of file itkOrientationDistributionFunction.txx.

References QuadProgPP::sum(), and QuadProgPP::t().

  {
    Self result;
    typedef typename NumericTraits<T>::AccumulateType  AccumulateType;
    for(unsigned int r=0; r<NOdfDirections; r++)
    {
      for(unsigned int c=0; c<NOdfDirections; c++)
      {
        AccumulateType sum = NumericTraits<AccumulateType>::ZeroValue();
        for(unsigned int t=0; t<NOdfDirections; t++)
        {
          sum += m(r,t) * (*this)(t,c);
        }
        result(r,c) = static_cast<T>( sum );
      }
    }
    return result;
  }
template<class T , unsigned int NOdfDirections>
void itk::OrientationDistributionFunction< T, NOdfDirections >::SetIsotropic (  )

Set the distribution to isotropic.

Definition at line 334 of file itkOrientationDistributionFunction.txx.

  {
    this->Fill(NumericTraits< T >::One / NOdfDirections);
  }
template<typename TComponent, unsigned int NOdfDirections>
void itk::OrientationDistributionFunction< TComponent, NOdfDirections >::SetNthComponent ( int  c,
const ComponentType v 
) [inline]

Set the Nth component to v.

Definition at line 136 of file itkOrientationDistributionFunction.h.

  {  this->operator[](c) = v; }

The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines