我想用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 注明:数字图像处理
翻转算法:
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 注明:数字图像处理
解决方案 »
- 传言VS2012支持混合编程,即在同一份代码里面,混合各种语言的代码
- c#开发环境
- lock 方法是做什么用的?
- 100分 问个 微软拼音输入法的问题(怎么样才能让全角标点符号消失?)
- 多任务情况下...............如何获取线程状态 ??
- 下拉式按钮显示对话框的位置确定
- 有个C++的计算24的程序,想把他转为C#的命令行程序,可遇到问题
- 哪位有关于ORMAP的资料啊,最好是C#版的.多谢!!
- .Net中这个提示是什么意思?
- c#和.net区别大吗?
- DataGrid如何实现点击一个网格,而选中该网格所在的行,即该行显为蓝色
- C#和ASP。NET中,用什么方法统计访问网站的人数比较合适?
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 方法。在不带参数的情况下调用此方法时,会将整个工作区添加到更新区域。
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;
}
其实 我的主要问题出在: 2个函数中的For循环中一个是p[0],而另一个是p[0],p[1],p[2],我不懂这是怎么个用法。
说白了
我真正面对的问题是:对图像进行低通滤波处理 简单的平滑线形滤波 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]
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]=............
差不多成功了
感谢给我最大帮助的2个人:Jim3(Jim), lgh12345(.NET资源文件生成器)
不过我的方向改了,准备向 .net与matlab整合 攻关了
呵呵 结贴给分