我想用C#对图像进行低通滤波,高通滤波,直方图均衡化,由于不懂技术,就参考了些网上源代码,如 翻转,灰度等算法,可是算法中的部分实现不知其所以然。比如:
翻转算法:
public static bool Invert(Bitmap b)
{
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
unsafe
{
byte * p = (byte *)(void *)Scan0;
int nOffset = stride - b.Width*3;
int nWidth = b.Width * 3;
for(int y=0;y<b.Height;++y)
{
for(int x=0; x < nWidth; ++x )
{
p[0] = (byte)(255-p[0]);
++p;
}
p += nOffset;
}
}
b.UnlockBits(bmData);
return true;
}
灰度算法:
public static bool Gray(Bitmap b)
{
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
unsafe
{
byte * p = (byte *)(void *)Scan0;
int nOffset = stride - b.Width*3;
byte red, green, blue;
for(int y=0;y<b.Height;++y)
{
for(int x=0; x < b.Width; ++x )
{
blue = p[0];
green = p[1];
red = p[2];
p[0] = p[1] = p[2] = (byte)(.299 * red + .587 * green + .114 * blue);
p += 3;
}
p += nOffset;
}
}
b.UnlockBits(bmData);
return true;
}
仔细分析,就弄不怎么透:到底是怎样通过指针来实现的?上面2个类似的算法中对指针的应用似乎有很大的不同。还有:p[0]与后面的p[0],p[1],p[2]到底是怎么个用法,好像和以前使用指针有很大的不同。顺便问问学习这么久以来的困惑:到底在Paint()方法中使用Graphics g = e.Graphics 与在其他地方使用Graphics g = this.CreatGraphics()有什么不同?this.Refresh()与this.invalidate()有什么不同?
各位朋友注意了,一共是4个问题,回答任何一个都可以,希望满足我的求知欲望!!谢谢了
当然,如果哪位编写过类似的源代码,发给我学习研究的话,我更是感激不尽!!!
[email protected]
正在学习这方面的新手或是这方面的高手,我都愿意与你们交流,分享经验。
QQ:33805508    注明:数字图像处理

解决方案 »

  1.   

    1.???哪里不清楚?
    2.有什么不同?(只是根据需要计算方法不同而已,第一个是r g b 分别取反( p[0] = (byte)(255-p[0]);)第二个是r g b取加权平均值)
    3.区别不是很清楚(如果不用到双缓冲的话,基本上没有问题,至少我没遇到)
    4.用reflector看一下这两个方法的实现也许比较清楚,然后再看一下两者的帮助说明
    public virtual void Refresh()
    {
          this.Invalidate(true);
          this.Update();
    }public void Invalidate()
    {
          this.Invalidate(false);
    }
    msdn的帮助:
    调用 Invalidate 方法并不强制同步绘制;若要强制同步绘制,请在调用 Invalidate 方法之后调用 Update 方法。在不带参数的情况下调用此方法时,会将整个工作区添加到更新区域。  
      

  2.   

    灰度算法:
    public static bool Gray(Bitmap b)
    {
    BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    int stride = bmData.Stride;//请看Msdn关于Stride的说明:跨距是单行像素(一个扫描行)的宽度,舍入为一个 4 字节的边界
    System.IntPtr Scan0 = bmData.Scan0;//bitmap的图像数据的起始指针
    unsafe
    {
    byte * p = (byte *)(void *)Scan0;//(指针类型转换)
    int nOffset = stride - b.Width*3;//计算每一行数据对齐的字节数
    byte red, green, blue;
    for(int y=0;y<b.Height;++y)
    {
    for(int x=0; x < b.Width; ++x )
    {
    blue = p[0];
    green = p[1];
    red = p[2];
    p[0] = p[1] = p[2] = (byte)(.299 * red + .587 * green + .114 * blue);
    p += 3;
    }
    p += nOffset;
    }
    }
    b.UnlockBits(bmData);
    return true;
    }
      

  3.   

    似乎长进了不少    谢谢了 !!
    其实 我的主要问题出在: 2个函数中的For循环中一个是p[0],而另一个是p[0],p[1],p[2],我不懂这是怎么个用法。
    说白了
    我真正面对的问题是:对图像进行低通滤波处理   简单的平滑线形滤波  3*3 就可以了 
    是不是需要  先将原图像 克隆 下  ,然后再用克隆图片的数据处理原图像数据,那么,指针操作我就遇到了很大的问题,总是出不了结果~~~~
    拜托  再 帮我 解释下  谢谢!!!
      

  4.   

    你是要找到3*3点的坐标吧
    以求灰度的那个循环为例
    各点坐标是:
    p-stride-3 p-stride p-stride+3
        p-3        p       p+3
    p+stride-3 p+stride p+stride+3每个点的b g r 分别为 p[0] p[1] p[2] 
      

  5.   

    p指向中心点,q指向左上角那个点
    q=p-stride-3
    p[0]=q[0]+q[3]+[6]+q[stride]+q[stride+3]+q[stride+6]+q[stride*2]+q[stride*2+3]+q[stride*2+6]
    p[1]=q[1]+q[4]+[7]+q[stride+1]+q[stride+4]+q[stride+7]+q[stride*2+1]+q[stride*2+4]+q[stride*2+7]
    p[3]=............ 
      

  6.   

    好了 
    差不多成功了
    感谢给我最大帮助的2个人:Jim3(Jim), lgh12345(.NET资源文件生成器) 
    不过我的方向改了,准备向  .net与matlab整合  攻关了   
    呵呵  结贴给分