c#中的3X3中值滤波,但不起作用?
实际上,我正试图通过C#应用3X3中值滤波,根据我对中值滤波概念的理解,我编写了以下代码,但当我运行它时,表单挂起。我认为在上一个嵌套for循环中存在一些问题,但我不知道应用中间值概念的错误在哪里c#中的3X3中值滤波,但不起作用?,c#,.net,image-processing,C#,.net,Image Processing,实际上,我正试图通过C#应用3X3中值滤波,根据我对中值滤波概念的理解,我编写了以下代码,但当我运行它时,表单挂起。我认为在上一个嵌套for循环中存在一些问题,但我不知道应用中间值概念的错误在哪里 public static Bitmap MedianFiltering(Bitmap bm) { List<int> termsList = new List<int>(); Bitmap res, temp; Colo
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;
}
公共静态位图媒体过滤(位图bm)
{
列表项列表=新列表();
位图分辨率,温度;
颜色c;
int计数器=0;
//转换为灰度
对于(int i=0;i 对于(int i=0;i在每个像素处理后,您没有清除术语列表
。这会导致列表不断增长。排序和反转列表将持续花费越来越长的时间。这也会导致不正确的结果,因为您只想获得与当前像素相关的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));
}
}
publicstaticvoidmedianfiltering(位图bm)
{
列表项列表=新列表();
字节[,]图像=新字节[bm.宽度,bm.高度];
//转换为灰度
对于(int i=0;i 对于(int i=0;i)如果在UI线程(例如,从按钮处理程序)上运行此代码,则UI挂起是正常的。但它应该只挂起,直到中值滤波器计算完成。您可以使用异步方法使窗体在计算过程中不挂起。我现在在这一行进行了尝试!temp.SetPixel(i+1,j+1,Color.FromArgb(Color,Color,Color));所以它完全挂起了?如果您等待足够的时间,它是否结束了?我等待了5分钟甚至更长时间,结果是相同的。5分钟后是否有任何进展?将Debug.WriteLine(i+”,“+j);
放在temp.SetPixel之后(i+1,j+1,….
行。这将把当前像素坐标输出到输出窗口(在visual studio中查看->输出)通过这种方式,你可以看到程序是否仍在运行。它现在运行得更快了。我等待了5分钟来获取结果,但我想做一些事情来应用它,以获得更高的性能,你有什么建议吗?奇怪。5分钟太多了。输入图像有多大?宽度和高度是多少?我绑定了你的代码(添加termsList.Clear()后
)在尺寸为1013x699的图像上。在我的机器上大约需要8秒。虽然有改进的余地,但仍然很奇怪为什么在你的机器上需要5分钟。我正在mac上的windows虚拟机上工作,这有什么效果吗?我现在尝试了一个图像500x333,需要2.5分钟,回答你的问题:是的。虚拟机几乎总是比真实机慢。