高手,这是什么平滑算法?

hahasong1213 2010-05-06 12:09:10
刚刚接触图像,看到一段smooth的代码,谁能告诉我一下c#代码用的是什么平滑处理?谢谢!
public static bool Smooth(Bitmap b, int nWeight /* default to 1 */)
{
ConvMatrix m = new ConvMatrix();
m.SetAll(1);
m.Pixel = nWeight;
m.Factor = nWeight + 8;

return BitmapFilter.Conv3x3(b, m);
}
public static bool Conv3x3(Bitmap b, ConvMatrix m)
{
// Avoid divide by zero errors
if (0 == m.Factor) return false;

Bitmap bSrc = (Bitmap)b.Clone();

// GDI+ still lies to us - the return format is BGR, NOT RGB.
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

int stride = bmData.Stride;
int stride2 = stride * 2;
System.IntPtr Scan0 = bmData.Scan0;
System.IntPtr SrcScan0 = bmSrc.Scan0;

unsafe
{
byte * p = (byte *)(void *)Scan0;
byte * pSrc = (byte *)(void *)SrcScan0;

int nOffset = stride + 6 - b.Width*3;
int nWidth = b.Width - 2;
int nHeight = b.Height - 2;

int nPixel;

for(int y=0;y < nHeight;++y)
{
for(int x=0; x < nWidth; ++x )
{
nPixel = ( ( ( (pSrc[2] * m.TopLeft) + (pSrc[5] * m.TopMid) + (pSrc[8] * m.TopRight) +
(pSrc[2 + stride] * m.MidLeft) + (pSrc[5 + stride] * m.Pixel) + (pSrc[8 + stride] * m.MidRight) +
(pSrc[2 + stride2] * m.BottomLeft) + (pSrc[5 + stride2] * m.BottomMid) + (pSrc[8 + stride2] * m.BottomRight)) / m.Factor) + m.Offset);

if (nPixel < 0) nPixel = 0;
if (nPixel > 255) nPixel = 255;

p[5 + stride]= (byte)nPixel;

nPixel = ( ( ( (pSrc[1] * m.TopLeft) + (pSrc[4] * m.TopMid) + (pSrc[7] * m.TopRight) +
(pSrc[1 + stride] * m.MidLeft) + (pSrc[4 + stride] * m.Pixel) + (pSrc[7 + stride] * m.MidRight) +
(pSrc[1 + stride2] * m.BottomLeft) + (pSrc[4 + stride2] * m.BottomMid) + (pSrc[7 + stride2] * m.BottomRight)) / m.Factor) + m.Offset);

if (nPixel < 0) nPixel = 0;
if (nPixel > 255) nPixel = 255;

p[4 + stride] = (byte)nPixel;

nPixel = ( ( ( (pSrc[0] * m.TopLeft) + (pSrc[3] * m.TopMid) + (pSrc[6] * m.TopRight) +
(pSrc[0 + stride] * m.MidLeft) + (pSrc[3 + stride] * m.Pixel) + (pSrc[6 + stride] * m.MidRight) +
(pSrc[0 + stride2] * m.BottomLeft) + (pSrc[3 + stride2] * m.BottomMid) + (pSrc[6 + stride2] * m.BottomRight)) / m.Factor) + m.Offset);

if (nPixel < 0) nPixel = 0;
if (nPixel > 255) nPixel = 255;

p[3 + stride] = (byte)nPixel;

p += 3;
pSrc += 3;
}

p += nOffset;
pSrc += nOffset;
}
}

b.UnlockBits(bmData);
bSrc.UnlockBits(bmSrc);

return true;
}
...全文
436 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
PeterSong9970 2010-05-10
  • 打赏
  • 举报
回复
学习了。。。
sarah1031 2010-05-10
  • 打赏
  • 举报
回复
学习一下
卧_槽 2010-05-10
  • 打赏
  • 举报
回复
这就是经典的平滑算法啊。
以传入的nWeight 为参数。
nWeight为1的时候即为当前像素点值为周围9点像素值平均数(包括自己)。即平均模糊。达到的效果和ps的平均模糊等同。

nWeight大于1时,加强原像素点信息,减弱周围点对原像素点的影响。
nWeight趋向于无穷大时效果图等同原图。

可以看出这是一个改良过的平均模糊算法,可以调控模糊程度(nWeight越大,模糊程度越低),但是最大也就是达到平均模糊的效果。


zhoujk 2010-05-09
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 hahasong1213 的回复:]
引用 3 楼 zhoujk 的回复:
如果m的每个字段的值相等,则为均值平滑

public class ConvMatrix
{
public int TopLeft = 0, TopMid = 0, TopRight = 0;
public int MidLeft = 0, Pixel = 1, MidRight = 0;
public int BottomLeft = 0, B……
[/Quote]
...在下眼高手低头大,这种搞法就真的没见过了
zhoujk 2010-05-09
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 hahasong1213 的回复:]
引用 3 楼 zhoujk 的回复:
如果m的每个字段的值相等,则为均值平滑

public class ConvMatrix
{
public int TopLeft = 0, TopMid = 0, TopRight = 0;
public int MidLeft = 0, Pixel = 1, MidRight = 0;
public int BottomLeft = 0, B……
[/Quote]
...OK,算我错了,全文应该是:
如果M的每个字段的值相等且大于0,则为均值平滑,多此一举,还不如直接求平均数
如果等于0,则为脱了裤子打屁,多此一举,
如果均为负,则系统出错。。。
dubaokun 2010-05-08
  • 打赏
  • 举报
回复
值得学习一下
Justin-Liu 2010-05-07
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 zhoujk 的回复:]
nPixel = ( ( ( (pSrc[0] * m.TopLeft) + (pSrc[3] * m.TopMid) + (pSrc[6] * m.TopRight) +
(pSrc[0 + stride] * m.MidLeft) + (pSrc[3 + stride] * m.Pixel) + (pSrc[6 + stride] * m.MidRight) +
(pSrc[0 +……
[/Quote]
恩 用的是这种方式
dylike 2010-05-07
  • 打赏
  • 举报
回复
效果不错
changjin642 2010-05-07
  • 打赏
  • 举报
回复
学习,帮顶
zhoujk 2010-05-07
  • 打赏
  • 举报
回复
如果m的每个字段的值相等,则为均值平滑
wangwenzhuang 2010-05-07
  • 打赏
  • 举报
回复
俺是GDI+菜鸟,进来学习的
hahasong1213 2010-05-07
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 zhoujk 的回复:]
如果m的每个字段的值相等,则为均值平滑
[/Quote]
public class ConvMatrix
{
public int TopLeft = 0, TopMid = 0, TopRight = 0;
public int MidLeft = 0, Pixel = 1, MidRight = 0;
public int BottomLeft = 0, BottomMid = 0, BottomRight = 0;
public int Factor = 1;
public int Offset = 0;
public void SetAll(int nVal)
{
TopLeft = TopMid = TopRight = MidLeft = Pixel = MidRight = BottomLeft = BottomMid = BottomRight = nVal;
}
}
huminghua 2010-05-06
  • 打赏
  • 举报
回复
不懂帮顶学习!
zhoujk 2010-05-06
  • 打赏
  • 举报
回复
nPixel = ( ( ( (pSrc[0] * m.TopLeft) + (pSrc[3] * m.TopMid) + (pSrc[6] * m.TopRight) +
(pSrc[0 + stride] * m.MidLeft) + (pSrc[3 + stride] * m.Pixel) + (pSrc[6 + stride] * m.MidRight) +
(pSrc[0 + stride2] * m.BottomLeft) + (pSrc[3 + stride2] * m.BottomMid) + (pSrc[6 + stride2] * m.BottomRight)) / m.Factor) + m.Offset);
不是均值平滑,而是使用加权平均的方式进行,其中的加权值就是m.XXX,应该是预选设定好的。这些字段的名称就带是指向。
BMP magic是一个新型的加密软件,你可以用它把任何格式的windows文件存入到一幅24位真彩色的BMP图片中,神奇的是这幅内部藏有文件的图片的尺寸、大小不变! 在接下来的文字中您会了解到关于这个新版软件的强大功能与安全算法:在5.0B版本中:★支持jpg格式! 在本版本中,新加入了对jpg格式的自动转换——如果您打开的是一幅jpg图片,程序会自动转换为bmp格式来处理,不用事先再用其它工具转换。★可以隐藏比图片自身大若干倍的文件! 您要相信自己的眼睛:一幅200K的24位BMP,利用本程序成功地将一个1474.56K=1.44兆的WPS文件隐藏于其中!而且这还不是软件创的最高记录。★通过一系列优化算法,使隐藏文件的图片画质得到最大程序的提升! 一幅图片在最大限度上隐藏外部文件后,画质依然清晰,色彩过渡仍很平滑,基本不存在色块问题。这种算法理论上还未达到极限,后续版本中还将继续改进算法使画质进一步提升。★引领数据压缩领域新潮流! 目前最先进的压缩工具对文本文件的压缩率也不过90%,然而利用本软件将图片隐藏文件后再压缩,却有望突破这一“极限”压缩率!基于此种组合压缩法,阁下的160G海量硬盘是否可以多出几十G呢?★独创的255位动态密钥加密术让数据隐藏的更安全! 传统加密法采用常量作加密密钥不少解密高手正是利用这一普遍规律分析加密算法从而成功将所谓的“安全数据”解密。本软件自这一版本起采用最前沿的“动态密钥加密算法”使被加密的数据安全性能有了一个“质”的飞跃!也就是说,即使您用同一幅图片隐藏同一个文件,每次生成的新图片内部数据绝对是不一样的!★采用多种加密方式加密数据,无须担心数据传递过程的“中介者”! 新版软件中采用六种方式加密数据: 1.日期时间锁定; 2.外部软件锁定; 3.程序版本识别; 4.机器硬件锁定; 5.操作系统识别; 6.解密口令锁定。 这六种方式可以任意组合,现分别说明如下: A.采用“日期时间”限制时,您可以输入自1985-2099年间的任何时间(精确到秒),这样数据被加密后,解密者如不是在设定的时间企图解密将得不到正确的隐藏文件; B.采用外部软件锁定时,你可以选择你机器上有的任何一个文件做为锁定用程序,对方在解密时,必要性要用同样的文件来做为密匙才能解开里面的密文(你用的是什么文件,在“图文信息”中是查看不到的!)。 C.程序版本识别,也就是说,你用某一个版本的BMP magic加密了文件后,用其它版本的BMP magic是无法解开里面的密文的,换句话说,就是我们开发的程序,没有设置“向下兼容”; D.机器硬件锁定,你可以用你机器上的任何一个驱动器作为锁定密匙,包括硬盘逻辑分区,光盘,软盘,这样,除了在你的硬件环境中,别人将无法得到正确的加密文件; E.操作员识别,你选用“操作系统识别”后,就只能在相同的操作系统下解开密文,并且,在“图文信息”中不会标识出系统类型; F.采用“用户口令”限制时,您可以输入最长255位的密码(可以是您有办法输入其中的任何字符,当然有中文啦...)。★在图片中的任何添加数据(包括添加的文件头部信息)均用不同密钥加密,如不利用本软件根本提取不到任何有用的信息!这使数据的安全保密性得以极端的提高!★图片中可以像电子邮件一样附加“发送人”、“接收人”、“主题”及留言信息,使加密后的图片交互性更强,十二分的人性化设计!...... 共享软件时代,加密软件数不胜数,相信阁下在看到上面的文字后会在选择加密软件方面有一个成熟的理念,同时我们也相信,这个最新版的软件会带给您生活与工作上的方便与惊喜!********************************************************* 在您使用本软件之前,希望事先能与阁下达成下面的协议: 1.本软件纯属利用娱乐创意编写,参与软件编写的所有人员均不会对您由于使用本软件所造成的一切后果与损失负责! 2.本软件加密技术相当先进,属于“一次性加密”,故软件作者不会接受任何人员提出的“数据抢救”询求,请阁下自我保重! 3.本软件的所有流行版本严禁任何组织或个人对其进行反编及商业炒作或以作者名义营利,但欢迎在不影响版权时传播与发布! 如果用户使用本软件,就表示默认上述许可,否则请销毁本软件! ********************************************************* 经测试,本软件在Window9x/Me/NT/2000/XP运行稳定并无不安全因素敬请放心使用并烦劳扩充测试,谢谢! 感谢众多朋友帮忙测试软件!

110,566

社区成员

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

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

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