public int MaximumDepthOfField(Point view) { var result = Math.Min( MathCV.Min( view.X, Math.Abs(ViewColumns - view.X), view.Y, Math.Abs(ViewRows - view.Y) ), DEPTH_OF_FIELD_MAX ); Debug.Assert(result >= 0, "There are some blurred image"); return(result); }
/// <summary> /// Creates a deblur filter from three channel in frequency domain. /// </summary> /// <param name="c0Freqz">channel 0 in frequency domain</param> /// <param name="c1Freqz">channel 1 in frequency domain</param> /// <param name="c2Freqz">channel 2 in frequency domain</param> /// <param name="normalize"> /// if true, each pixel c_n with 0 < n < N-1 will be divided by 1/sum|c_n|, c_0 will be set /// to 1+j0 /// </param> /// <returns></returns> public static DeblurFilter CreateFromFrequencies(Complex2D c0Freqz, Complex2D c1Freqz, Complex2D c2Freqz, bool normalize = false) { var w = MathCV.Max(c0Freqz.Width, c1Freqz.Width, c2Freqz.Width); var h = MathCV.Max(c0Freqz.Height, c1Freqz.Height, c2Freqz.Height); var result = new DeblurFilter { C0 = c0Freqz.Width != w || c0Freqz.Height != h?DoScale(c0Freqz, w, h) : new Complex2D(c0Freqz), C1 = c1Freqz.Width != w || c1Freqz.Height != h?DoScale(c1Freqz, w, h) : new Complex2D(c1Freqz), C2 = c2Freqz.Width != w || c2Freqz.Height != h?DoScale(c2Freqz, w, h) : new Complex2D(c2Freqz) }; if (!normalize) { return(result); } var n = w * h; var d0 = result.C0.Data; var d1 = result.C1.Data; var d2 = result.C2.Data; var norm0 = (n - 1) / (d0.SumAbs() - d0[0].Magnitude); var norm1 = (n - 1) / (d1.SumAbs() - d1[0].Magnitude); var norm2 = (n - 1) / (d2.SumAbs() - d2[0].Magnitude); d0[0] = d1[0] = d2[0] = Complex.One; for (var i = 1; i < n; i++) { d0[i] *= norm0; d1[i] *= norm1; d2[i] *= norm2; } return(result); }
public static double[,] GetGaussian2D(int size, double alpha = 2.5) { var gaus1D = new double[size]; var mu = size / 2; var b = (-alpha * alpha) / (size * mu); for (var i = 0; i < size; i++) { gaus1D[i] = Math.Exp(b * MathCV.Pow2(i - mu)); } var result = new double[size, size]; for (var j = 0; j < size; j++) { var val = gaus1D[j]; for (var i = 0; i < size; i++) { result[i, j] = gaus1D[i] * val; } } return(result); }
/// <summary> /// Codes a image using the light field based on the given parameters. /// </summary> /// <param name="parameter"> /// <see cref="LightfieldParam" /> /// </param> /// <returns></returns> public unsafe UnmanagedImage GetUnmanagedImage(LightfieldParam parameter) { var lightFieldSize = ViewRows * ViewColumns; if (lightFieldSize == 0) { return(null); } var doField = Math.Min(MaximumDepthOfField(parameter.ViewPoint), parameter.DepthOfField); var focusPoint = parameter.ViewPoint; if (focusPoint == default) { focusPoint = ViewPoint; } var doFocus = parameter.DepthOfFocus; var x0Focus = Math.Min(Math.Max(focusPoint.X, doField), ViewColumns - doField - 1); var y0Focus = Math.Min(Math.Max(focusPoint.Y, doField), ViewRows - doField - 1); var nLightFields = MathCV.Pow2(doField + doField + 1); var invNormLightFields = 1 / (float)nLightFields; var img = DoGetUnmanImage(x0Focus, y0Focus); if (img == null) { return(null); } var format = img.PixelFormat; var h = img.Height; var s = img.Stride; var n = s * h; var dt = (byte *)img.ImageData; Preferences.Supported.CheckFormat(format); var dxFocus = doFocus; var dyFocus = parameter.InvertFocus ? -doFocus : doFocus; var sumData = new float[img.Stride * h]; for (var i = 0; i < sumData.Length; i++) { sumData[i] = dt[i] * invNormLightFields; } var result = UnmanagedImage.Create(img.Width, img.Height, format); dt = (byte *)result.ImageData; var xMax = x0Focus + doField; var yMin = y0Focus - doField; var yMax = y0Focus + doField; for (var x = x0Focus - doField; x <= xMax; x++) { for (var y = yMin; y <= yMax; y++) { if (x == x0Focus && y == y0Focus) { continue; } var view = DoGetUnmanImage(x, y); if (view == null) { return(null); } if (view.PixelFormat != format) { throw new BadImageFormatException(nameof(view)); } try { IntegrateImage( view, sumData, dxFocus * (x - x0Focus), dyFocus * (y - y0Focus), invNormLightFields ); } catch (OperationCanceledException) { return(null); } } } for (var i = 0; i < n; i++) { dt[i] = sumData[i].ClampToByte(); } // throw new NotSupportedException("Not tested use of (float).LimitToByte(), or is (float).ToBase256() correct?"); return(result); }
public void Rearrange(int f1X, int f1Y, int phi1, int phi2, int nAngles) { CheckImages(); /* Size of captured image */ _m = MathCV.OddFloor(_fft.Width); _n = MathCV.OddFloor(_fft.Height); const double f1Xd = 237; // f1x <= 0 ? (double)m / (double)nAngles : f1x; const double f1Yd = 191; // f1y <= 0 ? (double)n / (double)nAngles : f1y; F1X = (int)f1Xd; F1Y = (int)f1Yd; NAngles = nAngles % 2 != 0 ? nAngles : NAngles > nAngles ? --nAngles : ++nAngles; CAngles = nAngles / 2; Phi1 = phi1; Phi2 = phi2; var phi1Rad = (phi1 * Math.PI) / 180; var phi2Rad = (phi2 * Math.PI) / 180; var k = Complex.Sqrt(-1); var kphi1Rad = phi1Rad * k; var kphi2Rad = phi2Rad * k; var f12Y = F1Y / 2; var f12X = F1X / 2; /* compute spectral tile centers, peak strengths und phase */ var centX = new int[nAngles]; var centY = new int[nAngles]; //Complex[,] Mat = new Complex[nAngles, nAngles]; var m = (_m >> 1) - (CAngles * f1Xd); var n = (_n >> 1) - (CAngles * f1Yd); for (var i = 0; i < nAngles; i++) { centX[i] = (int)(m + (i * f1Xd)); centY[i] = (int)(n + (i * f1Yd)); } var f = new ComplexImage(_fft); f.FFTShift(); /* fft zentrieren */ /* Rearrange tiles of 2D fft into 4d planes to obtain fft of 4d lightfield */ _fftLightField = new ComplexImage4D(F1X, F1Y, nAngles, nAngles); var data1 = f.Channel0; var data2 = f.Channel1; var data3 = f.Channel2; var w = f.Width; for (var y = 0; y < F1Y; y++) { var isYcAngles = y == CAngles; for (var x = 0; x < F1X; x++) { var rField = _fftLightField.R[x, y]; var gField = _fftLightField.G[x, y]; var bField = _fftLightField.B[x, y]; var factor = 1.0 / (isYcAngles && x == CAngles ? 20 : 1); for (var j = 0; j < nAngles; j++) { var iCh0 = ((((centY[j] + y) - f12Y) * w) + x) - f12X; for (var i = 0; i < nAngles; i++) { var iCh = iCh0 + centX[i]; rField[i, j] = data1[iCh] * factor; gField[i, j] = data2[iCh] * factor; bField[i, j] = data3[iCh] * factor; } } } } for (var x = 0; x < F1X; x++) { for (var y = 0; y < F1Y; y++) { var rField = _fftLightField.R[x, y]; var gField = _fftLightField.G[x, y]; var bField = _fftLightField.B[x, y]; for (var i = 0; i < nAngles; i++) { var cAngle1 = kphi1Rad * (i - CAngles); for (var j = 0; j < nAngles; j++) { var factor = Complex.Exp(cAngle1 + (kphi2Rad * (j - CAngles))); rField[i, j] *= factor; gField[i, j] *= factor; bField[i, j] *= factor; } } } } }