代码之家  ›  专栏  ›  技术社区  ›  user366312

带通滤波器不能旋转超过90度

  •  7
  • user366312  · 技术社区  · 6 年前

    我试图实现以下FFT过滤器内核:

    此公式在sqrt下缺少两个正方形。

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
    
            Bitmap image = DataConverter2d.ReadGray(StandardImage.LenaGray);
            Array2d<double> dImage = DataConverter2d.ToDouble(image);            
    
            int newWidth = Tools.ToNextPowerOfTwo(dImage.Width) * 2;
            int newHeight = Tools.ToNextPowerOfTwo(dImage.Height) * 2;
    
            double n = 6;
            double f0 = 0.5;
            double theta = 60;
            double a = 0.4;
    
            Array2d<Complex> kernel2d = CustomFft(newWidth, newHeight, n, f0, theta, a);
    
            dImage.PadTo(newWidth, newHeight);
            Array2d<Complex> cImage = DataConverter2d.ToComplex(dImage);
            Array2d<Complex> fImage = FourierTransform.ForwardFft(cImage);
    
            // FFT convolution .................................................
            Array2d<Complex> fOutput = new Array2d<Complex>(newWidth, newHeight);
            for (int x = 0; x < newWidth; x++)
            {
                for (int y = 0; y < newHeight; y++)
                {
                    fOutput[x, y] = fImage[x, y] * kernel2d[x, y];
                }
            }
    
            Array2d<Complex> cOutput = FourierTransform.InverseFft(fOutput);
            Array2d<double> dOutput = Rescale2d.Rescale(DataConverter2d.ToDouble(cOutput));
    
            dOutput.CropBy((newWidth - image.Width) / 2, (newHeight - image.Height) / 2);
    
            Bitmap output = DataConverter2d.ToBitmap(dOutput, image.PixelFormat);
    
            Array2d<Complex> cKernel = FourierTransform.InverseFft(kernel2d);
            cKernel = FourierTransform.RemoveFFTShift(cKernel);
            Array2d<double> dKernel = DataConverter2d.ToDouble(cKernel);
            Array2d<double> dLimitedKernel = Rescale2d.Limit(dKernel);
    
            Bitmap kernel = DataConverter2d.ToBitmap(dLimitedKernel, image.PixelFormat);
    
            pictureBox1.Image = image;
            pictureBox2.Image = kernel;
            pictureBox3.Image = output;
        }
    
        private double Basic(double u, double v, double n, double f0, double rad, double a, double b)
        {
            double ua = u + f0 * Math.Cos(rad);
            double va = v + f0 * Math.Sin(rad);
    
            double ut = ua * Math.Cos(rad) + va * Math.Sin(rad);
            double vt = (-1) * ua * Math.Sin(rad) + va * Math.Cos(rad);
    
            double p = ut/a;
            double q = vt/b;
    
            double sqrt = Math.Sqrt(p*p + q*q);
    
            return 1.0 / (1.0+ 0.414 * Math.Pow(sqrt, 2*n));
        }
    
        private double Custom(double u, double v, double n, double f0, double theta, double a)
        {
            double rad1 = (Math.PI / 180) * (90-theta);
            double rad2 = rad1 + Math.PI;
            double b = (a / 5.0) / (2*n);
    
            double ka = Basic(u, v, n, f0, rad1, a, b);
            double kb = Basic(u, v, n, f0, rad2, a, b);
    
            return Math.Max(ka, kb);
        }
    
        private Array2d<Complex> CustomFft(double sizeX, double sizeY, double n, double f0, double theta, double a)
        {
            double halfX = sizeX / 2;
            double halfY = sizeY / 2;
    
            Array2d<Complex> kernel = new Array2d<Complex>((int)sizeX, (int)sizeY);
    
            for (double y = 0; y < sizeY; y++)
            {
                double v = y / sizeY;
    
                for (double x = 0; x < sizeX; x++)
                {
                    double u = x / sizeX;
    
                    double kw = Custom(u, v, n, f0, theta, a);
    
                    kernel[(int)x, (int)y] = new Complex(kw, 0);
                }
            }
    
            return kernel;
        }
    }
    

    enter image description here

    这个过滤器的问题是,它只能在0-90度之间旋转,不能在这个范围外工作。

    如何使其旋转0-360度之间的任何角度?

    1 回复  |  直到 6 年前
        1
  •  0
  •   Cupcake Protocol    6 年前

    使用无损变换旋转90、180和270,然后将其用于旋转的其余部分。