Example #1
0
        /// <summary>
        /// Двумерное обратное быстрое преобразование фурье
        /// </summary>
        /// <param name="source">входная матрица</param>
        /// <param name="height">The height.</param>
        /// <param name="width">The width.</param>
        /// <returns>
        /// Выходной ряд
        /// </returns>
        public static Complex[,] IFastTransform(Complex[,] source, int height, int width)
        {
            if (source.GetLength(0) != source.GetLength(1))
            {
                return(null);
            }
            int size = source.GetLength(0);


            Complex[,] outC = new Complex[size, size];

            //преобразуем столбцы
            for (int i = 0; i < size; i++) //проходим по столбцам
            {
                Complex[] raw = new Complex[size];
                for (int j = 0; j < size; j++) //проходим внутри столбца, собирая его
                {
                    raw[j] = source[j, i];
                }
                raw = Fourier.IFastTransform(raw); //получаем фурье образ столбца
                for (int j = 0; j < size; j++)     //записываем его в массив
                {
                    outC[j, i] = raw[j];
                }
            }

            //преобразуем строки
            for (int i = 0; i < size; i++) //проходим по строкам
            {
                Complex[] str = new Complex[size];
                for (int j = 0; j < size; j++) //проходим внутри строки, собирая её
                {
                    str[j] = outC[i, j];
                }
                str = Fourier.IFastTransform(str); //получаем фурье образ строки
                for (int j = 0; j < size; j++)     //записываем его в массив
                {
                    outC[i, j] = str[j];
                }
            }

            Complex[,] value = new Complex[height, width];

            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    value[i, j] = outC[i, j];
                }
            }
            return(value);
        }
        /// <summary>
        /// Конволюция (свёртка) в частотной области
        /// </summary>
        /// <param name="sourceImage">исходное изображение</param>
        /// <returns>искаженное изображение</returns>
        public Image FastConvolution(Image sourceImage)
        {
            int   height         = sourceImage.Height;
            int   width          = sourceImage.Width;
            int   filterSize     = this.filterMatrix.GetLength(0); //размер PSF
            int   filterHalfSize = (filterSize - 1) / 2 + 1;       //центр PSF
            Image expandedImage  = sourceImage.Expand(filterHalfSize);
            int   expHeight      = expandedImage.Height;
            int   expWidth       = expandedImage.Width;

            double[] image = Converter.ToDoubleArray(expandedImage);
            double[,] red   = new double[expHeight, expWidth];
            double[,] green = new double[expHeight, expWidth];
            double[,] blue  = new double[expHeight, expWidth];
            int index = 0;

            for (int i = 0; i < expHeight; i++)
            {
                for (int j = 0; j < expWidth; j++)
                {
                    blue[i, j]  = image[index];
                    green[i, j] = image[index + 1];
                    red[i, j]   = image[index + 2];
                    index      += 4;
                }
            }

            Complex[,] redFourier   = Fourier.FastTransform(Converter.ToComplexMatrix(red));
            Complex[,] greenFourier = Fourier.FastTransform(Converter.ToComplexMatrix(green));
            Complex[,] blueFourier  = Fourier.FastTransform(Converter.ToComplexMatrix(blue));
            int newSize = redFourier.GetLength(0);

            double[,] kernel         = this.ExpendedByZero(newSize);
            Complex[,] kernelFourier = Fourier.FastTransform(Converter.ToComplexMatrix(kernel));
            for (int u = 0; u < newSize; u++)
            {
                for (int v = 0; v < newSize; v++)
                {
                    redFourier[u, v]   *= kernelFourier[u, v];
                    greenFourier[u, v] *= kernelFourier[u, v];
                    blueFourier[u, v]  *= kernelFourier[u, v];
                }
            }
            Complex[,] newRed   = Fourier.IFastTransform(redFourier, expHeight, expWidth);
            Complex[,] newGreen = Fourier.IFastTransform(greenFourier, expHeight, expWidth);
            Complex[,] newBlue  = Fourier.IFastTransform(blueFourier, expHeight, expWidth);

            Complex[,] resRed   = new Complex[height, width];
            Complex[,] resGreen = new Complex[height, width];
            Complex[,] resBlue  = new Complex[height, width];
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    resRed[i, j]   = Math.Round(newRed[i + filterHalfSize + 1, j + filterHalfSize + 1].Real);
                    resGreen[i, j] = Math.Round(newGreen[i + filterHalfSize + 1, j + filterHalfSize + 1].Real);
                    resBlue[i, j]  = Math.Round(newBlue[i + filterHalfSize + 1, j + filterHalfSize + 1].Real);
                }
            }
            Image result = Converter.ToImage(resRed, resGreen, resBlue);

            return(result);
        }