双边滤波JAVA代码实现 双边滤波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. }  
原图:

高斯滤波:

双边滤波

猜你喜欢

转载自blog.csdn.net/jacke121/article/details/80574355