• 欢迎访问web前端中文站,JavaScript,CSS3,HTML5,web前端demo
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏web前端中文站吧

Java 实现高斯模糊算法

JAVA web前端中文站 2年前 (2017-12-19) 1467次浏览 已收录 0个评论

接上篇文章《高斯模糊算法的原理》,本文我们借助 java 来实现高斯模糊算法,并使用高斯模糊算法处理实际图片。

更多精彩内容请看 web 前端中文站
http://www.lisa33xiaoq.net 可按 Ctrl + D 进行收藏

高斯模糊就是图像和高斯函数的卷积。等价于傅里叶变换后乘上高斯函数再逆变换回来(高斯函数的傅里叶变换也是高斯函数),没错就是低通滤波。实现方式可以按照卷积公式算,复杂度 O(n?m?)。考虑到二维高斯函数 G(x,y)可以写成两个一维高斯函数 G(x)和 G(y)的乘积,也就是 G(x)δ(y)和 G(y)δ(x)的卷积,也就是可以 x 和 y 两个方向分别做高斯模糊。O(n?m)卷积核很大的时候也可以用 FFT->相乘->IFFT 的方式实现,复杂度 O((m+n)?log(m+n)),不过高斯模糊的 m 也就是几个像素,就不要考虑这个了。

下面我们使用 java 来实现一个高斯模糊案例。

 import java.awt.Color; 
 import java.awt.image.BufferedImage; 
 import java.io.File; 
 import java.io.IOException; 
 import javax.imageio.ImageIO;       
 public class Test {     
 static float [][]aa;
 //计算高斯后的权重矩阵     
 final static int shu = 1;
 //高斯模糊半径     
 final static int  size = 2*shu+1;
 //数组大小          
 /** * 简单高斯模糊算** @param args* @throws IOException [参数说明]**/
 /* @return void [返回类型说明]* @exception throws [违例类型] [违例说明] */
 /* @see [类、类#方法、类#成员]      */     
 public static void main(String[] args) throws IOException{             
 aa = GaosiUtil.get2(GaosiUtil.get2DKernalData(shu,1.5f));
 //计算高斯权重         
 BufferedImage img = ImageIO.read(new File("d://1.jpg"));         
 System.out.println("图片加载成功"+img);         
 int height = img.getHeight();         
 int width = img.getWidth();                        
 int[][] matrix = new int[size][size];
 //基础矩阵         
 int[] values = new int[size*size];         
 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:/test1.jpg"));
 //保存在 d 盘为 test1.jpeg}              
 private static void readPixel(
 BufferedImage img, int x, int y, int[] pixels){
 //读取像素         
 int xStart = x - shu;         
 int yStart = y - shu;         
 int current = 0;         
 for (int i = xStart; i < size + xStart; i++){             
 for (int j = yStart; j < size + 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++){                    
 for (int j = 0; j <size; j++){                             
 matrix[i][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++){                        
 for (int j = 0; j <matrix.length; j++){                      
 Color c = new Color(matrix[i][j]);                             
 r += c.getRed()*aa[i][j];                               
 g += c.getGreen()*aa[i][j];                 
 b += c.getBlue()*aa[i][j];}}                  
 return new Color(r, g, b).getRGB();     } }   
 public class GaosiUtil {     
 //二维高斯算法具体实现     
 static float sum=0;     
 public static 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++;}          
 System.out.println("二维高斯结果");         
 for(int i=0; i<size; i++) {              
 for(int j=0; j<size; j++) {                  
 sum +=kernalData[i][j];                
 System.out.print("/t" + kernalData[i][j]);}              
 System.out.println();              
 System.out.println("/t ---------------------------");}          
 return kernalData;       }             
 public static float[][] get2(float[][] kernalData) {          
 System.out.println("均值后");          
 for(int i=0; i<kernalData.length; i++) {              
 for(int j=0; j<kernalData.length; j++) {                  
 kernalData[i][j] = kernalData[i][j]/sum;                
 System.out.print("/t" + kernalData[i][j]);              }              
 System.out.println();              
 System.out.println("/t ---------------------------");}          
 return kernalData;}}

最后看看处理后的图片效果:

Java 实现高斯模糊算法

【注:本文源自网络文章资源,由站长整理发布】


web 前端中文站 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Java 实现高斯模糊算法
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址