用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字

云代码会员    -  云代码空间

——

图像处理之高斯模糊

2013-08-24|2198阅||

摘要:图像处理之高斯模糊

高斯模糊是一种两维的卷积模糊操作,在图像完成高斯模糊相对于均值模糊来说,

计算量会增加,但是高斯模糊可以实现一些特殊效果,特别是在图像噪声(非椒盐

噪声)消去方面,更是有着非常好的效果。一维高斯公式如下:


其中x是制定[-n,n]范围的整数,sigma代表标准方差。通常取值为1.

一维高斯函数Java代码如下:

[java] view plaincopy


1         private float[] get1DKernalData(int n, float sigma) { 

2             float sigma22 = 2*sigma*sigma; 

3             float Pi2 = 2*(float)Math.PI; 

4             float sqrtSigmaPi2 = (float)Math.sqrt(Pi2) * sigma ; 

5             int size = 2*n + 1; 

6             int index = 0; 

7             float[] kernalData = new float[size]; 

8             for(int i=-n; i<=n; i++) { 

9                 float distance = i*i; 

10              kernalData[index] = (float)Math.exp((-distance)/sigma22)/sqrtSigmaPi2; 

11              System.out.println("\t" + kernalData[index]); 

12              index++; 

13          } 

14          return kernalData; 

15      } 

假设输入 n= 1, sigma = 1时,输出的Kernel数据为:

0.24197073, 0.3989423,0.24197073


两维的高斯分布函数为:

对应的Java实现代码为:

[java] view plaincopy


16      public float[][] get2DKernalData(int n, float sigma) { 

17          int size = 2*n +1; 

18          float sigma22 = 2*sigma*sigma; 

19          float sigma22PI = (float)Math.PI * sigma22; 

20          float[][] kernalData = new float[size][size]; 

21          int row = 0; 

22          for(int i=-n; i<=n; i++) { 

23              int column = 0; 

24              for(int j=-n; j<=n; j++) { 

25                  float xDistance = i*i; 

26                  float yDistance = j*j; 

27                  kernalData[row][column] = (float)Math.exp(-(xDistance + yDistance)/sigma22)/sigma22PI; 

28                  column++; 

29              } 

30              row++; 

31          } 

32            

33          for(int i=0; i<size; i++) { 

34              for(int j=0; j<size; j++) { 

35                  System.out.print("\t" + kernalData[i][j]); 

36              } 

37              System.out.println(); 

38              System.out.println("\t ---------------------------"); 

39          } 

40          return kernalData; 

41      } 

当n=1, sigma=1时对应输出的Kernel数据为:

    0.058549833   0.09653235     0.058549833

    0.09653235     0.15915494     0.09653235

    0.058549833   0.09653235     0.058549833

一个2D高斯分布的图可以表示如下:

高斯过滤在图像处理是一种低通滤波,会除去图像的细节而保持整体不变化,在图像美化和特效

方面,高斯过滤有这很多应用。高斯模糊不同于均值模糊!

 

本文实现完整的高斯模糊算法包括下面几个步骤:

1. 生成高斯操作数即Kernel Data

2. 从图像中读取像素,利用第一步的操作数,完成卷积。

3. 发现图像处理前后的最大像素值peak得出rate

4. 完成归一化操作,返回处理后像素数组


关键程序解析:

利用操作数完成卷积的代码参看以前的Blog文章《图像处理之理解卷积

完成归一化操作的算法非常简单, 主要是利用第三步计算出来的rate

[java] view plaincopy


42          // normalization 

43          float rate = inMax/outMax; 

44          System.out.println("Rate = " + rate); 

45          for(int row=0; row<height; row++) { 

46              for(int col=0; col<width; col++) { 

47                  index = row * width + col; 

48                  int rgb1 = tempoutPixels[index]; 

49      int red = (rgb1 >> 16) & 0xff; 

50      int green = (rgb1 >> 8) & 0xff; 

51      int blue = rgb1 & 0xff; 

52      red = (int)(rate * red); 

53      green = (int)(rate * green); 

54      blue = (int)(rate * blue); 

55      outPixels[index] = (rgb1 & 0xff000000) | (red << 16) | (green << 8) | blue; 

56              } 

57          } 


高斯模糊效果如下:

 - 左边为原图                                                                                                                                                            - 右边为高斯模糊之后效果,发现皱纹和手部滑了

等等现在还不最cool的效果,高斯模糊之后如果与原图像叠加会出现一种Glow的

效果,好像灯光打在图像上一样,Glow处理之后的运行效果如下:

原图:

实现Glow Filter之后的图像:

实现Glow算法只是高斯模糊输出像素值叠加原来的像素值。

[java] view plaincopy


58      int index = 0; 

59      for ( int y = 0; y < height; y++ ) { 

60          for ( int x = 0; x < width; x++ ) { 

61              int rgb1 = outPixels[index]; 

62              int r1 = (rgb1 >> 16) & 0xff; 

63              int g1 = (rgb1 >> 8) & 0xff; 

64              int b1 = rgb1 & 0xff; 

65        

66              int rgb2 = inPixels[index]; 

67              int r2 = (rgb2 >> 16) & 0xff; 

68              int g2 = (rgb2 >> 8) & 0xff; 

69              int b2 = rgb2 & 0xff; 

70        

71              r1 = PixelUtils.clamp( (int)(r1 + a * r2) ); 

72              g1 = PixelUtils.clamp( (int)(g1 + a * g2) ); 

73              b1 = PixelUtils.clamp( (int)(b1 + a * b2) ); 

74        

75              inPixels[index] = (rgb1 & 0xff000000) | (r1 << 16) | (g1 << 8) | b1; 

76              index++; 

77          } 

78      } 


转载时请注明出处!!,谢谢!

顶 1踩 0收藏
文章评论
共1 条评论 1/1页
发表评论

个人资料

  • 昵称: 云代码会员
  • 等级: 初级程序员
  • 积分: 28
  • 代码: 0 个
  • 文章: 4 篇
  • 随想: 0 条
  • 访问: 2 次
  • 关注

人气代码

    最新提问

      站长推荐