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