Ejemplo n.º 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
}
Ejemplo n.º 2
0
// (2*mu+gam)^{-1}
static CVImageType::Pointer ComputeInvTwoMuPlusGamma( FloatImageType::Pointer edgemask,  const PrecisionType gam)
{
  CVImageType::Pointer repMu = CreateEmptyImage<CVImageType>(edgemask);
  itk::ImageRegionIterator<CVImageType> cvIt(repMu,repMu->GetLargestPossibleRegion());
  itk::ImageRegionConstIterator<FloatImageType> muIt(edgemask,edgemask->GetLargestPossibleRegion());
  CVImageType::PixelType temp;
  while(!muIt.IsAtEnd())
  {
    cvIt.Set( 1.0 / ( 2.0*muIt.Value() + gam) );
    ++cvIt;
    ++muIt;
  }
  return repMu;
}
Ejemplo n.º 3
0
int main(int argc, char**argv)
{
	typedef itk::GradientAnisotropicDiffusionImageFilter<FloatImageType, FloatImageType> FilterType;

	if(!file_exists(argv[3]))
	{
		InputImageType::Pointer im = readImage<InputImageType>(argv[1]);

		typedef itk::CastImageFilter<InputImageType,FloatImageType> CastFilter;
		typedef itk::CastImageFilter<FloatImageType,InputImageType> ReverseCastFilter;
		FilterType::Pointer filter = FilterType::New();


		CastFilter::Pointer cfilter = CastFilter::New();
		cfilter->SetInput(im);
		filter->SetInput(cfilter->GetOutput());

		int num_i;
		float time_step;
		float conductance;
		sscanf(argv[2],"%d,%f,%f",&num_i,&time_step,&conductance);
		printf("time_step %f num_i %d conductance %f\n",time_step,num_i,conductance);
		filter->SetTimeStep(time_step);
		filter->SetNumberOfIterations(num_i);
		filter->SetConductanceParameter(conductance);
		filter->Update();

		FloatImageType::Pointer imf = filter->GetOutput();
		typedef itk::ImageRegionIterator<FloatImageType> IRI;
		IRI imageIterator(imf,imf->GetLargestPossibleRegion());
		for(imageIterator.GoToBegin();!imageIterator.IsAtEnd(); ++imageIterator)
		{
			float value = imageIterator.Get();
			value = ((value < 0)?0:((value>255)?255:value));
			imageIterator.Set(value);
		}

		ReverseCastFilter::Pointer rfilter = ReverseCastFilter::New();
		rfilter->SetInput(filter->GetOutput());
		rfilter->Update();
		writeImage<InputImageType>(rfilter->GetOutput(),argv[3]);
	}

	return 0;
}
Ejemplo n.º 4
0
  void TractAnalyzer::MakeRoi()
  {

    m_CostSum = 0.0;

    int n = 0;
    if(m_PointSetNode.IsNotNull())
    {
      n = m_PointSetNode->GetSize();
      if(n==0)
      {
        QMessageBox msgBox;
        msgBox.setText("No points have been set yet.");
        msgBox.exec();
      }
    }
    else{
      QMessageBox msgBox;
      msgBox.setText("No points have been set yet.");
      msgBox.exec();
    }

    std::string pathDescription = "";
    std::vector< itk::Index<3> > totalPath;

    if(n>0)
    {
      for(int i=0; i<n-1; ++i)
      {

        mitk::ProgressBar::GetInstance()->Progress();

        mitk::Point3D p = m_PointSetNode->GetPoint(i);
        mitk::Point3D p2 = m_PointSetNode->GetPoint(i+1);


        itk::Index<3> startPoint;
        itk::Index<3> endPoint;

        m_InputImage->GetGeometry()->WorldToIndex(p,startPoint);
        m_InputImage->GetGeometry()->WorldToIndex(p2,endPoint);

        MITK_INFO << "create roi";

        std::vector< itk::Index<3> > path = CreateSegment(startPoint, endPoint);

        for(std::vector< itk::Index<3> >::iterator it = path.begin();
            it != path.end(); it++)
        {
          itk::Index<3> ix = *it;

          if (!(ix==endPoint))
          {
            mitk::ProgressBar::GetInstance()->Progress();

            totalPath.push_back(ix);
            std::stringstream ss;
            ss << ix[0] << " " << ix[1] << " " << ix[2] << "\n";
            pathDescription += ss.str();
          }
          else
          {
            // Only when dealing with the last segment the last point should be added. This one will not occur
            // as the first point of the next roi segment.
            if(i == (n-2))
            {
              totalPath.push_back(endPoint);
              std::stringstream ss;
              ss << endPoint[0] << " " << endPoint[1] << " " << endPoint[2] << "\n";
              pathDescription += ss.str();
            }

          }

        }

      }


      // save pathDescription to m_PathDescription
      m_PathDescription = pathDescription;

      FloatImageType::Pointer itkImg = FloatImageType::New();
      mitk::CastToItkImage(m_InputImage, itkImg);

      CharImageType::Pointer roiImg = CharImageType::New();
      roiImg->SetRegions(itkImg->GetLargestPossibleRegion().GetSize());
      roiImg->SetOrigin(itkImg->GetOrigin());
      roiImg->SetSpacing(itkImg->GetSpacing());
      roiImg->SetDirection(itkImg->GetDirection());
      roiImg->Allocate();
      roiImg->FillBuffer(0);


      std::vector< itk::Index<3> > roi;

      std::vector< itk::Index<3> >::iterator it;
      for(it = totalPath.begin();
          it != totalPath.end();
          it++)
      {
        itk::Index<3> ix = *it;
        roiImg->SetPixel(ix, 1);
        roi.push_back(ix);
      }


      m_TbssRoi = mitk::TbssRoiImage::New();

      m_TbssRoi->SetRoi(roi);

      m_TbssRoi->SetImage(roiImg);

      m_TbssRoi->InitializeFromImage();



    }



  }
Ejemplo n.º 5
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;
}