自定义过滤器库未生成预期输出

时间:2016-10-20 23:33:46

标签: c#-4.0 image-processing convolution bitmapdata imagefilter

请参阅this article

我已实施 4.1(预处理部分。

  

预处理步骤旨在增强一组图像特征   选择的方向。首先,图像是灰度的,并用a过滤   锐化滤波器(我们从图像中减去其局部均值滤波   版本),从而消除了直流分量。

     

我们选择了12个不重叠的过滤器,来分析12个不同的过滤器   方向,相互旋转15°。

GitHub Repositiry is here.

由于文章中的给定公式不正确,我尝试了两组不同的公式。

第一组公式,

enter image description here

enter image description here

第二组公式,

enter image description here

预期输出应为

enter image description here

他们都没有给出正确的结果。

enter image description here

有人可以建议我进行任何修改吗?

GitHub Repository is here.

源代码的大多数相关部分都在这里:

    public List<Bitmap> Apply(Bitmap bitmap)
    {
        Kernels = new List<KassWitkinKernel>();

        double degrees = FilterAngle;

        KassWitkinKernel kernel;
        for (int i = 0; i < NoOfFilters; i++)
        {
            kernel = new KassWitkinKernel();
            kernel.Width = KernelDimension;
            kernel.Height = KernelDimension;
            kernel.CenterX = (kernel.Width) / 2;
            kernel.CenterY = (kernel.Height) / 2;
            kernel.Du = 2;
            kernel.Dv = 2;
            kernel.ThetaInRadian = Tools.DegreeToRadian(degrees);
            kernel.Compute();

            //SleuthEye
            kernel.Pad(kernel.Width, kernel.Height, WidthWithPadding, HeightWithPadding);

            Kernels.Add(kernel);

            degrees += degrees;
        }

        List<Bitmap> list = new List<Bitmap>();

        Bitmap image = (Bitmap)bitmap.Clone();

        //PictureBoxForm f = new PictureBoxForm(image);
        //f.ShowDialog();

        Complex[,] cImagePadded = ImageDataConverter.ToComplex(image);

        Complex[,] fftImage = FourierTransform.ForwardFFT(cImagePadded);

        foreach (KassWitkinKernel k in Kernels)
        {
            Complex[,] cKernelPadded = k.ToComplexPadded();
            Complex[,] convolved = Convolution.ConvolveInFrequencyDomain(fftImage, cKernelPadded);

            Bitmap temp = ImageDataConverter.ToBitmap(convolved);



            list.Add(temp);
        }

        return list;
    }

1 个答案:

答案 0 :(得分:1)

也许应该提到的第一件事是应该生成过滤器,角度应该增加FilterAngle(在你的情况下为15度)增量。这可以通过修改KassWitkinFilterBank.Apply来实现,如下所示(参见this commit):

public List<Bitmap> Apply(Bitmap bitmap)
{
    // ...

    // The generated template filter from the equations gives a line at 45 degrees. 
    // To get the filter to highlight lines starting with an angle of 90 degrees
    // we should start with an additional 45 degrees offset.
    double degrees = 45;

    KassWitkinKernel kernel;
    for (int i = 0; i < NoOfFilters; i++)
    {
        // ... setup filter (unchanged)

        // Now increment the angle by FilterAngle
        // (not "+= degrees" which doubles the value at each step)
        degrees += FilterAngle;
    }

这应该会给你以下结果:

enter image description here

这不完全是纸张的结果,图像之间的差异仍然非常微妙,但你应该能够注意到刮痕线在第8个数字中最强烈(正如预期的那样,从刮擦角度开始)约为100-105度。

为了改善结果,我们应该按照文章中描述的相同方式为过滤器提供预处理过的图像:

  

首先,图像是灰度缩放的,并使用锐化滤镜进行过滤(我们从图像中减去其局部均值滤波版本),从而消除了DC分量

当你这样做时,你会得到一个值矩阵,其中一些将是负数。结果,该中间处理结果不适合存储为Bitmap。作为执行图像处理的一般规则,您应该将所有中间结果保存在doubleComplex中,并且只将最终结果转换回Bitmap以进行可视化。

通过将输入bitmap和临时image变量更改为使用double[,]数据类型来集成您的更改以从your GitHub repository添加图像锐化,同时保持中间结果为双精度而不是Bitmap方法中的KassWitkinFilterBank.Apply(请参阅this commit):

public List<Bitmap> Apply(double[,] bitmap)
{
    // [...]

    double[,] image = (double[,])bitmap.Clone();

    // [...]
}

应该会给你以下结果:

enter image description here

或者为了更好地突出差异,左边的图1(0度),右边的图8(105度)旁边:

enter image description here