求C#版的图像高斯模糊算法,模糊半径是个参数,谢!

Ki1381 2007-01-19 09:00:08
RT,谢谢!
...全文
1433 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
老青菜 2010-05-13
  • 打赏
  • 举报
回复
kitten_scratch

(小猫抓抓)

WeightedColor这个类里有三个字段,没有其他的东东 吗好象不对诶

阿牛138588 2007-01-20
  • 打赏
  • 举报
回复
路过...
renmasheshou 2007-01-20
  • 打赏
  • 举报
回复
C#的确做图像不行~
Ki1381 2007-01-20
  • 打赏
  • 举报
回复
kitten_scratch(小猫抓抓) :貌似给出的代码有点问题,不过总算有点方向了...
谢谢各位的参与。谁还有更好的方法?
snowvan 2007-01-19
  • 打赏
  • 举报
回复
做个记号!还没有弄过这类东西!学习了!
Ki1381 2007-01-19
  • 打赏
  • 举报
回复
谢谢楼上的~
我先试一下。C#用SetPixel/GetPixel一个个像素计算的话效率确实低的非常可怕,但用BitmapData和unsafe指针就非常令人满意了。
hertcloud 2007-01-19
  • 打赏
  • 举报
回复
http://down.devdao.com/down/5653.html
或 http://www.cn700.com/2004-11/13-204749.html
个人感觉 做图像 还是c/c++ 效率更好
楼主可以将这个代码编译成dll
然后用c#调用
kitten_scratch 2007-01-19
  • 打赏
  • 举报
回复
原文地址
http://www.dormforce.net/Blog/hiworld/archive/2005/05/19/4720.aspx

高斯模糊的.net实现
选择.net来做图像处理唯一的好处就是避免了烦琐的编程细节,可以全部精力投入在算法上.
在图像结构分析之前,我使用了高斯模糊来去粗取精, 将细节部分的去掉,将边缘强化.
高斯模糊的算法很简单了, 使用高斯函数和图像做卷积, 不过复杂度真是不错, 宽度=2的高斯模糊要做 24*n(n是图像像素)次浮点运算
不过如果把重复计算的除外,就只有4*n次了, 而且宽度约大, 重复计算的越多. 我最早实现的不加任何优化的算法真是奇满无比,在被
acdsee的高斯模糊速度bs后,我开始优化,最后终于在速度上比较能够接受(还是要被acdsee鄙视)不过,这个慢速度,vm也多少要负点责任吧...(我又不能使用pointer,所有的数值在使用时都是copy的,这个就比用c实现慢多了...)
private double[,] GAUSS; //高斯函数的值, 每次都计算高斯函数太夸张了吧...事先计算好,放这里备用
private const int FI = 2; //高斯函数宽度
//初试化高斯函数
private void IniGauss(int fi) {
GAUSS = new double[fi * 2 + 1, fi * 2 + 1];

for(int x = -fi; x <=fi; x++)
for(int y = -fi; y <= fi; y++) {
int sqrtFi = fi * fi;
double ex = Math.Pow(Math.E, (-(x * x + y * y)/(2 * sqrtFi)));
double result = ex / (2 * Math.PI * sqrtFi);
GAUSS[x + fi, y + fi] = result;
}
}

//事先计算好每个像素在卷积中要用到的值,避免重复运算, WeightedColor是自定义struct, 只有3个字段,
//分别是double R; double G; double B;
private WeightedColor[,,] GetWeightedColor(Bitmap source, int fi) {
WeightedColor[,,] retVal = new WeightedColor[fi + 1 + fi, source.Width, source.Height];
double r = 0, g = 0, b = 0;

for(int i = 0; i < source.Width; i++)
for(int j = 0; j <source.Height; j++) {
//Calculate weighted color
Color c = source.GetPixel(i, j);

for(int k = 0; k < fi + 1 + fi; k++) {
//From center to edge
double weight;
if( k < fi + 1)
weight = GAUSS[fi, fi + k];
else
//对角
weight = GAUSS[k, k];
r = c.R * weight;
g = c.G * weight;
b = c.B * weight;
r = r > 255 ? 255 : r;
g = g > 255 ? 255 : g;
b = b > 255 ? 255 : b;
retVal[k, i, j] = WeightedColor.FromRGB(r, g, b);
}
}

//计算一个点的卷积值
private Color GetFilteredColor(Bitmap source, int x, int y, int fi, WeightedColor[,,] colorMap) {
int w = source.Width, h = source.Height;
double r = 0, g = 0, b = 0;

for(int u = x - fi; u <= x + fi; u++)
for(int v = y - fi; v <= y + fi; v++) {
if(u >= 0 && u < w && v >= 0 && v < h) {
//wx, wy is the distance between x and u, y and v
int wx = Math.Abs(u - x), wy = Math.Abs(v - y);
//Use which version of colorMap
int wVersion;
if(wx == wy && wx != 0)//对角
wVersion = fi + wx;
else
wVersion = wx > wy ? wx : wy;
WeightedColor tmpC = colorMap[wVersion, u, v];
r += tmpC.R;
g += tmpC.G;
b += tmpC.B;
}
}
r = r > 255 ? 255 : r;
g = g > 255 ? 255 : g;
b = b > 255 ? 255 : b;
return Color.FromArgb((int)r, (int)g, (int)b);
}
return retVal;
}

//使用这个函数对图像进行过滤
private Bitmap GaussianFilt(Bitmap source, int fi) {
Bitmap retVal = new Bitmap(source.Width, source.Height);
WeightedColor[,,] colorMap = GetWeightedColor(source, fi);
for(int i = 0; i < source.Width; i++)
for(int j = 0; j <source.Height; j++) {
Color fColor = GetFilteredColor(source, i, j, fi, colorMap);
retVal.SetPixel(i, j, fColor);
}
return retVal;
}

//使用范例
Bitmap fbmp = GaussianFilt(bmp, FI);
pictureBox1.Image = fbmp;

110,534

社区成员

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

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

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