Beispiel #1
0
        public static Bitmap fft2dRGB(Bitmap input, bool reorder)
        {
            int width  = input.Width;
            int height = input.Height;

            ImageUtils.RGB[] data = ImageUtils.SplitColorChannels(input);
            Complex[,] cmplxR = new Complex[height, width];
            Complex[,] cmplxG = new Complex[height, width];
            Complex[,] cmplxB = new Complex[height, width];
            double scale = 1.0 / (double)Math.Sqrt(width * height);

            for (int i = 0; i < data.Length; i++)
            {
                cmplxR[i / width, i % width] = new Complex(data[i].r / 256.0);
                cmplxG[i / width, i % width] = new Complex(data[i].g / 256.0);
                cmplxB[i / width, i % width] = new Complex(data[i].b / 256.0);
            }

            cmplxR = fft2d(cmplxR);
            cmplxG = fft2d(cmplxG);
            cmplxB = fft2d(cmplxB);

            for (int i = 0; i < data.Length; i++)
            {
                data[i].r = (byte)Math.Min(255, (int)(cmplxR[i / width, i % width].GetModulus() * 256.0) * scale);
                data[i].g = (byte)Math.Min(255, (int)(cmplxG[i / width, i % width].GetModulus() * 256.0) * scale);
                data[i].b = (byte)Math.Min(255, (int)(cmplxB[i / width, i % width].GetModulus() * 256.0) * scale);
            }

            // Swapping data -> lowest frequencies at center
            if (reorder)
            {
                for (int i = 0; i < height / 2; i++)
                {
                    for (int k = 0; k < width / 2; k++)
                    {
                        ImageUtils.RGB val1 = data[i * width + k];
                        ImageUtils.RGB val2 = data[i * width + k + width / 2];
                        data[i * width + k] = data[(i + width / 2) * width + k + width / 2];
                        data[(i + width / 2) * width + k + width / 2] = val1;
                        data[i * width + k + width / 2]   = data[(i + width / 2) * width + k];
                        data[(i + width / 2) * width + k] = val2;
                    }
                }
            }

            Bitmap output = ImageUtils.GetBitmap(ImageUtils.CombineColorChannels(data), input.PixelFormat, width, height);

            return(output);
        }
Beispiel #2
0
        public static Bitmap ifft2dRGB(Bitmap input)
        {
            int width  = (int)Math.Pow(2, Math.Ceiling(Math.Log(input.Width, 2)));
            int height = (int)Math.Pow(2, Math.Ceiling(Math.Log(input.Width, 2)));

            ImageUtils.RGB[] data = ImageUtils.SplitColorChannels(input);

            if (width != input.Width || height != input.Height)
            {
                // Pad data
                ImageUtils.RGB[] newdata = new ImageUtils.RGB[width * height];
                int xoff = width - input.Width;
                int yoff = height - input.Height;
                for (int i = 0; i < input.Height; i++)
                {
                    for (int k = 0; k < input.Width; k++)
                    {
                        newdata[(i + yoff) * width + k + xoff] = data[i * input.Width + k];
                    }
                }
                data = newdata;
            }

            Complex[,] cmplxR = new Complex[height, width];
            Complex[,] cmplxG = new Complex[height, width];
            Complex[,] cmplxB = new Complex[height, width];

            double scale = 1.0 / (double)Math.Sqrt(width * height);

            scale = 1;

            for (int i = 0; i < data.Length; i++)
            {
                cmplxR[i / width, i % width] = new Complex(data[i].r / 256.0);
                cmplxG[i / width, i % width] = new Complex(data[i].g / 256.0);
                cmplxB[i / width, i % width] = new Complex(data[i].b / 256.0);
            }

            cmplxR = ifft2d(cmplxR);
            cmplxG = ifft2d(cmplxG);
            cmplxB = ifft2d(cmplxB);

            for (int i = 0; i < height; i++)
            {
                for (int k = 0; k < width; k++)
                {
                    if (((k + i) & 0x1) != 0)
                    {
                        cmplxR[i, k] *= -1;
                        cmplxG[i, k] *= -1;
                        cmplxB[i, k] *= -1;
                    }
                }
            }

            for (int i = 0; i < data.Length; i++)
            {
                data[i].r = (byte)Math.Min(255, (int)(cmplxR[i / width, i % width].GetModulus() * 256.0 * scale));
                data[i].g = (byte)Math.Min(255, (int)(cmplxG[i / width, i % width].GetModulus() * 256.0 * scale));
                data[i].b = (byte)Math.Min(255, (int)(cmplxB[i / width, i % width].GetModulus() * 256.0 * scale));
            }

            Bitmap output = ImageUtils.GetBitmap(ImageUtils.CombineColorChannels(data), input.PixelFormat, width, height);

            return(output);
        }
Beispiel #3
0
        public static Bitmap ifft2dRGB(Bitmap input)
        {
            int width = (int)Math.Pow(2, Math.Ceiling(Math.Log(input.Width, 2)));
            int height = (int)Math.Pow(2, Math.Ceiling(Math.Log(input.Width, 2)));
            ImageUtils.RGB[] data = ImageUtils.SplitColorChannels(input);

            if (width != input.Width || height != input.Height)
            {
                // Pad data
                ImageUtils.RGB[] newdata = new ImageUtils.RGB[width * height];
                int xoff = width - input.Width;
                int yoff = height - input.Height;
                for (int i = 0; i < input.Height; i++)
                {
                    for (int k = 0; k < input.Width; k++)
                    {
                        newdata[(i + yoff) * width + k + xoff] = data[i * input.Width + k];
                    }
                }
                data = newdata;
            }

            Complex[,] cmplxR = new Complex[height, width];
            Complex[,] cmplxG = new Complex[height, width];
            Complex[,] cmplxB = new Complex[height, width];

            double scale = 1.0 / (double)Math.Sqrt(width * height);
            scale = 1;

            for (int i = 0; i < data.Length; i++)
            {
                cmplxR[i / width, i % width] = new Complex(data[i].r / 256.0);
                cmplxG[i / width, i % width] = new Complex(data[i].g / 256.0);
                cmplxB[i / width, i % width] = new Complex(data[i].b / 256.0);
            }

            cmplxR = ifft2d(cmplxR);
            cmplxG = ifft2d(cmplxG);
            cmplxB = ifft2d(cmplxB);

            for (int i = 0; i < height; i++)
            {
                for (int k = 0; k < width; k++)
                {
                    if (((k + i) & 0x1) != 0)
                    {
                        cmplxR[i, k] *= -1;
                        cmplxG[i, k] *= -1;
                        cmplxB[i, k] *= -1;
                    }
                }
            }

            for (int i = 0; i < data.Length; i++)
            {
                data[i].r = (byte)Math.Min(255, (int)(cmplxR[i / width, i % width].GetModulus() * 256.0 * scale));
                data[i].g = (byte)Math.Min(255, (int)(cmplxG[i / width, i % width].GetModulus() * 256.0 * scale));
                data[i].b = (byte)Math.Min(255, (int)(cmplxB[i / width, i % width].GetModulus() * 256.0 * scale));
            }

            Bitmap output = ImageUtils.GetBitmap(ImageUtils.CombineColorChannels(data), input.PixelFormat, width, height);
            return output;
        }