Esempio n. 1
0
void PyramidDenoiser::DenoiseLevelBivariate(int level)
{
   if (level < (int)(mpPyramid->GetNumberOfScales() - 1))
   {
      PyramidLevel<double>* pBandSetCurrent;
      PyramidLevel<double>* pBandSetParent;
      if (level != -1)
      {
         pBandSetCurrent = mpPyramid->GetRecursiveScale(level);
         pBandSetParent = mpPyramid->GetRecursiveScale(level+1);
      }
      else
      {
         pBandSetCurrent = mpPyramid->GetResidualScale();
         pBandSetParent = mpPyramid->GetRecursiveScale(0);
      }

      double avgVariance = 0.0;

      double scaleNoiseVariance = mSigmaNoise / GetScaledNoiseVarianceFactor( level );
      double scaleParentChildFactor = GetScaledParentChildFactor( level);

      for (int orientationIndex = 0; orientationIndex < pBandSetCurrent->GetNumberOfOrientations(); orientationIndex++)
      {
         ArrayGrid<double>* pBandCurrent = pBandSetCurrent->GetOrientedBand( orientationIndex);
         ArrayGrid<double>* pBandParent = pBandSetParent->GetOrientedBand( orientationIndex);

         double meanVal     = GridStatistics<double>::GetGridMean( pBandCurrent );
         double varianceVal = GridStatistics<double>::GetGridVariance( pBandCurrent, meanVal );

         #ifdef DEBUG
         cout << "Denoising level " << level << " and orientationIndex " << orientationIndex
              << ", variance is " << varianceVal << " and scaled noise variance = " << scaleNoiseVariance << endl << flush;
         #endif
         avgVariance += varianceVal;


         for (int y = 0; y < pBandCurrent->GetHeight(); y++)
         {
            for (int x = 0; x < pBandCurrent->GetWidth(); x++)
            {
               double sigmaSignal = EstimateSigmaSignal( pBandCurrent, x, y, mSigmaNoise, mWindowSize );
               double w1 = pBandCurrent->GetValue(x,y);
               double w2 = pBandParent->GetValue(x/2,y/2) / scaleParentChildFactor;
               double shrinkageFactor = ComputeBivariateShrinkagefactor(w1, w2, sigmaSignal, scaleNoiseVariance );
               pBandCurrent->SetValue(x,y, shrinkageFactor * w1);
            }
         }
      }
      #ifdef DEBUG
      cout << "Average variance at scale level = " << (avgVariance) / (double)(pBandSetCurrent->GetNumberOfOrientations())
           << endl << flush;
      #endif
   }
   else
   {
      std::cerr << "PyramidDenoiser::DenoiseLevelBivariate: Cannot denoise level " << level << " since top level is " << mpPyramid->GetNumberOfScales() << std::endl << std::flush;
   }
}
Esempio n. 2
0
void PyramidDenoiser::DenoiseLevelLaplacian(int level)
{
   if (level < (int)(mpPyramid->GetNumberOfScales() - 1))
   {
      PyramidLevel<double>* pBandSet;
      if (level != -1)
      {
         pBandSet = mpPyramid->GetRecursiveScale(level);
      }
      else
      {
         pBandSet = mpPyramid->GetResidualScale();
      }

      for (int orientationIndex = 0; orientationIndex < pBandSet->GetNumberOfOrientations(); orientationIndex++)
      {
         ArrayGrid<double>* pBand = pBandSet->GetOrientedBand( orientationIndex);
         for (int y = 0; y < pBand->GetHeight(); y++)
         {
            for (int x = 0; x < pBand->GetWidth(); x++)
            {
               double sigmaSignal = EstimateSigmaSignal( pBand, x, y, mSigmaNoise, mWindowSize );
               double w1 = pBand->GetValue(x,y);
               double shrinkageFactor = ComputeLaplacianShrinkagefactor(w1, sigmaSignal, mSigmaNoise);
               mpPyramid->GetRecursiveScale( level)->GetOrientedBand( orientationIndex)->SetValue(x,y, shrinkageFactor * w1);
            }
         }
      }
   }
   else
   {
      std::cerr << "PyramidDenoiser::DenoiseLevelLaplacian: Cannot denoise level " << level << " since top level is " << mpPyramid->GetNumberOfScales() << std::endl << std::flush;
   }
}
Esempio n. 3
0
ArrayGrid<double>* WienerDeconvolve::RunSingleband( ArrayGrid<double>* pInGrid, ArrayGrid<double>* pInPSF, double noiseLevel )
{
   int width  = pInGrid->GetWidth();
   int height = pInGrid->GetHeight();

   FFTBand* pFFTInputGrid = new FFTBand( pInGrid );
   FFTBand* pFFTPSFGrid   = new FFTBand( pInPSF );
   FFTBand* pWienerOut    = new FFTBand( pInGrid );
   
   pFFTInputGrid->ApplyForwardTransform();
   pFFTPSFGrid->ApplyForwardTransform();
   
   ArrayGrid<double>* pEstimatedIdealSpectrum = EstimateIdealSpectrum( pFFTInputGrid, pFFTPSFGrid, noiseLevel );
   double fourierNoiseLevel = width * height * noiseLevel * noiseLevel;
   pFFTPSFGrid->Conjugate();
   for (int y = 0; y < height; y++)
   {
      for (int x = 0; x < width; x++)
      {
         complex<double> wienerEstimate = 
                             (   ( pFFTPSFGrid->GetValue(x, y) * pFFTInputGrid->GetValue(x, y) )
                               / (     POWER2( abs( pFFTPSFGrid->GetValue( x, y ) ) )
                                   + ( fourierNoiseLevel / pEstimatedIdealSpectrum->GetValue(x, y) )
                                 )
                             );
         wienerEstimate /= (width * height);
         pWienerOut->SetValue( x, y, wienerEstimate );
      }
   }
   pWienerOut->ApplyInverseTransform();
   
   ArrayGrid<double>* pRestoredGrid = pWienerOut->ConvertToRealGrid();

   delete pEstimatedIdealSpectrum;

   delete pFFTInputGrid;
   delete pFFTPSFGrid;
   delete pWienerOut;
   return pRestoredGrid;
}
Image* AnisotropicDiffusion::Run()
{
   for (int bandNr = 0; bandNr < mpSourceImage->GetNumberOfBands(); bandNr++) 
   {
      cout << "Processing band nr " << bandNr << endl << flush;
      for (int iterationNr = 0; iterationNr < mMaxNumberOfIterations; iterationNr++)
      {
         cout << "\t\t iteration nr " << iterationNr << flush;
         
         ArrayGrid<double>* pPreviousIterationGrid = mpSourceImage->GetBands()[bandNr]->Clone();
         
         double flowConstant = DetermineMeanGradient( pPreviousIterationGrid ) * mFlowFactor;
         cout << "\t\t FlowConstant =  " << flowConstant << endl << flush;
         for (int y = 1; y < mpSourceImage->GetHeight()-1; y++) 
         {
            for (int x=1; x < mpSourceImage->GetWidth()-1 ; x++) 
            {
               double deltaIxu, deltaIxl, deltaIyu, deltaIyl;
               double cxu, cxl, cyu, cyl, deltaI, ttmp;

               deltaIxu = pPreviousIterationGrid->GetValue(x+1, y) - pPreviousIterationGrid->GetValue(x,   y);
               deltaIxl = pPreviousIterationGrid->GetValue(x,   y) - pPreviousIterationGrid->GetValue(x-1, y);
               deltaIyu = pPreviousIterationGrid->GetValue(x, y+1) - pPreviousIterationGrid->GetValue(x, y);
               deltaIyl = pPreviousIterationGrid->GetValue(x, y)   - pPreviousIterationGrid->GetValue(x, y-1);

               cxu = 1.0 / (1.0 + pow( ( abs( deltaIxu) / flowConstant ), (1.8) ) );
               cxl = 1.0 / (1.0 + pow( ( abs( deltaIxl) / flowConstant ), (1.8) ) );
               cyu = 1.0 / (1.0 + pow( ( abs( deltaIyu) / flowConstant ), (1.8) ) );
               cyl = 1.0 / (1.0 + pow( ( abs( deltaIyl) / flowConstant ), (1.8) ) );

               deltaI= (cxu*deltaIxu-cxl*deltaIxl)+(cyu*deltaIyu-cyl*deltaIyl);

               ttmp = pPreviousIterationGrid->GetValue(x,y) + mDeltaT * deltaI;

               mpSourceImage->GetBands()[bandNr]->SetValue(x,y,ttmp);
            } //for x
         }//for y
         delete pPreviousIterationGrid;
      } //for iterationNr
   } // for bandNr
   return mpSourceImage;
}
bool CriticallySubsampledTransform::Reconstruct( double threshold )
{
   ArrayGrid<double>* pRecursiveInput = mpPyramid->GetLowpassResidual( );
   for ( mCurrentScale = mNrScales-1; mCurrentScale >= 0; mCurrentScale-- )
   {
      int width  = pRecursiveInput->GetWidth();
      int height = pRecursiveInput->GetHeight();
      int upScaledWidth  =  width * 2;
      int upScaledHeight = height * 2;
      bool needsInitialisation = true;
      double initialValue = 0.0;

      ArrayGrid<double>* pLLGrid = new ArrayGrid<double>( upScaledWidth, upScaledHeight, needsInitialisation, initialValue );
      for (int y = 0; y < upScaledHeight; y+=2)
      {
         for (int x = 0; x < upScaledWidth; x+=2)
         {
            int halfX = x/2;
            int halfY = y/2;

            double x00 = pRecursiveInput->GetValue( halfX, halfY );
            
            double x01 = mpPyramid->GetRecursiveScale( mCurrentScale )->GetOrientedBand( 0 )->GetValue( halfX, halfY );
            double x10 = mpPyramid->GetRecursiveScale( mCurrentScale )->GetOrientedBand( 1 )->GetValue( halfX, halfY );
            double x11 = mpPyramid->GetRecursiveScale( mCurrentScale )->GetOrientedBand( 2 )->GetValue( halfX, halfY );
            
            pLLGrid->SetValue( x  , y  , (x00 + x01 + x10 + x11) / 2.0 );
            pLLGrid->SetValue( x  , y+1, (x00 + x01 - x10 - x11) / 2.0 );
            pLLGrid->SetValue( x+1, y  , (x00 - x01 + x10 - x11) / 2.0 );
            pLLGrid->SetValue( x+1, y+1, (x00 - x01 - x10 + x11) / 2.0 );
         }
      }
      pRecursiveInput = pLLGrid->Clone(); delete pLLGrid;
   }
   mpDecomposeReconstructGrid = pRecursiveInput;
   return true;
}
Esempio n. 6
0
ArrayGrid<bool>* StegerLineDetector::Run( ArrayGrid<double>* pGridIn, double sigmaSmooth, double lowerThreshold, double higherThreshold, bool isModeLight )
{
   int width = pGridIn->GetWidth();
   int height = pGridIn->GetHeight();
   OrientationGrid* pOrientationGrid = new OrientationGrid(width, height);  // NOT initialized at construction; values are set below
   ArrayGrid<bool>* pLineGrid = new ArrayGrid<bool>(width, height);  // NOT initialized at construction; values are set below
   pLineGrid->SetGridValues( false );
   
   ArrayGrid<double>* pGx  = GaussConvolve::DerivativeConvolveFFT( pGridIn, sigmaSmooth, sigmaSmooth, GaussConvolve::DERIVATIVE_X  );
   ArrayGrid<double>* pGy  = GaussConvolve::DerivativeConvolveFFT( pGridIn, sigmaSmooth, sigmaSmooth, GaussConvolve::DERIVATIVE_Y  );
   ArrayGrid<double>* pGxx = GaussConvolve::DerivativeConvolveFFT( pGridIn, sigmaSmooth, sigmaSmooth, GaussConvolve::DERIVATIVE_XX );
   ArrayGrid<double>* pGyy = GaussConvolve::DerivativeConvolveFFT( pGridIn, sigmaSmooth, sigmaSmooth, GaussConvolve::DERIVATIVE_YY );
   ArrayGrid<double>* pGxy = GaussConvolve::DerivativeConvolveFFT( pGridIn, sigmaSmooth, sigmaSmooth, GaussConvolve::DERIVATIVE_XY );
   
   for (int y = 0; y < height; y++)
   {
      for (int x = 0; x < width; x++)
      {
         double eigenValue1, eigenValue2, eigenValue;
         common::Point<double> eigenVector1;
         common::Point<double> eigenVector2;
         
         EigenValueComputation( pGxx->GetValue(x, y), pGyy->GetValue(x, y), pGxy->GetValue(x, y),
                                eigenValue1, eigenValue2, eigenVector1, eigenVector2);

         if (isModeLight == true)
         {
            eigenValue = -eigenValue1;
         }
         else
         {
            eigenValue = eigenValue1;
         }
         
         if (eigenValue > 0.0)
         {
            double n1 = eigenVector1.x;
            double n2 = eigenVector1.y;
            
            double a = pGxx->GetValue(x, y) * n1 * n1 + 2.0 * pGxy->GetValue(x, y) * n1 * n2 + pGyy->GetValue(x, y) * n2 * n2;
            double b = pGx->GetValue(x, y) * n1 + pGy->GetValue(x, y) * n2;
            double linearSolution;
            if ( MathUtils::SolveLinearEquation( a, b, linearSolution ) == true )
            {
               double p1 = linearSolution * n1;
               double p2 = linearSolution * n2;
               if ((fabs (p1) <= EDGE_THRESHOLD) && (fabs (p2) <= EDGE_THRESHOLD))
               {
                  int xx = (int)(x + p1 + 0.5);
                  int yy = (int)(y + p2 + 0.5);
                  if (  (xx >= 0) && (xx < width) && (yy >=0) && (yy < height))
                  {
                     if (eigenValue >= lowerThreshold)
                     {
                        if (eigenValue >= higherThreshold)
                        {
                           pLineGrid->SetValue(xx, yy, true);
                        }
                     }
                     else
                     {
                        pLineGrid->SetValue(xx, yy, false);
                     }
                  }
               }
            }
            
            pOrientationGrid->SetAngle( x, y, MathUtils::ComputeArgument( eigenVector1.x,  eigenVector1.y ) );
            pOrientationGrid->SetMagnitude( x, y, eigenValue1);
         }
      }
   }
   //pOrientationGrid->ExportMagnitudeImage( string("StegerMagnitude.pgm") );
   //pOrientationGrid->ExportOrientationImage( string("StegerOrientation.pgm"), -100000.0 );
   
   delete pGx;
   delete pGy;
   delete pGxx;
   delete pGyy;
   delete pGxy;
   delete pOrientationGrid;
   return pLineGrid;
}
bool CriticallySubsampledTransform::Decompose( image::ArrayGrid<double>* pSourceGrid, int nrScales )
{
   Initialize( pSourceGrid, nrScales );
   
   ArrayGrid<double>* pRecursiveInput = pSourceGrid;

   for ( mCurrentScale = 0; mCurrentScale < mNrScales; mCurrentScale++)
   {
      int width  = pRecursiveInput->GetWidth();
      int height = pRecursiveInput->GetHeight();
      int downScaledWidth  = width / 2;
      int downScaledHeight = height / 2;
      bool needsInitialisation = true;
      double initialValue = 0.0;
      ArrayGrid<double>* pLLGrid = new ArrayGrid<double>( downScaledWidth, downScaledHeight, needsInitialisation, initialValue );
      ArrayGrid<double>* pLHGrid = new ArrayGrid<double>( downScaledWidth, downScaledHeight, needsInitialisation, initialValue );
      ArrayGrid<double>* pHLGrid = new ArrayGrid<double>( downScaledWidth, downScaledHeight, needsInitialisation, initialValue );
      ArrayGrid<double>* pHHGrid = new ArrayGrid<double>( downScaledWidth, downScaledHeight, needsInitialisation, initialValue );
            
      // to be sure that (x+1) and (y+1) won't exceed width and height
      int limitWidth  = (width  / 2 ) * 2;
      int limitHeight = (height / 2 ) * 2;
      
      #ifdef DEBUG
      cout << "Width = " << width << ", height = " << height << endl << flush;
      cout << "limitWidth = " << limitWidth << ", limitHeight = " << limitHeight << endl << flush;
      #endif
      
      for (int y = 0; y < limitHeight; y+=2)
      {
         for (int x = 0; x < limitWidth; x+=2)
         {
            int halfX = x/2;
            int halfY = y/2;
            
            #ifdef DEBUG
            //cout << "Width = " << width << ", height = " << height << endl << flush;
            if ((x+1) > width)  {cout <<  (x+1) << " goes out of bounds." << endl << flush;}
            if ((y+1) > height) {cout <<  (y+1) << " goes out of bounds." << endl << flush;}
            assert ((x+1) < width);
            assert ((y+1) < height);
            #endif
            
            double x00 = pRecursiveInput->GetValue( x,   y   );
            double x01 = pRecursiveInput->GetValue( x,   y+1 );
            double x10 = pRecursiveInput->GetValue( x+1, y   );
            double x11 = pRecursiveInput->GetValue( x+1, y+1 );
            
            pLLGrid->SetValue( halfX, halfY, ( (x00 + x01 + x10 + x11) / 2.0) );
            pLHGrid->SetValue( halfX, halfY, ( (x00 + x01 - x10 - x11) / 2.0) );
            pHLGrid->SetValue( halfX, halfY, ( (x00 - x01 + x10 - x11) / 2.0) );
            pHHGrid->SetValue( halfX, halfY, ( (x00 - x01 - x10 + x11) / 2.0) );
         }
      }
      mpPyramid->GetRecursiveScale( mCurrentScale )->AddOrientedBand( pLHGrid );   // in on index 0
      mpPyramid->GetRecursiveScale( mCurrentScale )->AddOrientedBand( pHLGrid );   // in on index 1
      mpPyramid->GetRecursiveScale( mCurrentScale )->AddOrientedBand( pHHGrid );   // in on index 2

      mpPyramid->SetLowpassResidual( pLLGrid );
      
      pRecursiveInput = mpPyramid->GetLowpassResidual( );
   }
   return true;
}