예제 #1
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;
   }
}
예제 #2
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;
   }
}
예제 #3
0
bool ReadPgmFromZipFileTest()
{
   std::string zipName = std::string("/u/frooms/research/develop/stira-env/stira/testdata/testZipFile.zip");

   std::string imageInZipName = std::string("CropOrig-2033.pgm");

   ArrayGrid<int>* pGrid = ImageIO::ReadPGMfromZip( zipName, imageInZipName );

   cout << "Image from zip: width = " << pGrid->GetWidth() << " height = " << pGrid->GetHeight() << endl << flush;

   ImageIO::WritePGM( pGrid, std::string("ImageFromZip.pgm") );
   delete pGrid;
   return true;
}
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;
}
예제 #5
0
image::ArrayGrid<double>* MedianFilter::RunMedian( image::ArrayGrid<double>* pGridIn, int size)
{
   int windowWidth = 2 * size + 1;
   int windowArea  = windowWidth * windowWidth;
   int medianPosition = (int)(windowArea / 2);

   int width = pGridIn->GetWidth();
   int height = pGridIn->GetHeight();

   double* pR = new double[windowArea];

   ArrayGrid<double>* pGridOut = pGridIn->Clone();
   //cout << "Input grid has width " << pGridIn->GetWidth() << " and height " << pGridIn->GetHeight() << endl;

   for (int y = size; y < height-size; y++)
   {
      for (int x = size; x < width - size; x ++)
      {
         int index=0;
         for (int s = -size; s <= size; s++)
         {
            for (int t = -size; t <= size; t++)
            {
               pR[index] = pGridIn->GetValue( x+s, y+t );
               index++;
            }
         }
         qsort( pR, windowArea, sizeof(double), MathUtils::CompareDoubles );
         pGridOut->SetValue( x, y, pR[medianPosition] );
      }
   }

   delete [] pR;
   cout << "Output grid has width " << pGridOut->GetWidth() << " and height " << pGridOut-> GetHeight() << endl;
   return pGridOut;
}
예제 #6
0
ArrayGrid<double>* PyramidBurtAdelson::DecomposeSingleScale( ArrayGrid<double>* pGridIn, int scale )
{
    // smoothened input
    ArrayGrid<double>* pLowpassTmp = mSeparableFilter->RunRowColumn( pGridIn, pH, pH, 5, 5 );

    // smoothened and downsampled input
    ArrayGrid<double>* pNextLowpass = ArrayGridTools<double>::DownSampleGrid( pLowpassTmp );
    delete pLowpassTmp;

    // upsample again to subtract from original input
    int currentScaleWidth = pNextLowpass->GetWidth();
    int currentScaleHeight = pNextLowpass->GetHeight();

    ArrayGrid<double>* pUpscaleTmp = ArrayGridTools<double>::UpSampleGrid( pNextLowpass, currentScaleWidth * 2, currentScaleHeight * 2 );
    ArrayGrid<double>* pUpscale2 = mSeparableFilter->RunRowColumn( pUpscaleTmp, pH, pH, 5, 5 );
    delete pUpscaleTmp;

    pGridIn->SubtractGrid(pUpscale2);
    delete pUpscale2;

    mpPyramid->GetRecursiveScale( scale )->AddOrientedBand( pGridIn );

    return pNextLowpass;
}
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;
}