修复了用于实现Gabor过滤器的简单C#代码

时间:2018-08-02 04:18:15

标签: c# opencv signal-processing emgucv gabor-filter

Wikipedia给出的Gabor滤波器公式为: enter image description here

我试图编写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)用于卷积,因为我不了解有关卷积函数的详细信息。

程序正常运行。但是结果似乎很奇怪。例如这张图片:

enter image description here

转换为:

enter image description here

theta = Math.PI / 4。将theta更改为theta = Math.PI / 6会使输出完全不同。同样,更改width似乎也不会更改输出。

我认为我的代码有问题。你能帮我解决吗?使用Gabor滤波器公式是否正确?还是我使用Emgu.CV卷积是错误的?

我希望第一张图片的输出是这样的:

enter image description here

但是程序不会产生这个。

0 个答案:

没有答案