Example #1
0
        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);
        }
Example #2
0
        /// <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 &lt; n &lt; 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);
        }
Example #3
0
        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);
        }
Example #4
0
        /// <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;
                        }
                    }
                }
            }
        }