Beispiel #1
0
static HalfHermetianImageType::Pointer GetLowpassOperator(FloatImageType::Pointer norm01_lowres,
                                                           FloatImageType::Pointer p_image, const PrecisionType scaler)
{
  /*
   * Make dirac-delta impulse response filter for convolving with the high-resolution image
  The operator A should represent the characteristics of the measurement device as it
  takes measurements at lower resolutions.  For example, in MRI as resolution is decreased,
  larger anatomical regions are included in each measurement, thus giving a
  smoother image as if the high resolution image were passed through a low-pass-filter.
  p_image below represents the smoothing convolution filter that is applied to a
  high-resolution image to best represent the low-resolution image sampling.
  In the case of no downsampling p_image is simply a perfect dirac-delta function.
  Convolution in the spatial-domain is multiplication in the frequency domain.

  In the case were some downsampling is present between the lowresolution and
  the highresolution images, we need the operator A to represent a low-pass filter
  that optimally models the lower sampling rate.  The low-pass filter is accomplished
  in the frequency domain by zeroing-out frequency components that are not representable
  in the frequency domain of the low-resolution image.
   */

  HalfHermetianImageType::Pointer testA_fhp = A_fhp(p_image,norm01_lowres.GetPointer());
  FloatImageType::Pointer testAtA = At_fhp(testA_fhp,norm01_lowres->GetLargestPossibleRegion().GetSize()[0]%2 == 1, p_image.GetPointer());
  HalfHermetianImageType::Pointer AtAhat = GetForwardFFT(testAtA);
  return opIC(AtAhat,AtAhat,'*',scaler); // A is the linear measurement operator
}
void QmitkBasicImageProcessing::StartButtonClicked()
{
  if(!m_SelectedImageNode->GetNode()) return;

  this->BusyCursorOn();

  mitk::Image::Pointer newImage;

  try
  {
    newImage = dynamic_cast<mitk::Image*>(m_SelectedImageNode->GetNode()->GetData());
  }
  catch ( std::exception &e )
  {
  QString exceptionString = "An error occured during image loading:\n";
  exceptionString.append( e.what() );
    QMessageBox::warning( NULL, "Basic Image Processing", exceptionString , QMessageBox::Ok, QMessageBox::NoButton );
    this->BusyCursorOff();
    return;
  }

  // check if input image is valid, casting does not throw exception when casting from 'NULL-Object'
  if ( (! newImage) || (newImage->IsInitialized() == false) )
  {
    this->BusyCursorOff();

    QMessageBox::warning( NULL, "Basic Image Processing", "Input image is broken or not initialized. Returning.", QMessageBox::Ok, QMessageBox::NoButton );
    return;
  }

  // check if operation is done on 4D a image time step
  if(newImage->GetDimension() > 3)
  {
    mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
    timeSelector->SetInput(newImage);
    timeSelector->SetTimeNr( ((QmitkSliderNavigatorWidget*)m_Controls->sliceNavigatorTime)->GetPos() );
    timeSelector->Update();
    newImage = timeSelector->GetOutput();
  }



  // check if image or vector image
  ImageType::Pointer itkImage = ImageType::New();
  VectorImageType::Pointer itkVecImage = VectorImageType::New();

  int isVectorImage = newImage->GetPixelType().GetNumberOfComponents();

  if(isVectorImage > 1)
  {
    CastToItkImage( newImage, itkVecImage );
  }
  else
  {
    CastToItkImage( newImage, itkImage );
  }

  std::stringstream nameAddition("");

  int param1 = m_Controls->sbParam1->value();
  int param2 = m_Controls->sbParam2->value();
  double dparam1 = m_Controls->dsbParam1->value();
  double dparam2 = m_Controls->dsbParam2->value();
  double dparam3 = m_Controls->dsbParam3->value();

  try{

  switch (m_SelectedAction)
  {

  case GAUSSIAN:
    {
      GaussianFilterType::Pointer gaussianFilter = GaussianFilterType::New();
      gaussianFilter->SetInput( itkImage );
      gaussianFilter->SetVariance( param1 );
      gaussianFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(gaussianFilter->GetOutput())->Clone();
      nameAddition << "_Gaussian_var_" << param1;
      std::cout << "Gaussian filtering successful." << std::endl;
      break;
    }

  case MEDIAN:
    {
      MedianFilterType::Pointer medianFilter = MedianFilterType::New();
      MedianFilterType::InputSizeType size;
      size.Fill(param1);
      medianFilter->SetRadius( size );
      medianFilter->SetInput(itkImage);
      medianFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(medianFilter->GetOutput())->Clone();
      nameAddition << "_Median_radius_" << param1;
      std::cout << "Median Filtering successful." << std::endl;
      break;
    }

  case TOTALVARIATION:
    {
      if(isVectorImage > 1)
      {
        VectorTotalVariationFilterType::Pointer TVFilter
          = VectorTotalVariationFilterType::New();
        TVFilter->SetInput( itkVecImage.GetPointer() );
        TVFilter->SetNumberIterations(param1);
        TVFilter->SetLambda(double(param2)/1000.);
        TVFilter->UpdateLargestPossibleRegion();

        newImage = mitk::ImportItkImage(TVFilter->GetOutput())->Clone();
      }
      else
      {
        ImagePTypeToFloatPTypeCasterType::Pointer floatCaster = ImagePTypeToFloatPTypeCasterType::New();
        floatCaster->SetInput( itkImage );
        floatCaster->Update();
        FloatImageType::Pointer fImage = floatCaster->GetOutput();

        TotalVariationFilterType::Pointer TVFilter
          = TotalVariationFilterType::New();
        TVFilter->SetInput( fImage.GetPointer() );
        TVFilter->SetNumberIterations(param1);
        TVFilter->SetLambda(double(param2)/1000.);
        TVFilter->UpdateLargestPossibleRegion();

        newImage = mitk::ImportItkImage(TVFilter->GetOutput())->Clone();
      }

      nameAddition << "_TV_Iter_" << param1 << "_L_" << param2;
      std::cout << "Total Variation Filtering successful." << std::endl;
      break;
    }

  case DILATION:
    {
      BallType binaryBall;
      binaryBall.SetRadius( param1 );
      binaryBall.CreateStructuringElement();

      DilationFilterType::Pointer dilationFilter = DilationFilterType::New();
      dilationFilter->SetInput( itkImage );
      dilationFilter->SetKernel( binaryBall );
      dilationFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(dilationFilter->GetOutput())->Clone();
      nameAddition << "_Dilated_by_" << param1;
      std::cout << "Dilation successful." << std::endl;
      break;
    }

  case EROSION:
    {
      BallType binaryBall;
      binaryBall.SetRadius( param1 );
      binaryBall.CreateStructuringElement();

      ErosionFilterType::Pointer erosionFilter = ErosionFilterType::New();
      erosionFilter->SetInput( itkImage );
      erosionFilter->SetKernel( binaryBall );
      erosionFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(erosionFilter->GetOutput())->Clone();
      nameAddition << "_Eroded_by_" << param1;
      std::cout << "Erosion successful." << std::endl;
      break;
    }

  case OPENING:
    {
      BallType binaryBall;
      binaryBall.SetRadius( param1 );
      binaryBall.CreateStructuringElement();

      OpeningFilterType::Pointer openFilter = OpeningFilterType::New();
      openFilter->SetInput( itkImage );
      openFilter->SetKernel( binaryBall );
      openFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(openFilter->GetOutput())->Clone();
      nameAddition << "_Opened_by_" << param1;
      std::cout << "Opening successful." << std::endl;
      break;
    }

  case CLOSING:
    {
      BallType binaryBall;
      binaryBall.SetRadius( param1 );
      binaryBall.CreateStructuringElement();

      ClosingFilterType::Pointer closeFilter = ClosingFilterType::New();
      closeFilter->SetInput( itkImage );
      closeFilter->SetKernel( binaryBall );
      closeFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(closeFilter->GetOutput())->Clone();
      nameAddition << "_Closed_by_" << param1;
      std::cout << "Closing successful." << std::endl;
      break;
    }

  case GRADIENT:
    {
      GradientFilterType::Pointer gradientFilter = GradientFilterType::New();
      gradientFilter->SetInput( itkImage );
      gradientFilter->SetSigma( param1 );
      gradientFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(gradientFilter->GetOutput())->Clone();
      nameAddition << "_Gradient_sigma_" << param1;
      std::cout << "Gradient calculation successful." << std::endl;
      break;
    }

  case LAPLACIAN:
    {
      // the laplace filter requires a float type image as input, we need to cast the itkImage
      // to correct type
      ImagePTypeToFloatPTypeCasterType::Pointer caster = ImagePTypeToFloatPTypeCasterType::New();
      caster->SetInput( itkImage );
      caster->Update();
      FloatImageType::Pointer fImage = caster->GetOutput();

      LaplacianFilterType::Pointer laplacianFilter = LaplacianFilterType::New();
      laplacianFilter->SetInput( fImage );
      laplacianFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(laplacianFilter->GetOutput())->Clone();
      nameAddition << "_Second_Derivative";
      std::cout << "Laplacian filtering successful." << std::endl;
      break;
    }

  case SOBEL:
    {
      // the sobel filter requires a float type image as input, we need to cast the itkImage
      // to correct type
      ImagePTypeToFloatPTypeCasterType::Pointer caster = ImagePTypeToFloatPTypeCasterType::New();
      caster->SetInput( itkImage );
      caster->Update();
      FloatImageType::Pointer fImage = caster->GetOutput();

      SobelFilterType::Pointer sobelFilter = SobelFilterType::New();
      sobelFilter->SetInput( fImage );
      sobelFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(sobelFilter->GetOutput())->Clone();
      nameAddition << "_Sobel";
      std::cout << "Edge Detection successful." << std::endl;
      break;
    }

  case THRESHOLD:
    {
      ThresholdFilterType::Pointer thFilter = ThresholdFilterType::New();
      thFilter->SetLowerThreshold(param1 < param2 ? param1 : param2);
      thFilter->SetUpperThreshold(param2 > param1 ? param2 : param1);
      thFilter->SetInsideValue(1);
      thFilter->SetOutsideValue(0);
      thFilter->SetInput(itkImage);
      thFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(thFilter->GetOutput())->Clone();
      nameAddition << "_Threshold";
      std::cout << "Thresholding successful." << std::endl;
      break;
    }

  case INVERSION:
    {
      InversionFilterType::Pointer invFilter = InversionFilterType::New();
      mitk::ScalarType min = newImage->GetScalarValueMin();
      mitk::ScalarType max = newImage->GetScalarValueMax();
      invFilter->SetMaximum( max + min );
      invFilter->SetInput(itkImage);
      invFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(invFilter->GetOutput())->Clone();
      nameAddition << "_Inverted";
      std::cout << "Image inversion successful." << std::endl;
      break;
    }

  case DOWNSAMPLING:
    {
      ResampleImageFilterType::Pointer downsampler = ResampleImageFilterType::New();
      downsampler->SetInput( itkImage );

      NearestInterpolatorType::Pointer interpolator = NearestInterpolatorType::New();
      downsampler->SetInterpolator( interpolator );

      downsampler->SetDefaultPixelValue( 0 );

      ResampleImageFilterType::SpacingType spacing = itkImage->GetSpacing();
      spacing *= (double) param1;
      downsampler->SetOutputSpacing( spacing );

      downsampler->SetOutputOrigin( itkImage->GetOrigin() );
      downsampler->SetOutputDirection( itkImage->GetDirection() );

      ResampleImageFilterType::SizeType size = itkImage->GetLargestPossibleRegion().GetSize();
      for ( int i = 0; i < 3; ++i )
      {
        size[i] /= param1;
      }
      downsampler->SetSize( size );
      downsampler->UpdateLargestPossibleRegion();

      newImage = mitk::ImportItkImage(downsampler->GetOutput())->Clone();
      nameAddition << "_Downsampled_by_" << param1;
      std::cout << "Downsampling successful." << std::endl;
      break;
    }

  case FLIPPING:
    {
      FlipImageFilterType::Pointer flipper = FlipImageFilterType::New();
      flipper->SetInput( itkImage );
      itk::FixedArray<bool, 3> flipAxes;
      for(int i=0; i<3; ++i)
      {
        if(i == param1)
        {
          flipAxes[i] = true;
        }
        else
        {
          flipAxes[i] = false;
        }
      }
      flipper->SetFlipAxes(flipAxes);
      flipper->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(flipper->GetOutput())->Clone();
      std::cout << "Image flipping successful." << std::endl;
      break;
    }

  case RESAMPLING:
    {
      std::string selectedInterpolator;
      ResampleImageFilterType::Pointer resampler = ResampleImageFilterType::New();
      switch (m_SelectedInterpolation)
      {
      case LINEAR:
        {
          LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New();
          resampler->SetInterpolator(interpolator);
          selectedInterpolator = "Linear";
          break;
        }
      case NEAREST:
        {
          NearestInterpolatorType::Pointer interpolator = NearestInterpolatorType::New();
          resampler->SetInterpolator(interpolator);
          selectedInterpolator = "Nearest";
          break;
        }
      default:
        {
          LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New();
          resampler->SetInterpolator(interpolator);
          selectedInterpolator = "Linear";
          break;
        }
      }
      resampler->SetInput( itkImage );
      resampler->SetOutputOrigin( itkImage->GetOrigin() );

      ImageType::SizeType input_size = itkImage->GetLargestPossibleRegion().GetSize();
      ImageType::SpacingType input_spacing = itkImage->GetSpacing();

      ImageType::SizeType output_size;
      ImageType::SpacingType output_spacing;

      output_size[0] = input_size[0] * (input_spacing[0] / dparam1);
      output_size[1] = input_size[1] * (input_spacing[1] / dparam2);
      output_size[2] = input_size[2] * (input_spacing[2] / dparam3);
      output_spacing [0] = dparam1;
      output_spacing [1] = dparam2;
      output_spacing [2] = dparam3;

      resampler->SetSize( output_size );
      resampler->SetOutputSpacing( output_spacing );
      resampler->SetOutputDirection( itkImage->GetDirection() );

      resampler->UpdateLargestPossibleRegion();

      ImageType::Pointer resampledImage = resampler->GetOutput();

      newImage = mitk::ImportItkImage( resampledImage );
      nameAddition << "_Resampled_" << selectedInterpolator;
      std::cout << "Resampling successful." << std::endl;
      break;
    }


  case RESCALE:
    {
      FloatImageType::Pointer floatImage = FloatImageType::New();
      CastToItkImage( newImage, floatImage );
      itk::RescaleIntensityImageFilter<FloatImageType,FloatImageType>::Pointer filter = itk::RescaleIntensityImageFilter<FloatImageType,FloatImageType>::New();
      filter->SetInput(0, floatImage);
      filter->SetOutputMinimum(dparam1);
      filter->SetOutputMaximum(dparam2);
      filter->Update();
      floatImage = filter->GetOutput();

      newImage = mitk::Image::New();
      newImage->InitializeByItk(floatImage.GetPointer());
      newImage->SetVolume(floatImage->GetBufferPointer());
      nameAddition << "_Rescaled";
      std::cout << "Rescaling successful." << std::endl;

      break;
    }

  default:
    this->BusyCursorOff();
    return;
  }
  }
  catch (...)
  {
    this->BusyCursorOff();
    QMessageBox::warning(NULL, "Warning", "Problem when applying filter operation. Check your input...");
    return;
  }

  newImage->DisconnectPipeline();

  // adjust level/window to new image
  mitk::LevelWindow levelwindow;
  levelwindow.SetAuto( newImage );
  mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New();
  levWinProp->SetLevelWindow( levelwindow );

  // compose new image name
  std::string name = m_SelectedImageNode->GetNode()->GetName();
  if (name.find(".pic.gz") == name.size() -7 )
  {
    name = name.substr(0,name.size() -7);
  }
  name.append( nameAddition.str() );

  // create final result MITK data storage node
  mitk::DataNode::Pointer result = mitk::DataNode::New();
  result->SetProperty( "levelwindow", levWinProp );
  result->SetProperty( "name", mitk::StringProperty::New( name.c_str() ) );
  result->SetData( newImage );

  // for vector images, a different mapper is needed
  if(isVectorImage > 1)
  {
    mitk::VectorImageMapper2D::Pointer mapper =
      mitk::VectorImageMapper2D::New();
    result->SetMapper(1,mapper);
  }

  // reset GUI to ease further processing
//  this->ResetOneImageOpPanel();

  // add new image to data storage and set as active to ease further processing
  GetDefaultDataStorage()->Add( result, m_SelectedImageNode->GetNode() );
  if ( m_Controls->cbHideOrig->isChecked() == true )
    m_SelectedImageNode->GetNode()->SetProperty( "visible", mitk::BoolProperty::New(false) );
  // TODO!! m_Controls->m_ImageSelector1->SetSelectedNode(result);

  // show the results
  mitk::RenderingManager::GetInstance()->RequestUpdateAll();
  this->BusyCursorOff();
}
Beispiel #3
0
/*
OPWEIGHTEDL2: Solves weighted L2 regularized inverse problems.
Minimizes the cost function
X* = argmin_X ||A(X)-b_FC||_2^2 + lambda ||W |D(X)| ||_2^2
where     X* = recovered image
          A  = linear measurement operator
          b_FC  = (noisy) measurements
                 %           W  = diagonal weight matrix built from the edge mask
          |D(X)| = gradient magnitude at each pixel

Inputs:  A = function handle representing the forward
              model/measurement operator
         At = function handle representing the backwards model/
              the transpose of the measurment operator.
              (e.g. if A is a downsampling, At is a upsampling)
         b_FC =  a vector of measurements; should match the
              dimensions of A(X)
         lambda = regularization parameter that balances data fidelity
              and smoothness. set lambda high for more smoothing.
         siz = output image size, e.g. siz = [512,512]
         Niter = is the number of iterations; should be ~100-500

Output:  X = high-resolution output image
         cost = array of cost function value vs. iteration
Define AtA fourier mask
PrecisionType lambda, uvec ind_samples, frowvec res, int Niter, double tol, PrecisionType gam, FloatImageType::Pointer& X, frowvec& cost, frowvec& resvec)
 */
FloatImageType::Pointer OpWeightedL2(FloatImageType::Pointer norm01_lowres, FloatImageType::Pointer edgemask)
{
  const PrecisionType lambda = 1e-3F ;
  constexpr int Niter = 100;
  const PrecisionType tol = 1e-8F ;

  const PrecisionType gam = 1.0F ;

  //typedef itk::VectorMagnitudeImageFilter<CVImageType, FloatImageType> GMType;

  //The optimal filter for modeling the measurement operator is low pass filter in this case
  // NOTE: That the A operator is a projection operator, so A^{T}A = A, That is to say that applying
  //       the A^{T} to A results in A.
  FloatImageType::Pointer p_image = GetDiracDeltaImage(edgemask);
  // Precompute

  //Make high-res coefficients
  const HalfHermetianImageType::Pointer b_FC = GetAFP_of_b(norm01_lowres, edgemask);
  //TODO: too many copies of Atb here.
  FloatImageType::Pointer Atb = At_fhp(b_FC,
                                       edgemask->GetLargestPossibleRegion().GetSize()[0]%2 == 1,
                                       edgemask.GetPointer());
  FloatImageType::Pointer TwoAtb = MakeTwoAtb(Atb);
  FloatImageType::Pointer X = DeepImageCopy<FloatImageType>(Atb);
  Atb = nullptr; //Save memory here

  CVImageType::Pointer DX = GetGradient(X);
  CVImageType::Pointer L = CreateEmptyImage<CVImageType>(DX);
  CVImageType::Pointer Y = CreateEmptyImage<CVImageType>(DX);
  //CVImageType::Pointer WDX = CreateEmptyImage<CVImageType>(DX);
  CVImageType::Pointer residue = CreateEmptyImage<CVImageType>(DX);
  CVImageType::Pointer YminusL = CreateEmptyImage<CVImageType>(DX);
  FloatImageType::Pointer tempValue=CreateEmptyImage<FloatImageType>(DX);

  std::vector<PrecisionType> resvec(Niter,0);
  std::vector<PrecisionType> cost(Niter,0);

#ifdef USE_WRITE_DEGUBBING
  itk::ComplexToModulusImageFilter<HalfHermetianImageType,FloatImageType>::Pointer cpx2abs =
  itk::ComplexToModulusImageFilter<HalfHermetianImageType,FloatImageType>::New();
#endif

  CVImageType::Pointer gradIm = GetGradient(p_image);
  FloatImageType::Pointer divIm = GetDivergence(gradIm);
  HalfHermetianImageType::Pointer DtDhat = GetForwardFFT(divIm);
  // TODO:  ALL SAME TO HERE!
  typedef HalfHermetianImageType::PixelType FCType;
  HalfHermetianImageType::Pointer TwoTimesAtAhatPlusLamGamDtDhat = CreateEmptyImage<HalfHermetianImageType>(DtDhat);
  {
    HalfHermetianImageType::Pointer TwoTimesAtAhat = GetLowpassOperator(norm01_lowres,p_image, 2.0F);
    TwoTimesAtAhatPlusLamGamDtDhat = opIC(TwoTimesAtAhatPlusLamGamDtDhat,FCType(lambda*gam),'*',DtDhat);
    //TODO:  Make This an inverse!
    TwoTimesAtAhatPlusLamGamDtDhat = opII(TwoTimesAtAhatPlusLamGamDtDhat,TwoTimesAtAhat,'+',TwoTimesAtAhatPlusLamGamDtDhat);
  }
  p_image = nullptr; //Save memory

  const bool edgemask_ActualXDimensionIsOdd = edgemask->GetLargestPossibleRegion().GetSize()[0] % 2 == 1;

  CVImageType::Pointer InvTwoMuPlusGamma = ComputeInvTwoMuPlusGamma(edgemask,gam);
  //FloatImageType::Pointer SqrtMu = ComputeSqrtMu(edgemask);

#define USE_BLAS_WRAPPERS
#ifdef USE_BLAS_WRAPPERS
#else
  typedef itk::AddImageFilter<CVImageType,CVImageType> CVImageAdder;
  CVImageAdder::Pointer dxPlusL = CVImageAdder::New();
#endif

  itk::TimeProbe tp;
  tp.Start();

  HalfHermetianImageType::Pointer tempRatioFC = CreateEmptyImage<HalfHermetianImageType>(DtDhat);

  for (size_t i=0; i < Niter; ++i)
  {
    std::cout << "Iteration : " << i << std::endl;

#ifdef USE_BLAS_WRAPPERS
    //Z = 1.0*L+DX
    AddAllElements(DX,1.0F,L,DX,gam);//DX destroyed
    CVImageType::Pointer & Z = DX;
#else
    //Z = opII(Z,DX,'+',L);
    dxPlusL->SetInput1(DX);
    dxPlusL->SetInput2(L);
    dxPlusL->SetInPlace(true);
    dxPlusL->Update();
    CVImageType::Pointer Z=dxPlusL->GetOutput();
    MultiplyCVByScalar(Z,gam);
#endif
#ifdef USE_BLAS_WRAPPERS
    //Y=InvTwoMuPlusGamm.*Z
    MultiplyVectors(Y,InvTwoMuPlusGamma,Z);
#else
    Y = opII(Y,Z,'*',InvTwoMuPlusGamma);
#endif

    // X Subprob
    // Numerator = 2*Atb+lambda*gam*SRdiv(Y-L))
#ifdef USE_BLAS_WRAPPERS
    //YminusL = 1.0F* SRdiv( -1.0F*L + Y)
    Duplicate(Y,YminusL);
    AddAllElements(YminusL,-1.0F,L,YminusL,1.0F);
#else
    YminusL=opII(YminusL,Y,'-',L);
#endif
    FloatImageType::Pointer tempNumerator=GetDivergence(YminusL);
#ifdef USE_BLAS_WRAPPERS
    //lambd*gam*tempNumerator+TwoAtb
    Duplicate(TwoAtb,tempValue);
    AddAllElements(tempValue,lambda*gam,tempNumerator,tempValue,1.0F);
    HalfHermetianImageType::Pointer tempNumeratorFC = GetForwardFFT(tempValue);
#else
    tempNumerator=opIC(tempNumerator,lambda*gam,'*',tempNumerator);
    tempNumerator=opII(tempNumerator,TwoAtb,'+',tempNumerator);
    HalfHermetianImageType::Pointer tempNumeratorFC = GetForwardFFT(tempNumerator);
#endif

    //KEEP
    tempRatioFC = opII_scalar(tempRatioFC,tempNumeratorFC,'/',TwoTimesAtAhatPlusLamGamDtDhat);

    X = GetInverseFFT(tempRatioFC,edgemask_ActualXDimensionIsOdd,1.0); //TODO: Determine scale factor here. X

    // should be on same dynamic range as b
    DX = GetGradient(X);
    residue = opII(residue, DX, '-', Y); //TODO:  Implement math graph output here
    L = opII(L,L,'+',residue);

    //
    resvec[i] = 0; //TODO: Figure out the math for here
    if ( i > 900000 )
    {
      tp.Stop();
      std::cout << " Only iterations " << tp.GetTotal() << tp.GetUnit() << std::endl;
      return X;
    }
    if( i > 99 ) //HACK: Cutting this function short
    {
      return X;
    }
    //WDX = opII_CVmult(WDX,SqrtMu,'*',DX);
    //diff = opII(diff,A_fhp(X,norm01_lowres.GetPointer()),'-',b_FC);
    //
    //cost[i] = 0; //TODO: Need to figure out math for here
  }
  return X;
}
Beispiel #4
0
static HalfHermetianImageType::Pointer GetAFP_of_b(FloatImageType::Pointer norm01_lowres, FloatImageType::Pointer edgemask)
{
  FloatImageType::Pointer upsampledB = IdentityResampleByFFT(norm01_lowres, edgemask.GetPointer());
  HalfHermetianImageType::Pointer b_FC = A_fhp(upsampledB, norm01_lowres.GetPointer());
  return b_FC;
}
  bool AcceptMatch(VertexDescriptorType target, VertexDescriptorType source, float& computedEnergy) const override
  {
    itk::Index<2> targetPixel = ITKHelpers::CreateIndex(target);
    itk::ImageRegion<2> targetRegion = ITKHelpers::GetRegionInRadiusAroundPixel(targetPixel, HalfWidth);

    itk::Index<2> sourcePixel = ITKHelpers::CreateIndex(source);
    itk::ImageRegion<2> sourceRegion = ITKHelpers::GetRegionInRadiusAroundPixel(sourcePixel, HalfWidth);

    typedef itk::Image<float, 2> FloatImageType;
    
    typedef itk::VectorMagnitudeImageFilter<TImage, FloatImageType> VectorMagnitudeFilterType;
    typename VectorMagnitudeFilterType::Pointer magnitudeFilter = VectorMagnitudeFilterType::New();
    magnitudeFilter->SetInput(Image);
    magnitudeFilter->Update();

    std::vector<itk::Offset<2> > validOffsets = MaskImage->GetValidOffsetsInRegion(targetRegion);

    FloatImageType::Pointer sourceImage = FloatImageType::New();
//     sourceImage->SetRegions(ITKHelpers::CornerRegion(sourceRegion.GetSize()));
//     sourceImage->Allocate();
    ITKHelpers::ExtractRegion(magnitudeFilter->GetOutput(), sourceRegion, sourceImage.GetPointer());

    FloatImageType::Pointer targetImage = FloatImageType::New();
//     sourceImage->SetRegions(ITKHelpers::CornerRegion(targetRegion.GetSize()));
//     sourceImage->Allocate();
    ITKHelpers::ExtractRegion(magnitudeFilter->GetOutput(), targetRegion, targetImage.GetPointer());

    std::vector<itk::Index<2> > validIndices = ITKHelpers::OffsetsToIndices(validOffsets);

    VarianceFunctor varianceFunctor;
    AverageFunctor averageFunctor;
    /////////// Target region //////////
    std::vector<FloatImageType::PixelType> validPixelsTargetRegion = ITKHelpers::GetPixelValues(targetImage.GetPointer(), validIndices);
    typename TypeTraits<FloatImageType::PixelType>::LargerType targetMean = averageFunctor(validPixelsTargetRegion);
    typename TypeTraits<FloatImageType::PixelType>::LargerType targetStandardDeviation = sqrt(varianceFunctor(validPixelsTargetRegion));

    typedef itk::AddImageFilter <FloatImageType, FloatImageType, FloatImageType> AddImageFilterType;
    AddImageFilterType::Pointer targetAddImageFilter = AddImageFilterType::New();
    targetAddImageFilter->SetInput(targetImage);
    targetAddImageFilter->SetConstant2(-1.0f * targetMean);
    targetAddImageFilter->Update();

    typedef itk::MultiplyImageFilter<FloatImageType, FloatImageType, FloatImageType> MultiplyImageFilterType;
    MultiplyImageFilterType::Pointer targetMultiplyImageFilter = MultiplyImageFilterType::New();
    targetMultiplyImageFilter->SetInput(targetImage);
    targetMultiplyImageFilter->SetConstant(1.0f/targetStandardDeviation);
    targetMultiplyImageFilter->Update();

    /////////// Source region //////////
    std::vector<FloatImageType::PixelType> validPixelsSourceRegion = ITKHelpers::GetPixelValues(sourceImage.GetPointer(), validIndices);
    typename TypeTraits<FloatImageType::PixelType>::LargerType sourceMean = averageFunctor(validPixelsSourceRegion);
    typename TypeTraits<FloatImageType::PixelType>::LargerType sourceStandardDeviation = sqrt(varianceFunctor(validPixelsSourceRegion));

    AddImageFilterType::Pointer sourceAddImageFilter = AddImageFilterType::New();
    sourceAddImageFilter->SetInput(sourceImage);
    sourceAddImageFilter->SetConstant2(-1.0f * sourceMean);
    sourceAddImageFilter->Update();

    MultiplyImageFilterType::Pointer sourceMultiplyImageFilter = MultiplyImageFilterType::New();
    sourceMultiplyImageFilter->SetInput(sourceImage);
    sourceMultiplyImageFilter->SetConstant(1.0f/sourceStandardDeviation);
    sourceMultiplyImageFilter->Update();

    // Initialize
    computedEnergy = 0.0f;
    
    for(std::vector<itk::Index<2> >::const_iterator iter = validIndices.begin(); iter != validIndices.end(); ++iter)
    {
      computedEnergy += (sourceMultiplyImageFilter->GetOutput()->GetPixel(*iter) * targetMultiplyImageFilter->GetOutput()->GetPixel(*iter));
    }

    computedEnergy /= static_cast<float>(validIndices.size());

    if(computedEnergy < Threshold)
      {
      std::cout << this->VisitorName << ": Match accepted (" << computedEnergy << " is less than " << Threshold << ")" << std::endl << std::endl;
      return true;
      }
    else
      {
      std::cout << this->VisitorName << ": Match rejected (" << computedEnergy << " is greater than " << Threshold << ")" << std::endl << std::endl;
      return false;
      }
  };