Java图像处理之高斯模糊

jopen 13年前
     <p>高斯模糊是一种两维的卷积模糊操作,在图像完成高斯模糊相对于均值模糊来说,</p>    <p>计算量会增加,但是高斯模糊可以实现一些特殊效果,特别是在图像噪声(非椒盐</p>    <p>噪声)消去方面,更是有着非常好的效果。一维高斯公式如下:</p>    <p><img border="0" alt="" src="https://simg.open-open.com/show/c716b24a35059619fc329c6201da87c2.png" /></p>    <p></p>    <p>其中x是制定[-n,n]范围的整数,sigma代表标准方差。通常取值为1. </p>    <p>一维高斯函数Java代码如下:</p>    <pre class="brush:java; toolbar: true; auto-links: false;"> private float[] get1DKernalData(int n, float sigma) {   float sigma22 = 2*sigma*sigma;   float Pi2 = 2*(float)Math.PI;   float sqrtSigmaPi2 = (float)Math.sqrt(Pi2) * sigma ;   int size = 2*n + 1;   int index = 0;   float[] kernalData = new float[size];   for(int i=-n; i<=n; i++) {    float distance = i*i;    kernalData[index] = (float)Math.exp((-distance)/sigma22)/sqrtSigmaPi2;    System.out.println("\t" + kernalData[index]);    index++;   }   return kernalData;  }</pre>    <p>假设输入 n= 1, sigma = 1时,输出的Kernel数据为:</p>    <p align="left">0.24197073, 0.3989423,<span style="white-space:pre;"> </span>0.24197073</p>    <p align="left"></p>    <p align="left">两维的高斯分布函数为:</p>    <p align="left"><img border="0" alt="" src="https://simg.open-open.com/show/c704d1c2213023a70f5a3bfa48d1cf01.png" /></p>    <p align="left"></p>    <p align="left">对应的Java实现代码为:</p>    <pre class="brush:java; toolbar: true; auto-links: false;"> public float[][] get2DKernalData(int n, float sigma) {   int size = 2*n +1;   float sigma22 = 2*sigma*sigma;   float sigma22PI = (float)Math.PI * sigma22;   float[][] kernalData = new float[size][size];   int row = 0;   for(int i=-n; i<=n; i++) {    int column = 0;    for(int j=-n; j<=n; j++) {     float xDistance = i*i;     float yDistance = j*j;     kernalData[row][column] = (float)Math.exp(-(xDistance + yDistance)/sigma22)/sigma22PI;     column++;    }    row++;   }      for(int i=0; i<size; i++) {    for(int j=0; j<size; j++) {     System.out.print("\t" + kernalData[i][j]);    }    System.out.println();    System.out.println("\t ---------------------------");   }   return kernalData;  }</pre>    <p align="left">当n=1, sigma=1时对应输出的Kernel数据为:</p>    <p align="left">    0.058549833   0.09653235     0.058549833</p>    <p align="left">    0.09653235     0.15915494     0.09653235</p>    <p align="left">    0.058549833   0.09653235     0.058549833</p>    <p align="left">一个2D高斯分布的图可以表示如下:</p>    <p align="left"><img border="0" alt="" src="https://simg.open-open.com/show/c9faba5cb94ec267f9c6457b1ad81451.png" /></p>    <p align="left"></p>    <p align="left">高斯过滤在图像处理是一种低通滤波,会除去图像的细节而保持整体不变化,在图像美化和特效</p>    <p align="left">方面,高斯过滤有这很多应用。高斯模糊不同于均值模糊!</p>    <p align="left"> </p>    <p align="left">本文实现完整的高斯模糊算法包括下面几个步骤:</p>    <p align="left">1. 生成高斯操作数即Kernel Data</p>    <p align="left">2. 从图像中读取像素,利用第一步的操作数,完成卷积。</p>    <p align="left">3. 发现图像处理前后的最大像素值peak得出rate</p>    <p align="left">4. 完成归一化操作,返回处理后像素数组</p>    <p align="left"></p>    <p align="left"><strong>关键程序解析:</strong></p>    <p align="left">利用操作数完成卷积的代码参看以前的Blog文章《<strong>图像处理之理解卷积</strong>》</p>    <p align="left">完成归一化操作的算法非常简单, 主要是利用第三步计算出来的rate</p>    <pre class="brush:java; toolbar: true; auto-links: false;">        // normalization         float rate = inMax/outMax;         System.out.println("Rate = " + rate);         for(int row=0; row<height; row++) {          for(int col=0; col<width; col++) {           index = row * width + col;           int rgb1 = tempoutPixels[index];     int red = (rgb1 >> 16) & 0xff;     int green = (rgb1 >> 8) & 0xff;     int blue = rgb1 & 0xff;     red = (int)(rate * red);     green = (int)(rate * green);     blue = (int)(rate * blue);     outPixels[index] = (rgb1 & 0xff000000) | (red << 16) | (green << 8) | blue;          }         }</pre>    <br /> 高斯模糊效果如下:    <p align="left"><img style="width:722px;height:447px;" border="0" alt="" src="https://simg.open-open.com/show/1c1b21883ed653a6c3d20e76c9de0603.png" width="943" height="615" /></p>    <p align="left"> - 左边为原图                                                                                                                                                            <br /> - 右边为高斯模糊之后效果,发现皱纹和手部滑了</p>    <p align="left"></p>    <p align="left">等等现在还不最cool的效果,高斯模糊之后如果与原图像叠加会出现一种Glow的</p>    <p align="left">效果,好像灯光打在图像上一样,Glow处理之后的运行效果如下:</p>    <p align="left">原图:</p>    <p align="left"><img border="0" alt="" src="https://simg.open-open.com/show/1d827e19bd5e2374ec2c488660f24116.png" width="640" height="480" /></p> 实现Glow Filter之后的图像:    <p align="left"><img border="0" alt="" src="https://simg.open-open.com/show/15702b96c9fed3d5419324ed7bd63b3b.png" width="685" height="531" /></p>    <p align="left"></p>    <p align="left">实现Glow算法只是高斯模糊输出像素值叠加原来的像素值。</p>    <pre class="brush:java; toolbar: true; auto-links: false;">  int index = 0;   for ( int y = 0; y < height; y++ ) {    for ( int x = 0; x < width; x++ ) {     int rgb1 = outPixels[index];     int r1 = (rgb1 >> 16) & 0xff;     int g1 = (rgb1 >> 8) & 0xff;     int b1 = rgb1 & 0xff;      int rgb2 = inPixels[index];     int r2 = (rgb2 >> 16) & 0xff;     int g2 = (rgb2 >> 8) & 0xff;     int b2 = rgb2 & 0xff;      r1 = PixelUtils.clamp( (int)(r1 + a * r2) );     g1 = PixelUtils.clamp( (int)(g1 + a * g2) );     b1 = PixelUtils.clamp( (int)(b1 + a * b2) );      inPixels[index] = (rgb1 & 0xff000000) | (r1 << 16) | (g1 << 8) | b1;     index++;    }   }</pre>    <br /> 转载:    <a href="/misc/goto?guid=4959517988681675929" target="_blank">http://blog.csdn.net/jia20003/article/details/7234741</a>    <br />