C#中值滤波算法的问题

ghjlesse 2012-03-09 03:08:15
这两天想整一下验证码图片的识别,了解到中值滤波算法对消除噪点特别有用,于是学习了一下中值滤波的算法,搞出来个中值滤波的方法,但是实际效果很不理想,不知道是代码的问题还是什么其他问题,期待高手指教!
代码如下:

public Bitmap Medianfilter(Bitmap bitmap,Int32 Radius)
{
Bitmap tarBitmap = new Bitmap(bitmap.Width, bitmap.Height);
for (Int32 x = 0; x < bitmap.Width; x++)
for (Int32 y = 0; y < bitmap.Height; y++)
{
Int32 left = x - Radius > 0 ? x - Radius : 0;
Int32 top = y - Radius > 0 ? y - Radius : 0;
Int32 right = x + Radius > bitmap.Width ? bitmap.Width : x + Radius;
Int32 bottom = y + Radius > bitmap.Height ? bitmap.Height : y + Radius;
List<Int32> listColor = new List<int>();

for(Int32 i = left; i < right; i ++)
for (Int32 j = top; j < bottom; j++)
{
if (!listColor.Contains(bitmap.GetPixel(i, j).R)) listColor.Add(bitmap.GetPixel(i, j).R);
}

listColor.Sort();
Int32 intMedian;
if (listColor.Count == 0) continue;
if (listColor.Count % 2 == 0)
intMedian = (listColor[listColor.Count / 2] + listColor[listColor.Count / 2 - 1]) / 2;
else
intMedian = listColor[(listColor.Count - 1) / 2];
tarBitmap.SetPixel(x, y, Color.FromArgb(intMedian, intMedian, intMedian));
}
return tarBitmap;
}

我不知道怎么贴图片,验证码图片可以用注册163邮箱时的图片,是汉字。
...全文
802 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
北风吹冷 2013-06-13
  • 打赏
  • 举报
回复
代码贴上来,用指针实现的!比上一种方法要好,如果有错误,希望大家指正!

  private void medianFilter1(object sender,EventArgs e)
        {
 
             //boxTwo是要处理的图片(bitmap对象)
            Bitmap srcBmp = (Bitmap)boxTwo.Clone();
            BitmapData bmData = boxTwo.LockBits(new Rectangle(0, 0, boxTwo.Width, boxTwo.Height), 
                ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            BitmapData bmSrcData = srcBmp.LockBits(new Rectangle(0,0,srcBmp.Width,srcBmp.Height),
                ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb);

            int stride = bmData.Stride;
            int stride2 = bmData.Stride*2;
            System.IntPtr scan0 = bmData.Scan0;
            System.IntPtr srcScan0 = bmSrcData.Scan0;

            unsafe
            {
                byte* p = (byte*)scan0;
                byte* pSrc = (byte*)srcScan0;
                int nWidth = boxTwo.Width - 2;
                int nHeight = boxTwo.Height - 2;
                int nOffset = stride - boxTwo.Width * 3;

                int nPixel;
                List<int> array = new List<int>();
                for (int y = 0; y < nHeight; y++)
                {
                    for (int x = 0; x < nWidth; x++)
                    {
                        /*清空数组*/
                        array.Clear();
                        array.Add(pSrc[2]);
                        array.Add(pSrc[5]);
                        array.Add(pSrc[8]);
                        array.Add(pSrc[2 + stride]);
                        array.Add(pSrc[5 + stride]);
                        array.Add(pSrc[8 + stride]);
                        array.Add(pSrc[2 + stride2]);
                        array.Add(pSrc[5 + stride2]);
                        array.Add(pSrc[8 + stride2]);
                        /*对数据进行大小排序*/
                        array.Sort();
                        nPixel = array[array.Count / 2];
                        if (nPixel < 0) nPixel = 0;
                        if (nPixel > 255) nPixel = 255;
                        /*对像素进行赋值*/
                        pSrc[5 + stride] = (byte)nPixel;

                        array.Clear();
                        array.Add(pSrc[1]);
                        array.Add(pSrc[4]);
                        array.Add(pSrc[7]);
                        array.Add(pSrc[1 + stride]);
                        array.Add(pSrc[4 + stride]);
                        array.Add(pSrc[7 + stride]);
                        array.Add(pSrc[1 + stride2]);
                        array.Add(pSrc[4 + stride2]);
                        array.Add(pSrc[7 + stride2]);

                        /*对数据进行大小排序*/
                        array.Sort();
                        nPixel = array[array.Count / 2];
                        if (nPixel < 0) nPixel = 0;
                        if (nPixel > 255) nPixel = 255;
                        /*对像素进行赋值*/
                        pSrc[4 + stride] = (byte)nPixel;

                        array.Clear();
                        array.Add(pSrc[0]);
                        array.Add(pSrc[3]);
                        array.Add(pSrc[6]);
                        array.Add(pSrc[0 + stride]);
                        array.Add(pSrc[3 + stride]);
                        array.Add(pSrc[6 + stride]);
                        array.Add(pSrc[0 + stride2]);
                        array.Add(pSrc[3 + stride2]);
                        array.Add(pSrc[6 + stride2]);

                        /*对数据进行大小排序*/
                        array.Sort();
                        nPixel = array[array.Count / 2];
                        if (nPixel < 0) nPixel = 0;
                        if (nPixel > 255) nPixel = 255;
                        /*对像素进行赋值*/
                        pSrc[3 + stride] = (byte)nPixel;

                        p += 3;
                        pSrc += 3;
                    }/*inner for*/
                    p += nOffset;
                    p += nOffset;
                }/*outer for*/
            }/*unsafe*/
            boxTwo.UnlockBits(bmData);
            srcBmp.UnlockBits(bmSrcData);
            boxTwo = srcBmp;
           
        }
北风吹冷 2013-06-13
  • 打赏
  • 举报
回复


            int Radius = 4;
/*boxOne是要处理的图像*/
            Bitmap source = (Bitmap)boxOne.Clone();
          
            Bitmap tarBitmap = new Bitmap(boxOne.Width, boxOne.Height);
            for (Int32 x = 0; x < source.Width; x++)
                for (Int32 y = 0; y <source.Height; y++)
                {
                    Int32 left = x - Radius > 0 ? x - Radius : 0;
                    Int32 top = y - Radius > 0 ? y - Radius : 0;
                    Int32 right = x + Radius > source.Width ? source.Width : x + Radius;
                    Int32 bottom = y + Radius > source.Height ? source.Height : y + Radius;
                    System.Collections.Generic.List<Int32> listColor = new System.Collections.Generic.List<Int32>();

                    for (Int32 i = left; i < right; i++)
                        for (Int32 j = top; j < bottom; j++)
                        {
                            if (!listColor.Contains(source.GetPixel(i, j).R)) listColor.Add(source.GetPixel(i, j).R);
                        }

                    listColor.Sort();
                    Int32 intMedian;
                    if (listColor.Count == 0) continue;
                    if (listColor.Count % 2 == 0)
                        intMedian = (listColor[listColor.Count / 2] + listColor[listColor.Count / 2 - 1]) / 2;
                    else
                        intMedian = listColor[(listColor.Count - 1) / 2];
                    tarBitmap.SetPixel(x, y, Color.FromArgb(intMedian, intMedian, intMedian));
                }
             
这种代码的效率太低,考虑一下利用指针来进行数据操作,否则运算不会太快!
ghjlesse 2012-03-16
  • 打赏
  • 举报
回复
怎么又没人回答了?
muyi66 2012-03-12
  • 打赏
  • 举报
回复
既然算法本身是对的,那就表明用这个算法对付不了你要对付的目标。

加噪永远比除噪容易,既然有除噪算法,别人针对着进行更强的加噪也就很正常了。

话说,现在有些验证码图片人都难看懂,别说傻乎乎的CPU了。
laviewpbt 2012-03-12
  • 打赏
  • 举报
回复
代码问题,你使用tarBitmap.SetPixel后就改变了tarBitmap某个位置的像素值,然后你在下一个循环中GetPixel时获取这个位置的值就是这个改变后的值,这和算法愿意冲突。
ghjlesse 2012-03-12
  • 打赏
  • 举报
回复
怎么没人呢?哪位高手指点一下吧!
ghjlesse 2012-03-12
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 muyi66 的回复:]

既然算法本身是对的,那就表明用这个算法对付不了你要对付的目标。

加噪永远比除噪容易,既然有除噪算法,别人针对着进行更强的加噪也就很正常了。

话说,现在有些验证码图片人都难看懂,别说傻乎乎的CPU了。
[/Quote]
我捣鼓这个是想把注册163邮箱时的验证码图片解析出来,那个验证码图片中是汉字,图片中只有很少的线条和一些噪点,字体也只是角度不同但并没有扭曲,应该容易解析的。
ghjlesse 2012-03-12
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 laviewpbt 的回复:]

代码问题,你使用tarBitmap.SetPixel后就改变了tarBitmap某个位置的像素值,然后你在下一个循环中GetPixel时获取这个位置的值就是这个改变后的值,这和算法愿意冲突。
[/Quote]
上面是用原始的bitMap调用GetPixel方法,而下面是用tarBitmap调用SetPixel方法,没错啊?

111,126

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧