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

我试图实现以下FFTfilter内核:

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

源代码

public partial class Form1 : Form { public Form1() { InitializeComponent(); Bitmap image = DataConverter2d.ReadGray(StandardImage.LenaGray); Array2d 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 kernel2d = CustomFft(newWidth, newHeight, n, f0, theta, a); dImage.PadTo(newWidth, newHeight); Array2d cImage = DataConverter2d.ToComplex(dImage); Array2d fImage = FourierTransform.ForwardFft(cImage); // FFT convolution ................................................. Array2d fOutput = new Array2d(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 cOutput = FourierTransform.InverseFft(fOutput); Array2d dOutput = Rescale2d.Rescale(DataConverter2d.ToDouble(cOutput)); dOutput.CropBy((newWidth - image.Width) / 2, (newHeight - image.Height) / 2); Bitmap output = DataConverter2d.ToBitmap(dOutput, image.PixelFormat); Array2d cKernel = FourierTransform.InverseFft(kernel2d); cKernel = FourierTransform.RemoveFFTShift(cKernel); Array2d dKernel = DataConverter2d.ToDouble(cKernel); Array2d 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 CustomFft(double sizeX, double sizeY, double n, double f0, double theta, double a) { double halfX = sizeX / 2; double halfY = sizeY / 2; Array2d kernel = new Array2d((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; } } 

此时只关注算法和公式。

产量

在此处输入图像描述

这个filter的问题是,它只能在0-90度之间旋转,并且不能在该范围之外工作。

如何让它旋转0-360度之间的任何角度?

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