高斯滤波器-这个我觉得讲的最好



收藏
485
110

高斯模糊编辑

高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在 Adobe Photoshop、 GIMP以及 Paint.NET等 图像处理软件中广泛使用的处理效果,通常用它来减少 图像噪声以及降低细节层次。 [1]  
中文名
高斯模糊
外文名
Gaussian Blur
别    名
高斯平滑
用    途
减少图像噪声以及降低细节层次
应    用
Adobe Photoshop等图像处理软件
开发公司
Adobe图像软件公司

目录

1简介

2原理

3实现

1简介编辑

高斯模糊(Gaussian Blur)是美国Adobe图像软件公司开发的一个图像处理软件:Adobe Photoshop(系列)中的一个 滤镜,具体的位置在:滤镜—模糊——高斯模糊!高斯模糊的原理中,它是根据 高斯曲线调节象素色值,它是有选择地模糊图像。说得直白一点,就是高斯模糊能够把某一点周围的像素色值按高斯曲线统计起来,采用数学上 加权平均的计算方法得到这条曲线的 色值,最后能够留下人物的轮廓,即曲线.是指当 Adobe Photoshop 将加权平均应用于像素时生成的钟形曲线。 [1]  
在PS中间,你应该知道所有的颜色不过都是数字,各种模糊不过都是算法。把要模糊的像素色值统计,用数学上加权平均的计算方法(高斯函数)得到色值,对范围、半径等进行模糊,大致就是高斯模糊。 [1]  

2原理编辑

周边像素的平均值
所谓"模糊",可以理解成每一个像素都取周边像素的 平均值。
高斯滤波器-这个我觉得讲的最好_第1张图片
高斯模糊原理的图解 (2张)
右图中,2是中间点,周边点都是1。
"中间点"取"周围点"的平均值,就会变成1。在数值上,这是一种"平滑化"。在图形上,就相当于产生"模糊"效果,"中间点"失去细节。
显然,计算平均值时,取值范围越大,"模糊效果"越强烈。
高斯滤波器-这个我觉得讲的最好_第2张图片
左图分别是原图、模糊半径3像素、模糊半径10像素的效果。模糊半径越大,图像就越模糊。从数值角度看,就是数值越平滑。
接下来的问题就是,既然每个点都要取周边像素的平均值,那么应该如何分配 权重呢?
如果使用简单平均,显然不是很合理,因为图像都是连续的,越靠近的点关系越密切,越远离的点关系越疏远。因此,加权平均更合理,距离越近的点权重越大,距离越远的点权重越小。 [3]  
正态分布的权重
高斯滤波器-这个我觉得讲的最好_第3张图片
正态分布显然是一种可取的权重分配模式。
在图形上,正态分布是一种钟形曲线,越接近中心,取值越大,越远离中心,取值越小。
计算平均值的时候,我们只需要将"中心点"作为原点,其他点按照其在正态曲线上的位置,分配权重,就可以得到一个加权平均值。 [3]  
高斯函数
高斯滤波器-这个我觉得讲的最好_第4张图片
上面的正态分布是 一维的,图像都是 二维的,所以我们需要二维的 正态分布。
正态分布的密度函数叫做"高斯函数"(Gaussian function)。它的一维形式是:
一维形式 一维形式[2]
其中,μ是x的均值,σ是x的方差。因为计算平均值的时候,中心点就是原
进一步推导 进一步推导[2]
点,所以μ等于0。
二维高斯函数 二维高斯函数[2]
根据一维高斯函数,可以推导得到二维高斯函数:
有了这个函数 ,就可以计算每个点的权重了。 [3]  
权重矩阵
假定中心点的坐标是(0,0),那么距离它最近的8个点的坐标如下:
高斯滤波器-这个我觉得讲的最好_第5张图片
权重矩阵 (3张)
更远的点以此类推。
为了计算权重 矩阵,需要设定σ的值。假定σ=1.5,则模糊半径为1的权重矩阵如下:
这9个点的权重总和等于0.4787147,如果只计算这9个点的加权平均,还必须让它们的权重之和等于1,因此上面9个值还要分别除以0.4787147,得到最终的权重矩阵。 [3]  
计算高斯模糊
高斯滤波器-这个我觉得讲的最好_第6张图片
计算高斯模糊 (3张)
有了权重矩阵,就可以计算高斯模糊的值了。假设现有9个像素点,灰度值(0-255)如下:
每个点乘以自己的权重值:
得到
将这9个值加起来,就是中心点的高斯模糊的值。
对所有点重复这个过程,就得到了高斯模糊后的图像。如果原图是彩色图片,可以对RGB三个通道分别做高斯模糊。 [3]  
高斯模糊矩阵示例表
这是一个计算 σ = 0.84089642 的 高斯分布生成的示例 矩阵。注意中心元素 [4,4]] 处有最大值,随着距离中心越远数值对称地减小。
0.00000067
0.00002292
0.00019117
0.00038771
0.00019117
0.00002292
0.00000067
0.00002292
0.00078633
0.00655965
0.01330373
0.00655965
0.00078633
0.00002292
0.00019117
0.00655965
0.05472157
0.11098164
0.05472157
0.00655965
0.00019117
0.00038771
0.01330373
0.11098164
0.22508352
0.11098164
0.01330373
0.00038771
0.00019117
0.00655965
0.05472157
0.11098164
0.05472157
0.00655965
0.00019117
0.00002292
0.00078633
0.00655965
0.01330373
0.00655965
0.00078633
0.00002292
0.00000067
0.00002292
0.00019117
0.00038771
0.00019117
0.00002292
0.00000067
注意中心处的 0.22508352 比 3σ 外的 0.00019117 大 1177 倍。 [1]  

3实现编辑

Java程序实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import  java.awt.Color;
import  java.awt.image.BufferedImage;
import  java.io.File;
import  java.io.IOException;
import  javax.imageio.ImageIO;
 
public   class  Test {
 
  /**
 * 简单高斯模糊算法
 *
 * @param args
 * @throws IOException [参数说明]
 *
 * @return void [返回类型说明]
 * @exception throws [违例类型] [违例说明]
 * @see [类、类#方法、类#成员]
 */
  public   static   void  main(String[] args)
  throws  IOException {
 BufferedImage img = ImageIO.read( new  File( "d:\\My Documents\\psb.jpg" ));
 System.out.println(img);
  int  height = img.getHeight();
  int  width = img.getWidth();
  int [][] matrix =  new   int [ 3 ][ 3 ];
  int [] values =  new   int [ 9 ];
  for  ( int  i =  0 ; i < width; i++) {
  for  ( int  j =  0 ; j < height; j++) {
 readPixel(img, i, j, values);
 fillMatrix(matrix, values);
 img.setRGB(i, j, avgMatrix(matrix));
 }
 }
 ImageIO.write(img,  "jpeg" ,  new  File( "d:/test.jpg" )); //保存在d盘为test.jpeg文件
 }
 
  private   static   void  readPixel(BufferedImage img,  int  x,  int  y,  int [] pixels) {
  int  xStart = x -  1 ;
  int  yStart = y -  1 ;
  int  current =  0 ;
  for  ( int  i = xStart; i <  3  + xStart; i++) {
  for  ( int  j = yStart; j <  3  + yStart; j++) {
  int  tx = i;
  if  (tx <  0 ) {
 tx = -tx;
 }  else   if  (tx >= img.getWidth()) {
 tx = x;
 }
 
  int  ty = j;
  if  (ty <  0 ) {
 ty = -ty;
 }  else   if  (ty >= img.getHeight()) {
 ty = y;
 }
 pixels[current++] = img.getRGB(tx, ty);
 }
 }
 }
 
  private   static   void  fillMatrix( int [][] matrix,  int ... values) {
  int  filled =  0 ;
  for  ( int  i =  0 ; i < matrix.length; i++) {
  int [] x = matrix[i];
  for  ( int  j =  0 ; j < x.length; j++) {
 x[j] = values[filled++];
 }
 }
 }
 
  private   static   int  avgMatrix( int [][] matrix) {
  int  r =  0 ;
  int  g =  0 ;
  int  b =  0 ;
  for  ( int  i =  0 ; i < matrix.length; i++) {
  int [] x = matrix[i];
  for  ( int  j =  0 ; j < x.length; j++) {
  if  (j ==  1 ) {
  continue ;
 }
 Color c =  new  Color(x[j]);
 r += c.getRed();
 g += c.getGreen();
 b += c.getBlue();
 }
 }
  return   new  Color(r /  8 , g /  8 , b /  8 ).getRGB();
 }
}
收藏
485
110

你可能感兴趣的:(编程之美,图形视觉UI,数学)