Ejemplo n.º 1
0
void mitk::LiveWireTool2D::FindHighestGradientMagnitudeByITK(itk::Image<TPixel, VImageDimension> *inputImage,
                                                             itk::Index<3> &index,
                                                             itk::Index<3> &returnIndex)
{
  typedef itk::Image<TPixel, VImageDimension> InputImageType;
  typedef typename InputImageType::IndexType IndexType;

  unsigned long xMAX = inputImage->GetLargestPossibleRegion().GetSize()[0];
  unsigned long yMAX = inputImage->GetLargestPossibleRegion().GetSize()[1];

  returnIndex[0] = index[0];
  returnIndex[1] = index[1];
  returnIndex[2] = 0.0;

  double gradientMagnitude = 0.0;
  double maxGradientMagnitude = 0.0;

  /*
    the size and thus the region of 7x7 is only used to calculate the gradient magnitude in that region
    not for searching the maximum value
    */

  // maximum value in each direction for size
  typename InputImageType::SizeType size;
  size[0] = 7;
  size[1] = 7;

  // minimum value in each direction for startRegion
  IndexType startRegion;
  startRegion[0] = index[0] - 3;
  startRegion[1] = index[1] - 3;
  if (startRegion[0] < 0)
    startRegion[0] = 0;
  if (startRegion[1] < 0)
    startRegion[1] = 0;
  if (xMAX - index[0] < 7)
    startRegion[0] = xMAX - 7;
  if (yMAX - index[1] < 7)
    startRegion[1] = yMAX - 7;

  index[0] = startRegion[0] + 3;
  index[1] = startRegion[1] + 3;

  typename InputImageType::RegionType region;
  region.SetSize(size);
  region.SetIndex(startRegion);

  typedef typename itk::GradientMagnitudeImageFilter<InputImageType, InputImageType> GradientMagnitudeFilterType;
  typename GradientMagnitudeFilterType::Pointer gradientFilter = GradientMagnitudeFilterType::New();
  gradientFilter->SetInput(inputImage);
  gradientFilter->GetOutput()->SetRequestedRegion(region);

  gradientFilter->Update();
  typename InputImageType::Pointer gradientMagnImage;
  gradientMagnImage = gradientFilter->GetOutput();

  IndexType currentIndex;
  currentIndex[0] = 0;
  currentIndex[1] = 0;

  // search max (approximate) gradient magnitude
  for (int x = -1; x <= 1; ++x)
  {
    currentIndex[0] = index[0] + x;

    for (int y = -1; y <= 1; ++y)
    {
      currentIndex[1] = index[1] + y;

      gradientMagnitude = gradientMagnImage->GetPixel(currentIndex);

      // check for new max
      if (maxGradientMagnitude < gradientMagnitude)
      {
        maxGradientMagnitude = gradientMagnitude;
        returnIndex[0] = currentIndex[0];
        returnIndex[1] = currentIndex[1];
        returnIndex[2] = 0.0;
      } // end if
    }   // end for y

    currentIndex[1] = index[1];
  } // end for x
}
void mitk::ImageLiveWireContourModelFilter::CreateDynamicCostMapByITK( const itk::Image<TPixel, VImageDimension>* inputImage, mitk::ContourModel* path )
{
  /*++++++++++ create dynamic cost transfer map ++++++++++*/

  /* Compute  the costs of the gradient magnitude dynamically.
  * using a map of the histogram of gradient magnitude image.
  * Use the histogram gradient map to interpolate the costs
  * with gaussing function including next two bins right and left
  * to current position x. With the histogram gradient costs are interpolated
  * with a gaussing function summation of next two bins right and left
  * to current position x.
  */
  std::vector< itk::Index<VImageDimension> > shortestPath;

  mitk::Image::ConstPointer input = dynamic_cast<const mitk::Image*>(this->GetInput());
  if(path == NULL)
  {
    OutputType::Pointer output = this->GetOutput();
    mitk::ContourModel::VertexIterator it = output->IteratorBegin();
    while( it != output->IteratorEnd() )
    {
      itk::Index<VImageDimension> cur;
      mitk::Point3D c = (*it)->Coordinates;
      input->GetGeometry()->WorldToIndex(c, c);
      cur[0] = c[0];
      cur[1] = c[1];

      shortestPath.push_back( cur);
      it++;
    }
  }
  else
  {

    mitk::ContourModel::VertexIterator it = path->IteratorBegin();
    while( it != path->IteratorEnd() )
    {
      itk::Index<VImageDimension> cur;
      mitk::Point3D c = (*it)->Coordinates;
      input->GetGeometry()->WorldToIndex(c, c);
      cur[0] = c[0];
      cur[1] = c[1];

      shortestPath.push_back( cur);
      it++;
    }

  }

  // filter image gradient magnitude
  typedef  itk::GradientMagnitudeImageFilter< itk::Image<TPixel, VImageDimension>,  itk::Image<TPixel, VImageDimension> > GradientMagnitudeFilterType;
  typename GradientMagnitudeFilterType::Pointer gradientFilter = GradientMagnitudeFilterType::New();
  gradientFilter->SetInput(inputImage);
  gradientFilter->Update();
  typename itk::Image<TPixel, VImageDimension>::Pointer gradientMagnImage = gradientFilter->GetOutput();

  //get the path

  //iterator of path
  typename std::vector< itk::Index<VImageDimension> >::iterator pathIterator = shortestPath.begin();

  std::map< int, int > histogram;

  //create histogram within path
  while(pathIterator != shortestPath.end())
  {
    //count pixel values
    //use scale factor to avoid mapping gradients between 0.0 and 1.0 to same bin
    histogram[ static_cast<int>( gradientMagnImage->GetPixel((*pathIterator)) * ImageLiveWireContourModelFilter::CostFunctionType::MAPSCALEFACTOR ) ] += 1;

    pathIterator++;
  }

  double max = 1.0;

  if( !histogram.empty() )
  {
    std::map< int, int >::iterator itMAX;

    //get max of histogramm
    int currentMaxValue = 0;
    std::map< int, int >::iterator it = histogram.begin();
    while( it != histogram.end())
    {
      if((*it).second > currentMaxValue)
      {
        itMAX = it;
        currentMaxValue = (*it).second;
      }
      it++;
    }

    std::map< int, int >::key_type keyOfMax = itMAX->first;

    // compute the to max of gaussian summation
    std::map< int, int >::iterator end = histogram.end();
    std::map< int, int >::iterator last = --(histogram.end());

    std::map< int, int >::iterator left2;
    std::map< int, int >::iterator left1;
    std::map< int, int >::iterator right1;
    std::map< int, int >::iterator right2;

    right1 = itMAX;

    if(right1 == end || right1 == last )
    {
      right2 = end;
    }
    else//( right1 <= last )
    {
      std::map< int, int >::iterator temp = right1;
      right2 = ++right1;//rght1 + 1
      right1 = temp;
    }

    if( right1 == histogram.begin() )
    {
      left1 = end;
      left2 = end;
    }
    else if( right1 == (++(histogram.begin())) )
    {
      std::map< int, int >::iterator temp = right1;
      left1  = --right1;//rght1 - 1
      right1 = temp;
      left2  = end;
    }
    else
    {
      std::map< int, int >::iterator temp = right1;
      left1 = --right1;//rght1 - 1
      left2 = --right1;//rght1 - 2
      right1 = temp;
    }

    double partRight1, partRight2, partLeft1, partLeft2;
    partRight1 = partRight2 = partLeft1 = partLeft2 = 0.0;

    /*
    f(x) = v(bin) * e^ ( -1/2 * (|x-k(bin)| / sigma)^2 )

    gaussian approximation

    where
    v(bin) is the value in the map
    k(bin) is the key
    */

    if( left2 != end )
    {
      partLeft2 = ImageLiveWireContourModelFilter::CostFunctionType::Gaussian(keyOfMax, left2->first, left2->second);
    }

    if( left1 != end )
    {
      partLeft1 = ImageLiveWireContourModelFilter::CostFunctionType::Gaussian(keyOfMax, left1->first, left1->second);
    }

    if( right1 != end )
    {
      partRight1 = ImageLiveWireContourModelFilter::CostFunctionType::Gaussian(keyOfMax, right1->first, right1->second);
    }

    if( right2 != end )
    {
      partRight2 = ImageLiveWireContourModelFilter::CostFunctionType::Gaussian(keyOfMax, right2->first, right2->second);
    }

    max = (partRight1 + partRight2 + partLeft1 + partLeft2);

  }

  this->m_CostFunction->SetDynamicCostMap(histogram);
  this->m_CostFunction->SetCostMapMaximum(max);
}