游戏开发论坛

 找回密码
 立即注册
搜索
查看: 4330|回复: 3

高斯模糊具体算法是怎样的呀?哪位大虾给说说

[复制链接]

42

主题

418

帖子

418

积分

中级会员

Rank: 3Rank: 3

积分
418
发表于 2005-8-3 16:25:00 | 显示全部楼层 |阅读模式
如题

22

主题

371

帖子

387

积分

中级会员

Rank: 3Rank: 3

积分
387
发表于 2005-8-3 18:37:00 | 显示全部楼层

Re:高斯模糊具体算法是怎样的呀?哪位大虾给说说

不会用google么

原文地址
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;

8

主题

239

帖子

239

积分

中级会员

Rank: 3Rank: 3

积分
239
发表于 2005-8-3 22:00:00 | 显示全部楼层

Re:高斯模糊具体算法是怎样的呀?哪位大虾给说说

这个是时域上的gauss, o- 大了肯定速度慢。

最近正在搞fftw, 从频域上用gauss,效果也不错。
速度不好说,但肯定稳定。


        void _make_h(float pN[7][7], ZCF pH[256][256]){
                for(long i=0; i<7; i++){
                  for(long j=0; j<7; j++){
                          pH[j].real(pN[j]/1003.0f);
                        }
                }
        }

  void _init(){
                fft.Init_(256, 256);
               
                D3DLOCKED_RECT r;
                if(mpTex1->LockRect(0, &r, NULL, 0)<0)return;
                BYTE* pBuf = NULL;
                pBuf= (BYTE*)r.pBits;
               
                ZCF* ts = new ZCF[256*256];
                ZCF hs[256][256];
                ZCF* hs11 = new ZCF[256*256];
                ZCF* pTS = (ZCF*)ts;
                ZCF* pHS = (ZCF*)hs;               
                ZCF (*hs1)[256] = (ZCF(*)[256])hs11;

                /// hs 付值
                memset(hs, 0, sizeof(hs));
                pHS = (ZCF*)hs;
                hs[0][0].real(1);

                float a = 1003.0f;
                float pN[7][7] = {
                        0,0,1,2,1,0,0,
                                0,3,13,22,13,3,0,
                                1,13,59,97,59,13,1,
                                2,22,97,159,97,22,2,
                                1,13,59,97,59,13,1,
                                0,3,13,22,13,3,0,
                        0,0,1,2,1,0,0,
                };
                ///_make_h(pN, hs);
                fft.FFT_(hs, hs);
                ///memset(hs1, 0, sizeof(hs));


                //fft.FFT_(hs1, hs1);
                //fft.Mul_(hs, hs, hs1);

                long count = 256*256;

                {
                        pBuf= (BYTE*)r.pBits;
                        ZCF* pTS = (ZCF*)ts;
                        ////ts 付值
                        for(long i=0; i<count; i++){
                                pTS->real(*pBuf); pTS->imag(0);
                                pTS++; pBuf+=4;
                        }
                        //// FFT;
                        fft.FFT_(ts, ts);                       
                        //// mul
                        fft.Mul_(ts, hs, ts);               
                        //// InvFFT;
                        fft.InvFFT_(ts, ts);
                        pBuf = (BYTE*)r.pBits;
                        pTS = (ZCF*)ts;
                        for(i=0; i<count; i++){
                                long rr = (long)pTS->real();
                                if(rr>0xff)rr = 0xff; if(rr<0)rr = 0;
                                *pBuf = rr;
                                pBuf+=4; pTS++;
                        }
                }

                {
                        pBuf= (BYTE*)r.pBits;
                        ZCF* pTS = (ZCF*)ts;
                        ////ts 付值
                        for(long i=0; i<count; i++){
                                pBuf++;
                                pTS->real(*pBuf); pTS->imag(0);
                                pTS++; pBuf+=3;
                        }
                        //// FFT;
                        fft.FFT_(ts, ts);
                        //// mul
                        fft.Mul_(ts, hs, ts);               
                        //// InvFFT;
                        fft.InvFFT_(ts, ts);
                        pBuf = (BYTE*)r.pBits;
                        pTS = (ZCF*)ts;
                        for(i=0; i<count; i++){
                                pBuf++;
                                long rr = (long)pTS->real();
                                if(rr>0xff)rr = 0xff; if(rr<0)rr = 0;
                                *pBuf = rr;
                                pBuf+=3; pTS++;
                        }
                }
                {
                        pBuf= (BYTE*)r.pBits;
                        ZCF* pTS = (ZCF*)ts;
                        ////ts 付值
                        for(long i=0; i<count; i++){
                                pBuf+=2;
                                pTS->real(*pBuf); pTS->imag(0);
                                pTS++; pBuf+=2;
                        }
                        //// FFT;
                        fft.FFT_(ts, ts);
                        //// mul
                        fft.Mul_(ts, hs, ts);               
                        //// InvFFT;
                        fft.InvFFT_(ts, ts);
                        pBuf = (BYTE*)r.pBits;
                        pTS = (ZCF*)ts;
                        for(i=0; i<count; i++){
                                pBuf+=2;
                                long rr = (long)pTS->real();
                                if(rr>0xff)rr = 0xff; if(rr<0)rr = 0;
                                *pBuf = rr;
                                pBuf+=2; pTS++;
                        }
                }

                delete [] ts;

                mpTex1->UnlockRect(0);

42

主题

418

帖子

418

积分

中级会员

Rank: 3Rank: 3

积分
418
 楼主| 发表于 2005-8-4 08:54:00 | 显示全部楼层

Re:高斯模糊具体算法是怎样的呀?哪位大虾给说说

多谢两位^_^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-26 16:30

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表