Wikipedia给出的Gabor滤波器公式为:
我试图编写follwong C#Console程序,以将Gabor过滤器(由上式给出)应用于图像:
using System;
using Emgu.CV;
using Emgu.CV.Structure;
using System.Drawing;
namespace Gabor
{
public class GaborKernel
{
public int width;
public Matrix<float> real;
public Matrix<float> imaginary;
public GaborKernel(int _width, double lambda, double theta, double psi, double sigma, double gamma) // constructor
{
width = _width;
imaginary = new Matrix<float>(width, width);
real = new Matrix<float>(width, width);
for (int i = 0; i < width; i++)
{
for (int j = 0; j < width; j++)
{
int x = i - width / 2;
int y = j - width / 2;
double x_prime = x * Math.Cos(theta) + y * Math.Sin(theta);
double y_prime = -x * Math.Sin(theta) + y * Math.Cos(theta);
double a = Math.Exp(-(x_prime * x_prime + gamma * gamma * y_prime * y_prime) / (2 * sigma * sigma));
double re = Math.Cos(2 * Math.PI * x_prime / lambda + psi);
double im = Math.Sin(2 * Math.PI * x_prime / lambda + psi);//*/
double real_part = a * re;
double imaginary_part = a * im;
real.Data[i, j] = (float)real_part;
imaginary.Data[i, j] = (float)imaginary_part;
}
}
}
}
class Program
{
public static Image<Gray, float> Convolution(Image<Gray, float> src, GaborKernel kernel)
{
Point center = new Point(kernel.width / 2 + 1, kernel.width / 2 + 1);
ConvolutionKernelF kernel_f;
kernel_f = new ConvolutionKernelF(kernel.real, center);
Image<Gray, float> temp1 = src.Convolution(kernel_f);
kernel_f = new ConvolutionKernelF(kernel.imaginary, center);
Image<Gray, float> temp2 = src.Convolution(kernel_f);
temp1 = temp1.Pow(2);
temp2 = temp2.Pow(2);
temp1 = temp1.Add(temp2);
return temp1.Pow(0.5);
}
static void Main()
{
Image<Gray, float> image = new Image<Gray, float>("input.bmp");
double psi = 0;
double gamma = 1;
double theta = Math.PI / 4;
double sigma = 1;
double lambda = 1;
int width = 12;
GaborKernel kernel = new GaborKernel(width, lambda,theta,psi,sigma,gamma);
Image<Gray, float> trans = Convolution(image, kernel);
trans.Save("output.bmp");
}
}
}
我不是emgu.CV程序员,我只是将Emgu.CV(opencv)用于卷积,因为我不了解有关卷积函数的详细信息。
程序正常运行。但是结果似乎很奇怪。例如这张图片:
转换为:
与theta = Math.PI / 4
。将theta更改为theta = Math.PI / 6
会使输出完全不同。同样,更改width
似乎也不会更改输出。
我认为我的代码有问题。你能帮我解决吗?使用Gabor滤波器公式是否正确?还是我使用Emgu.CV卷积是错误的?
我希望第一张图片的输出是这样的:
但是程序不会产生这个。