自定义过滤器组未生成预期输出
Custom filter bank is not generating the expected output
请参考this article。
我已经实现了 4.1 (Pre-processing).
部分
The preprocessing step aims to enhance image features along a set of
chosen directions. First, image is grey-scaled and filtered with a
sharpening filter (we subtract from the image its local-mean filtered
version), thus eliminating the DC component.
We selected 12 not overlapping filters, to analyze 12 different
directions, rotated with respect to 15° each other.
由于文章中给出的公式不正确,我尝试了两组不同的公式。
第一组公式,
第二组公式,
预期的输出应该是,
他们都没有给出正确的结果。
有人可以建议我修改吗?
最相关的源代码部分在这里:
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;
}
也许首先应该提到的是应该以 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;
}
这应该会给您以下结果:
这不完全是论文的结果,图像之间的差异仍然非常细微,但您应该能够注意到第 8 个数字中的划痕线最强烈(正如自划痕角度约为 100-105 度)。
为了改善结果,我们应该按照论文中描述的相同方式为过滤器提供预处理图像:
First, image is grey-scaled and filtered with a sharpening filter (we subtract from the image its local-mean filtered version), thus eliminating the DC component
当你这样做时,你会得到一个值矩阵,其中一些是负数。因此,这个中间处理结果不适合存储为 Bitmap
。作为图像处理的一般规则,您应该根据需要将所有中间结果保留在 double
或 Complex
中,并且只将最终结果转换回 Bitmap
以进行可视化。
整合您的更改以添加来自 your GitHub repository while keeping intermediate results as doubles can be achieve by changing the input bitmap
and temporary image
variables to use double[,]
datatype instead of Bitmap
in the KassWitkinFilterBank.Apply
method (see this commit 的图像锐化):
public List<Bitmap> Apply(double[,] bitmap)
{
// [...]
double[,] image = (double[,])bitmap.Clone();
// [...]
}
应该会得到以下结果:
或者为了更好地突出区别,左边是图1(0度),右边是图8(105度):
请参考this article。
我已经实现了 4.1 (Pre-processing).
部分The preprocessing step aims to enhance image features along a set of chosen directions. First, image is grey-scaled and filtered with a sharpening filter (we subtract from the image its local-mean filtered version), thus eliminating the DC component.
We selected 12 not overlapping filters, to analyze 12 different directions, rotated with respect to 15° each other.
由于文章中给出的公式不正确,我尝试了两组不同的公式。
第一组公式,
第二组公式,
预期的输出应该是,
他们都没有给出正确的结果。
有人可以建议我修改吗?
最相关的源代码部分在这里:
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;
}
也许首先应该提到的是应该以 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;
}
这应该会给您以下结果:
这不完全是论文的结果,图像之间的差异仍然非常细微,但您应该能够注意到第 8 个数字中的划痕线最强烈(正如自划痕角度约为 100-105 度)。
为了改善结果,我们应该按照论文中描述的相同方式为过滤器提供预处理图像:
First, image is grey-scaled and filtered with a sharpening filter (we subtract from the image its local-mean filtered version), thus eliminating the DC component
当你这样做时,你会得到一个值矩阵,其中一些是负数。因此,这个中间处理结果不适合存储为 Bitmap
。作为图像处理的一般规则,您应该根据需要将所有中间结果保留在 double
或 Complex
中,并且只将最终结果转换回 Bitmap
以进行可视化。
整合您的更改以添加来自 your GitHub repository while keeping intermediate results as doubles can be achieve by changing the input bitmap
and temporary image
variables to use double[,]
datatype instead of Bitmap
in the KassWitkinFilterBank.Apply
method (see this commit 的图像锐化):
public List<Bitmap> Apply(double[,] bitmap)
{
// [...]
double[,] image = (double[,])bitmap.Clone();
// [...]
}
应该会得到以下结果:
或者为了更好地突出区别,左边是图1(0度),右边是图8(105度):