Example #1
0
        /// <summary>
        /// Calculates the fast fourier transform of the image.
        /// </summary>
        /// <param name="image">The image to get calculate the FFT from.</param>
        /// <param name="shiftAxes">Whether to perform FFTShift on the Fourier image.</param>
        /// <param name="ignoreAlpha">Whether to ignore the alpha component of the image (if it is 32-bit).</param>
        /// <param name="disposeImage">Whether to dispose the image after use.</param>
        /// <param name="targetWidth">The height to resize the kernel to, or -1 to leave kernel same width. Can only be larger than the kernel width.</param>
        /// <param name="targetHeight">The height to resize the kernel to, or -1 to leave kernel same height. Can only be larger than the kernel height.</param>
        public FourierWorker(PixelWorker image, bool shiftAxes = true, bool ignoreAlpha = false, bool disposeImage = false, int targetWidth = -1, int targetHeight = -1)
        {
            if (image == null)
            {
                return;
            }
            int componentCount = image.ComponentCount, targetPixelCount = image.PixelCount;

            if (ignoreAlpha && componentCount == 4)
            {
                componentCount = 3;
                alphaReference = image;
                alphaReference.ShallowClone();
            }
            values                     = new ComplexF[componentCount][];
            ComponentCount             = componentCount;
            TargetWidth                = image.Width;
            TargetHeight               = image.Height;
            TargetPixelCount           = image.PixelCount;
            TargetPixelComponentCount  = image.PixelComponentCount;
            TargetSize                 = new Size(TargetWidth, TargetHeight);
            FourierWidth               = (int)Maths.CeilingPowerOfTwo((uint)(targetWidth <= TargetWidth ? TargetWidth : targetWidth));
            FourierHeight              = (int)Maths.CeilingPowerOfTwo((uint)(targetHeight <= TargetHeight ? TargetHeight : targetHeight));
            FourierSize                = new Size(FourierWidth, FourierHeight);
            FourierPixelCount          = FourierWidth * FourierHeight;
            FourierPixelComponentCount = FourierPixelCount * ComponentCount;
            fourierWidthLog2           = Maths.Log2((uint)FourierWidth);
            fourierHeightLog2          = Maths.Log2((uint)FourierHeight);
            ComplexF[] current;
            byte       comp;
            int        c, x = 0, y = 0, fourierWidth = FourierWidth, fourierHeight = FourierHeight, tw = TargetWidth;
            int        tcc = image.ComponentCount, txMinusOne = TargetWidth - 1, tyMinusOne = TargetHeight - 1;

            for (c = 0; c < componentCount; c++)
            {
                current   = new ComplexF[FourierPixelCount];
                values[c] = current;
                for (y = 0; y < fourierHeight; y++)
                {
                    for (x = 0; x < fourierWidth; x++)
                    {
                        comp = image.GetPixelBgra((Math.Min(y, tyMinusOne) * tw + Math.Min(x, txMinusOne)) * tcc)[c];
                        if (comp > OriginalMax)
                        {
                            OriginalMax = comp;
                        }
                        current[y * fourierWidth + x] = new ComplexF()
                        {
                            Real = comp,
                        };
                    }
                }
            }
            NormalizationCap = OriginalMax;
            FFT(true);
            if (shiftAxes)
            {
                ShiftAxes = true;
                FFTShift();
            }
            if (disposeImage)
            {
                image.Dispose();
            }
        }