双边滤波JAVA代码实现

双边滤波JAVA代码实现

[plain]  view plain  copy
  1. package test;  
  2. /**   
  3.  *  A simple and important case of bilateral filtering is shift-invariant Gaussian filtering   
  4.  *  refer to - http://graphics.ucsd.edu/~iman/Denoising/   
  5.  *  refer to - http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/MANDUCHI1/Bilateral_Filtering.html   
  6.  *  thanks to cyber   
  7.  */    
  8. import java.awt.Graphics;  
  9. import java.awt.Image;  
  10. import java.awt.image.BufferedImage;    
  11. import java.io.File;  
  12. import java.io.IOException;  
  13. import java.util.Date;  
  14.   
  15. import javax.imageio.ImageIO;  
  16.   
  17. /**  
  18.  * 双边滤波  
  19.  * 转载:http://blog.csdn.net/jia20003/article/details/7740683  
  20.  * @author Bob  
  21.  * 2017年9月9日12:25:41  
  22.  */  
  23. public class BilateralFilter extends AbstractBufferedImageOp {    
  24.     private final static double factor = -0.5d;    
  25.     private double ds; // distance sigma    
  26.     private double rs; // range sigma    
  27.     private int radius; // half length of Gaussian kernel Adobe Photoshop     
  28.     private double[][] cWeightTable;    
  29.     private double[] sWeightTable;    
  30.     private int width;    
  31.     private int height;    
  32.         
  33.     public BilateralFilter(double ds,double rs) {    
  34.         this.ds = ds;    
  35.         this.rs = rs;    
  36.     }    
  37.         
  38.     private void buildDistanceWeightTable() {    
  39.         int size = 2 * radius + 1;    
  40.         cWeightTable = new double[size][size];    
  41.         for(int semirow = -radius; semirow <= radius; semirow++) {    
  42.             for(int semicol = - radius; semicol <= radius; semicol++) {    
  43.                 // calculate Euclidean distance between center point and close pixels    
  44.                 double delta = Math.sqrt(semirow * semirow + semicol * semicol)/ds;    
  45.                 double deltaDelta = delta * delta;    
  46.                 cWeightTable[semirow+radius][semicol+radius] = Math.exp(deltaDelta * factor);    
  47.             }    
  48.         }    
  49.     }    
  50.         
  51.     /**   
  52.      * 灰度图像  
  53.      * @param row   
  54.      * @param col   
  55.      * @param inPixels   
  56.      */    
  57.     private void buildSimilarityWeightTable() {    
  58.         sWeightTable = new double[256]; // since the color scope is 0 ~ 255    
  59.         for(int i=0; i<256; i++) {    
  60.             double delta = Math.sqrt(i * i ) / rs;    
  61.             double deltaDelta = delta * delta;    
  62.             sWeightTable[i] = Math.exp(deltaDelta * factor);    
  63.         }    
  64.     }    
  65.         
  66.     public void setDistanceSigma(double ds) {    
  67.         this.ds = ds;    
  68.     }    
  69.         
  70.     public void setRangeSigma(double rs) {    
  71.         this.rs = rs;    
  72.     }    
  73.     
  74.     @Override    
  75.     public BufferedImage filter(BufferedImage src, BufferedImage dest) {    
  76.         width = src.getWidth();    
  77.         height = src.getHeight();    
  78.         //int sigmaMax = (int)Math.max(ds, rs);    
  79.         //radius = (int)Math.ceil(2 * sigmaMax);    
  80.         radius = (int)Math.max(ds, rs);    
  81.         buildDistanceWeightTable();    
  82.         buildSimilarityWeightTable();    
  83.         if ( dest == null )    
  84.             dest = createCompatibleDestImage( src, null );    
  85.     
  86.         int[] inPixels = new int[width*height];    
  87.         int[] outPixels = new int[width*height];    
  88.         getRGB( src, 0, 0, width, height, inPixels );    
  89.         int index = 0;    
  90.         double redSum = 0, greenSum = 0, blueSum = 0;    
  91.         double csRedWeight = 0, csGreenWeight = 0, csBlueWeight = 0;    
  92.         double csSumRedWeight = 0, csSumGreenWeight = 0, csSumBlueWeight = 0;    
  93.         for(int row=0; row> 24) & 0xff;    
  94.                 tr = (inPixels[index] >> 16) & 0xff;    
  95.                 tg = (inPixels[index] >> 8) & 0xff;    
  96.                 tb = inPixels[index] & 0xff;    
  97.                 int rowOffset = 0, colOffset = 0;    
  98.                 int index2 = 0;    
  99.                 int ta2 = 0, tr2 = 0, tg2 = 0, tb2 = 0;    
  100.                 for(int semirow = -radius; semirow <= radius; semirow++) {    
  101.                     for(int semicol = - radius; semicol <= radius; semicol++) {    
  102.                         if((row + semirow) >= 0 && (row + semirow) < height) {    
  103.                             rowOffset = row + semirow;    
  104.                         } else {    
  105.                             rowOffset = 0;    
  106.                         }    
  107.                             
  108.                         if((semicol + col) >= 0 && (semicol + col) < width) {    
  109.                             colOffset = col + semicol;    
  110.                         } else {    
  111.                             colOffset = 0;    
  112.                         }    
  113.                         index2 = rowOffset * width + colOffset;    
  114.                         ta2 = (inPixels[index2] >> 24) & 0xff;    
  115.                         tr2 = (inPixels[index2] >> 16) & 0xff;    
  116.                         tg2 = (inPixels[index2] >> 8) & 0xff;    
  117.                         tb2 = inPixels[index2] & 0xff;    
  118.                             
  119.                         csRedWeight = cWeightTable[semirow+radius][semicol+radius]  * sWeightTable[(Math.abs(tr2 - tr))];    
  120.                         csGreenWeight = cWeightTable[semirow+radius][semicol+radius]  * sWeightTable[(Math.abs(tg2 - tg))];    
  121.                         csBlueWeight = cWeightTable[semirow+radius][semicol+radius]  * sWeightTable[(Math.abs(tb2 - tb))];    
  122.                             
  123.                         csSumRedWeight += csRedWeight;    
  124.                         csSumGreenWeight += csGreenWeight;    
  125.                         csSumBlueWeight += csBlueWeight;    
  126.                         redSum += (csRedWeight * (double)tr2);    
  127.                         greenSum += (csGreenWeight * (double)tg2);    
  128.                         blueSum += (csBlueWeight * (double)tb2);    
  129.                     }    
  130.                 }    
  131.                     
  132.                 tr = (int)Math.floor(redSum / csSumRedWeight);    
  133.                 tg = (int)Math.floor(greenSum / csSumGreenWeight);    
  134.                 tb = (int)Math.floor(blueSum / csSumBlueWeight);    
  135.                 outPixels[index] = (ta << 24) | (clamp(tr) << 16) | (clamp(tg) << 8) | clamp(tb);    
  136.                     
  137.                 // clean value for next time...    
  138.                 redSum = greenSum = blueSum = 0;    
  139.                 csRedWeight = csGreenWeight = csBlueWeight = 0;    
  140.                 csSumRedWeight = csSumGreenWeight = csSumBlueWeight = 0;    
  141.                     
  142.             }    
  143.         }    
  144.         setRGB( dest, 0, 0, width, height, outPixels );    
  145.         return dest;    
  146.     }    
  147.         
  148.     public static int clamp(int p) {    
  149.         return p < 0 ? 0 : ((p > 255) ? 255 : p);    
  150.     }    
  151.     
  152.     public static void main(String[] args) {    
  153.         try {  
  154.             long l1=System.currentTimeMillis();  
  155.             BilateralFilter bf = new BilateralFilter(3,8);//初始化   距离西格玛 和 半径西格玛    
  156.             Image a = ImageIO.read(new File("e://old_1504255184945.png"));  
  157.             int width = a.getWidth(null);  
  158.             int height = a.getHeight(null);  
  159.   
  160.             BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);  
  161.             Graphics g = image.getGraphics();  
  162.             g.drawImage(a, 0, 0, width, height, null);  
  163.             g.dispose();  
  164.             BufferedImage dest =new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);  
  165.             image=bf.filter(image, dest);  
  166.             ImageIO.write(image, "png",new File("e:/new_" + new Date().getTime() + ".png"));  
  167.             long l2=System.currentTimeMillis();  
  168.             System.out.println(l2-l1);  
  169.         } catch (IOException e) {  
  170.             e.printStackTrace();  
  171.         }  
  172.           
  173.     }    
  174. }   
需要继承AbstractBufferedImageOp:
[plain]  view plain  copy
  1. package test;  
  2. /*  
  3. Copyright 2006 Jerry Huxtable  
  4. Licensed under the Apache License, Version 2.0 (the "License");  
  5. you may not use this file except in compliance with the License.  
  6. You may obtain a copy of the License at  
  7.    http://www.apache.org/licenses/LICENSE-2.0  
  8. Unless required by applicable law or agreed to in writing, software  
  9. distributed under the License is distributed on an "AS IS" BASIS,  
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
  11. See the License for the specific language governing permissions and  
  12. limitations under the License.  
  13.  */  
  14. import java.awt.*;  
  15. import java.awt.geom.Point2D;  
  16. import java.awt.geom.Rectangle2D;  
  17. import java.awt.image.BufferedImage;  
  18. import java.awt.image.BufferedImageOp;  
  19. import java.awt.image.ColorModel;  
  20. /**  
  21.  * A convenience class which implements those methods of BufferedImageOp which are rarely changed.  
  22.  */  
  23. public abstract class AbstractBufferedImageOp implements BufferedImageOp, Cloneable {  
  24.     public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {  
  25.         if ( dstCM == null )  
  26.             dstCM = src.getColorModel();  
  27.         return new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()), dstCM.isAlphaPremultiplied(), null);  
  28.     }  
  29.   
  30.     public Rectangle2D getBounds2D( BufferedImage src ) {  
  31.         return new Rectangle(0, 0, src.getWidth(), src.getHeight());  
  32.     }  
  33.   
  34.     public Point2D getPoint2D( Point2D srcPt, Point2D dstPt ) {  
  35.         if ( dstPt == null )  
  36.             dstPt = new Point2D.Double();  
  37.         dstPt.setLocation( srcPt.getX(), srcPt.getY() );  
  38.         return dstPt;  
  39.     }  
  40.     public RenderingHints getRenderingHints() {  
  41.         return null;  
  42.     }  
  43.     /**  
  44.      * A convenience method for getting ARGB pixels from an image. This tries to avoid the performance  
  45.      * penalty of BufferedImage.getRGB unmanaging the image.  
  46.      * @param image   a BufferedImage object  
  47.      * @param x       the left edge of the pixel block  
  48.      * @param y       the right edge of the pixel block  
  49.      * @param width   the width of the pixel arry  
  50.      * @param height  the height of the pixel arry  
  51.      * @param pixels  the array to hold the returned pixels. May be null.  
  52.      * @return the pixels  
  53.      * @see #setRGB  
  54.      */  
  55.     public int[] getRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) {  
  56.         int type = image.getType();  
  57.         if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB )  
  58.             return (int [])image.getRaster().getDataElements( x, y, width, height, pixels );  
  59.         return image.getRGB( x, y, width, height, pixels, 0, width );  
  60.     }  
  61.     /**  
  62.      * A convenience method for setting ARGB pixels in an image. This tries to avoid the performance  
  63.      * penalty of BufferedImage.setRGB unmanaging the image.  
  64.      * @param image   a BufferedImage object  
  65.      * @param x       the left edge of the pixel block  
  66.      * @param y       the right edge of the pixel block  
  67.      * @param width   the width of the pixel arry  
  68.      * @param height  the height of the pixel arry  
  69.      * @param pixels  the array of pixels to set  
  70.      * @see #getRGB  
  71.      */  
  72.     public void setRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) {  
  73.         int type = image.getType();  
  74.         if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB )  
  75.             image.getRaster().setDataElements( x, y, width, height, pixels );  
  76.         else  
  77.             image.setRGB( x, y, width, height, pixels, 0, width );  
  78.     }  
  79.     public Object clone() {  
  80.         try {  
  81.             return super.clone();  
  82.         }  
  83.         catch ( CloneNotSupportedException e ) {  
  84.             return null;  
  85.         }  
  86.     }  
  87. }  
原图:

高斯滤波:

双边滤波
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI算法网奇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值