我真的试图通过C#应用3X3中值过滤,并根据我的理解中位数过滤的概念,我编写了以下代码但是当我运行它时,表单挂起。我认为在最后一个嵌套for循环中有一些问题,但我不知道应用中值概念的错误或错误在哪里!
public static Bitmap MedianFiltering(Bitmap bm)
{
List<int> termsList = new List<int>();
Bitmap res, temp;
Color c;
int counter = 0;
//Convert to Grayscale
for (int i = 0; i < bm.Width; i++)
{
for (int j = 0; j < bm.Height; j++)
{
c = bm.GetPixel(i, j);
byte gray = (byte)(.333 * c.R + .333 * c.G + .333 * c.B);
bm.SetPixel(i, j, Color.FromArgb(gray, gray, gray));
}
}
temp = bm;
//applying Median Filtering
for (int i = 0; i <= temp.Width - 3; i++)
for (int j = 0; j <= temp.Height - 3; j++)
{
for (int x = i; x <= i + 2; x++)
for (int y = j; y <= j + 2; y++)
{
c = temp.GetPixel(x, y);
termsList.Add(c.R);
counter++;
}
int[] terms = termsList.ToArray();
Array.Sort<int>(terms);
Array.Reverse(terms);
int color = terms[4];
temp.SetPixel(i + 1, j + 1, Color.FromArgb(color, color, color));
counter = 0;
}
res = temp;
return res;
}
感谢。
答案 0 :(得分:1)
在每次像素处理后,您没有清除termsList
。这导致列表继续增长。对列表进行排序和反转将持续越来越长的时间。这也会导致错误的结果,因为您只想获得与当前像素相关的9个像素的中位数。
只需清除以下列表:
...
int[] terms = termsList.ToArray();
termsList.Clear();
...
<强>更新强>
我为代码做了更多优化:
public static void MedianFiltering(Bitmap bm)
{
List<byte> termsList = new List<byte>();
byte[,] image = new byte[bm.Width,bm.Height];
//Convert to Grayscale
for (int i = 0; i < bm.Width; i++)
{
for (int j = 0; j < bm.Height; j++)
{
var c = bm.GetPixel(i, j);
byte gray = (byte)(.333 * c.R + .333 * c.G + .333 * c.B);
image[i, j] = gray;
}
}
//applying Median Filtering
for (int i = 0; i <= bm.Width - 3; i++)
for (int j = 0; j <= bm.Height - 3; j++)
{
for (int x = i; x <= i + 2; x++)
for (int y = j; y <= j + 2; y++)
{
termsList.Add(image[x, y]);
}
byte[] terms = termsList.ToArray();
termsList.Clear();
Array.Sort<byte>(terms);
Array.Reverse(terms);
byte color = terms[4];
bm.SetPixel(i + 1, j + 1, Color.FromArgb(color, color, color));
}
}
请注意,在原始方法中,您返回了Bitmap
。我删除了这个。
请注意,temp = bm;
不会创建Bitmap
的副本。它只是将temp
变量指向同一个对象(由bm
指向)。因此,在原始方法中,您返回了在method参数中传递的确切对象。要使用新方法,请传递Bitmap
,然后修改自身的位图(对于您的方法也是如此)。
这在我的机器上增强了4倍的性能。
我所做的主要是将位图数据读入字节数组,而不是使用Bitmap
自己多次读/写数据。
如果您需要进一步提升效果,请查看this question。