private static void UpdateB(double[,] b, double[,] bUpdate, Common.Rectangle imageSection, int yPixel, int xPixel, double xDiff) { var yBHalf = bUpdate.GetLength(0) / 2; var xBHalf = bUpdate.GetLength(1) / 2; var yBMin = Math.Max(yPixel - yBHalf, imageSection.Y); var xBMin = Math.Max(xPixel - xBHalf, imageSection.X); var yBMax = Math.Min(yPixel - yBHalf + bUpdate.GetLength(0), imageSection.YEnd); var xBMax = Math.Min(xPixel - xBHalf + bUpdate.GetLength(1), imageSection.XEnd); for (int i = yBMin; i < yBMax; i++) { for (int j = xBMin; j < xBMax; j++) { var yLocal = i - imageSection.Y; var xLocal = j - imageSection.X; var yBUpdate = i + yBHalf - yPixel; var xBUpdate = j + xBHalf - xPixel; b[yLocal, xLocal] += bUpdate[yBUpdate, xBUpdate] * xDiff; } } }
public void Dirty(Common.Rectangle dr) { dobs.Dirty(dr); }
public void Dirty(Common.Rectangle rect) { lock (lock_dirty) dirty.Add(rect); }
public static bool Deconvolve(double[,] xImage, double[,] b, double[,] psf, double lambda, double alpha, int maxIteration = 100, double epsilon = 1e-4) { var yPsfHalf = psf.GetLength(0) / 2; var xPsfHalf = psf.GetLength(1) / 2; var aMap = CommonDeprecated.PSF.CalcAMap(xImage, psf); var imageSection = new Common.Rectangle(0, 0, xImage.GetLength(0), xImage.GetLength(1)); //invert the PSF, since we actually do want to correlate the psf with the residuals. (The FFT already inverts the psf, so we need to invert it again to not invert it. Trust me.) var psfTmp = new double[psf.GetLength(0) + +psf.GetLength(0), psf.GetLength(1) + psf.GetLength(1)]; for (int y = 0; y < psf.GetLength(0); y++) { for (int x = 0; x < psf.GetLength(1); x++) { psfTmp[y + yPsfHalf + 1, x + xPsfHalf + 1] = psf[psf.GetLength(0) - y - 1, psf.GetLength(1) - x - 1]; } } FFT.Shift(psfTmp); var PsfCorr = FFT.Forward(psfTmp, 1.0); psfTmp = new double[psf.GetLength(0) + psf.GetLength(0), psf.GetLength(1) + psf.GetLength(1)]; CommonDeprecated.PSF.SetPSFInWindow(psfTmp, xImage, psf, xImage.GetLength(0) / 2, xImage.GetLength(1) / 2); var tmp = FFT.Forward(psfTmp, 1.0); var tmp2 = Common.Fourier2D.Multiply(tmp, PsfCorr); //cached bUpdate. When the PSF is not masked var bUpdateCache = FFT.Backward(tmp2, (double)(tmp2.GetLength(0) * tmp2.GetLength(1))); //masked psf var maskedPsf = new double[psf.GetLength(0) + +psf.GetLength(0), psf.GetLength(1) + psf.GetLength(1)]; double[,] bUpdateMasked; int iter = 0; bool converged = false; var watch = new System.Diagnostics.Stopwatch(); watch.Start(); while (!converged & iter < maxIteration) { var yPixel = -1; var xPixel = -1; var xMax = 0.0; var xNew = 0.0; for (int y = 0; y < b.GetLength(0); y++) { for (int x = 0; x < b.GetLength(1); x++) { var yLocal = y; var xLocal = x; var currentA = aMap[y, x]; var old = xImage[yLocal, xLocal]; var xTmp = old + b[y, x] / currentA; xTmp = CommonDeprecated.ShrinkElasticNet(xTmp, lambda, alpha); var xDiff = old - xTmp; if (Math.Abs(xDiff) > xMax) { yPixel = y; xPixel = x; xMax = Math.Abs(xDiff); xNew = xTmp; } } } converged = Math.Abs(xMax) < epsilon; if (!converged) { var yLocal2 = yPixel; var xLocal2 = xPixel; var xOld = xImage[yLocal2, xLocal2]; xImage[yLocal2, xLocal2] = xNew; Console.WriteLine(iter + "\t" + (xNew - xOld) + "\t" + yLocal2 + "\t" + xLocal2); if (yPixel - yPsfHalf >= 0 & yPixel + yPsfHalf < xImage.GetLength(0) & xPixel - xPsfHalf >= 0 & xPixel + xPsfHalf < xImage.GetLength(0)) { UpdateB(b, bUpdateCache, imageSection, yPixel, xPixel, xOld - xNew); } else { /*CommonMethods.PSF.SetPSFInWindow(maskedPsf, xImage, psf, yPixel, xPixel); * tmp = FFT.FFTDebug(maskedPsf, 1.0); * tmp2 = Common.Fourier2D.Multiply(tmp, PsfCorr); * bUpdateMasked = FFT.IFFTDebug(tmp2, tmp2.GetLength(0) * tmp2.GetLength(1)); * UpdateB(b, bUpdateMasked, imageSection, yPixel, xPixel, xOld - xNew);*/ UpdateB(b, bUpdateCache, imageSection, yPixel, xPixel, xOld - xNew); } iter++; if (iter == 1000) { //FitsIO.Write(shrinked, "shrinkedReal.fits"); //FitsIO.Write(b, "candidatesGreedy2.fits"); //FitsIO.Write(xImage, "xImageGreedy2.fits"); } } } watch.Stop(); Console.WriteLine(watch.Elapsed); return(converged); }
public static bool Deconvolve(double[,] xImage, double[,] bMap, double[,] psf, double lambda, double alpha, int maxIteration = 100, double epsilon = 1e-4) { bool converged = false; var aMap = CommonDeprecated.PSF.CalcAMap(xImage, psf); var padding = new Rectangle(0, 0, xImage.GetLength(0), xImage.GetLength(1)); var psfCorrelated = PSF.CalcPaddedFourierCorrelation(ToFloatImage(psf), padding); var psf2 = Common.PSF.CalcPSFSquared(ToFloatImage(psf)); var xDiff = new double[xImage.GetLength(0), xImage.GetLength(1)]; var imageSection = new Common.Rectangle(0, 0, xImage.GetLength(0), xImage.GetLength(1)); var rand = new Random(33); var iter = 0; var theta = 1; //2; //theta, also number of processors. var degreeOfSep = CountNonZero(psf); var blockCount = xImage.Length; var beta = 1.0 + (degreeOfSep - 1) * (theta - 1) / (Math.Max(1.0, (blockCount - 1))); //arises from E.S.O of theta-nice sampling /* * Theta-nice sampling := take theta number of random pixels */ var yPsfHalf = psf.GetLength(0) / 2; var xPsfHalf = psf.GetLength(1) / 2; var psfTmp = new double[psf.GetLength(0) + +psf.GetLength(0), psf.GetLength(1) + psf.GetLength(1)]; for (int y = 0; y < psf.GetLength(0); y++) { for (int x = 0; x < psf.GetLength(1); x++) { psfTmp[y + yPsfHalf + 1, x + xPsfHalf + 1] = psf[psf.GetLength(0) - y - 1, psf.GetLength(1) - x - 1]; } } FFT.Shift(psfTmp); var PsfCorr = FFT.Forward(psfTmp, 1.0); psfTmp = new double[psf.GetLength(0) + psf.GetLength(0), psf.GetLength(1) + psf.GetLength(1)]; CommonDeprecated.PSF.SetPSFInWindow(psfTmp, xImage, psf, xImage.GetLength(0) / 2, xImage.GetLength(1) / 2); var tmp = FFT.Forward(psfTmp, 1.0); var tmp2 = Common.Fourier2D.Multiply(tmp, PsfCorr); var pixelAcces = new double[xImage.GetLength(0), xImage.GetLength(1)]; while (!converged & iter < maxIteration) { // create sampling var samples = CreateSamples(xImage.Length, theta, rand); for (int i = 0; i < samples.Length; i++) { var yPixel = samples[i] / xImage.GetLength(1); var xPixel = samples[i] % xImage.GetLength(1); //update with E.S.O //var xDiffPixel = 2.0 * bMap[y, x] / (beta * aMap[y, x]); //update without E.S.O var xDiffPixel = bMap[yPixel, xPixel] / (aMap[yPixel, xPixel]); var old = xImage[yPixel, xPixel]; var xDiffShrink = CommonDeprecated.ShrinkElasticNet(old + xDiffPixel, lambda, alpha); xDiff[yPixel, xPixel] = xDiffShrink; pixelAcces[yPixel, xPixel] += 1; } //update B-map //reset xDiff for (int i = 0; i < samples.Length; i++) { var yPixel = samples[i] / xImage.GetLength(1); var xPixel = samples[i] % xImage.GetLength(1); var bla = xDiff[yPixel, xPixel]; if (bla != 0.0) { if (yPixel - yPsfHalf >= 0 & yPixel + yPsfHalf < xImage.GetLength(0) & xPixel - xPsfHalf >= 0 & xPixel + xPsfHalf < xImage.GetLength(0)) { UpdateB(bMap, psf2, imageSection, yPixel, xPixel, -xDiff[yPixel, xPixel]); } else { CommonDeprecated.PSF.SetPSFInWindow(psfTmp, xImage, psf, yPixel, xPixel); tmp = FFT.Forward(psfTmp, 1.0); tmp2 = Common.Fourier2D.Multiply(tmp, PsfCorr); var bUpdateMasked = FFT.Backward(tmp2, tmp2.GetLength(0) * tmp2.GetLength(1)); UpdateB(bMap, Common.ToFloatImage(bUpdateMasked), imageSection, yPixel, xPixel, -xDiff[yPixel, xPixel]); } xImage[yPixel, xPixel] += xDiff[yPixel, xPixel]; xDiff[yPixel, xPixel] = 0; Console.WriteLine("iter " + iter + " y " + yPixel + " x " + xPixel + " val " + bla); } Console.WriteLine("iter " + iter); } iter++; } FitsIO.Write(pixelAcces, "pixelAccess.fits"); return(converged); }