双边滤波JAVA代码实现

[plain] view plaincopy
  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. import javax.imageio.ImageIO;
  15. /**
  16. * 双边滤波
  17. * 转载:http://blog.csdn.net/jia20003/article/details/7740683
  18. * @author Bob
  19. * 2017年9月9日12:25:41
  20. */
  21. public class BilateralFilter extends AbstractBufferedImageOp {
  22. private final static double factor = -0.5d;
  23. private double ds; // distance sigma
  24. private double rs; // range sigma
  25. private int radius; // half length of Gaussian kernel Adobe Photoshop
  26. private double[][] cWeightTable;
  27. private double[] sWeightTable;
  28. private int width;
  29. private int height;
  30. public BilateralFilter(double ds,double rs) {
  31. this.ds = ds;
  32. this.rs = rs;
  33. }
  34. private void buildDistanceWeightTable() {
  35. int size = 2 * radius + 1;
  36. cWeightTable = new double[size][size];
  37. for(int semirow = -radius; semirow <= radius; semirow++) {
  38. for(int semicol = - radius; semicol <= radius; semicol++) {
  39. // calculate Euclidean distance between center point and close pixels
  40. double delta = Math.sqrt(semirow * semirow + semicol * semicol)/ds;
  41. double deltaDelta = delta * delta;
  42. cWeightTable[semirow+radius][semicol+radius] = Math.exp(deltaDelta * factor);
  43. }
  44. }
  45. }
  46. /**
  47. * 灰度图像
  48. * @param row
  49. * @param col
  50. * @param inPixels
  51. */
  52. private void buildSimilarityWeightTable() {
  53. sWeightTable = new double[256]; // since the color scope is 0 ~ 255
  54. for(int i=0; i<256; i++) {
  55. double delta = Math.sqrt(i * i ) / rs;
  56. double deltaDelta = delta * delta;
  57. sWeightTable[i] = Math.exp(deltaDelta * factor);
  58. }
  59. }
  60. public void setDistanceSigma(double ds) {
  61. this.ds = ds;
  62. }
  63. public void setRangeSigma(double rs) {
  64. this.rs = rs;
  65. }
  66. @Override
  67. public BufferedImage filter(BufferedImage src, BufferedImage dest) {
  68. width = src.getWidth();
  69. height = src.getHeight();
  70. //int sigmaMax = (int)Math.max(ds, rs);
  71. //radius = (int)Math.ceil(2 * sigmaMax);
  72. radius = (int)Math.max(ds, rs);
  73. buildDistanceWeightTable();
  74. buildSimilarityWeightTable();
  75. if ( dest == null )
  76. dest = createCompatibleDestImage( src, null );
  77. int[] inPixels = new int[width*height];
  78. int[] outPixels = new int[width*height];
  79. getRGB( src, 0, 0, width, height, inPixels );
  80. int index = 0;
  81. double redSum = 0, greenSum = 0, blueSum = 0;
  82. double csRedWeight = 0, csGreenWeight = 0, csBlueWeight = 0;
  83. double csSumRedWeight = 0, csSumGreenWeight = 0, csSumBlueWeight = 0;
  84. for(int row=0; row> 24) & 0xff;
  85. tr = (inPixels[index] >> 16) & 0xff;
  86. tg = (inPixels[index] >> 8) & 0xff;
  87. tb = inPixels[index] & 0xff;
  88. int rowOffset = 0, colOffset = 0;
  89. int index2 = 0;
  90. int ta2 = 0, tr2 = 0, tg2 = 0, tb2 = 0;
  91. for(int semirow = -radius; semirow <= radius; semirow++) {
  92. for(int semicol = - radius; semicol <= radius; semicol++) {
  93. if((row + semirow) >= 0 && (row + semirow) < height) {
  94. rowOffset = row + semirow;
  95. } else {
  96. rowOffset = 0;
  97. }
  98. if((semicol + col) >= 0 && (semicol + col) < width) {
  99. colOffset = col + semicol;
  100. } else {
  101. colOffset = 0;
  102. }
  103. index2 = rowOffset * width + colOffset;
  104. ta2 = (inPixels[index2] >> 24) & 0xff;
  105. tr2 = (inPixels[index2] >> 16) & 0xff;
  106. tg2 = (inPixels[index2] >> 8) & 0xff;
  107. tb2 = inPixels[index2] & 0xff;
  108. csRedWeight = cWeightTable[semirow+radius][semicol+radius]  * sWeightTable[(Math.abs(tr2 - tr))];
  109. csGreenWeight = cWeightTable[semirow+radius][semicol+radius]  * sWeightTable[(Math.abs(tg2 - tg))];
  110. csBlueWeight = cWeightTable[semirow+radius][semicol+radius]  * sWeightTable[(Math.abs(tb2 - tb))];
  111. csSumRedWeight += csRedWeight;
  112. csSumGreenWeight += csGreenWeight;
  113. csSumBlueWeight += csBlueWeight;
  114. redSum += (csRedWeight * (double)tr2);
  115. greenSum += (csGreenWeight * (double)tg2);
  116. blueSum += (csBlueWeight * (double)tb2);
  117. }
  118. }
  119. tr = (int)Math.floor(redSum / csSumRedWeight);
  120. tg = (int)Math.floor(greenSum / csSumGreenWeight);
  121. tb = (int)Math.floor(blueSum / csSumBlueWeight);
  122. outPixels[index] = (ta << 24) | (clamp(tr) << 16) | (clamp(tg) << 8) | clamp(tb);
  123. // clean value for next time...
  124. redSum = greenSum = blueSum = 0;
  125. csRedWeight = csGreenWeight = csBlueWeight = 0;
  126. csSumRedWeight = csSumGreenWeight = csSumBlueWeight = 0;
  127. }
  128. }
  129. setRGB( dest, 0, 0, width, height, outPixels );
  130. return dest;
  131. }
  132. public static int clamp(int p) {
  133. return p < 0 ? 0 : ((p > 255) ? 255 : p);
  134. }
  135. public static void main(String[] args) {
  136. try {
  137. long l1=System.currentTimeMillis();
  138. BilateralFilter bf = new BilateralFilter(3,8);//初始化   距离西格玛 和 半径西格玛
  139. Image a = ImageIO.read(new File("e://old_1504255184945.png"));
  140. int width = a.getWidth(null);
  141. int height = a.getHeight(null);
  142. BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
  143. Graphics g = image.getGraphics();
  144. g.drawImage(a, 0, 0, width, height, null);
  145. g.dispose();
  146. BufferedImage dest =new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
  147. image=bf.filter(image, dest);
  148. ImageIO.write(image, "png",new File("e:/new_" + new Date().getTime() + ".png"));
  149. long l2=System.currentTimeMillis();
  150. System.out.println(l2-l1);
  151. } catch (IOException e) {
  152. e.printStackTrace();
  153. }
  154. }
  155. }
需要继承AbstractBufferedImageOp:
[plain] view plaincopy
  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. public Rectangle2D getBounds2D( BufferedImage src ) {
  30. return new Rectangle(0, 0, src.getWidth(), src.getHeight());
  31. }
  32. public Point2D getPoint2D( Point2D srcPt, Point2D dstPt ) {
  33. if ( dstPt == null )
  34. dstPt = new Point2D.Double();
  35. dstPt.setLocation( srcPt.getX(), srcPt.getY() );
  36. return dstPt;
  37. }
  38. public RenderingHints getRenderingHints() {
  39. return null;
  40. }
  41. /**
  42. * A convenience method for getting ARGB pixels from an image. This tries to avoid the performance
  43. * penalty of BufferedImage.getRGB unmanaging the image.
  44. * @param image   a BufferedImage object
  45. * @param x       the left edge of the pixel block
  46. * @param y       the right edge of the pixel block
  47. * @param width   the width of the pixel arry
  48. * @param height  the height of the pixel arry
  49. * @param pixels  the array to hold the returned pixels. May be null.
  50. * @return the pixels
  51. * @see #setRGB
  52. */
  53. public int[] getRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) {
  54. int type = image.getType();
  55. if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB )
  56. return (int [])image.getRaster().getDataElements( x, y, width, height, pixels );
  57. return image.getRGB( x, y, width, height, pixels, 0, width );
  58. }
  59. /**
  60. * A convenience method for setting ARGB pixels in an image. This tries to avoid the performance
  61. * penalty of BufferedImage.setRGB unmanaging the image.
  62. * @param image   a BufferedImage object
  63. * @param x       the left edge of the pixel block
  64. * @param y       the right edge of the pixel block
  65. * @param width   the width of the pixel arry
  66. * @param height  the height of the pixel arry
  67. * @param pixels  the array of pixels to set
  68. * @see #getRGB
  69. */
  70. public void setRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) {
  71. int type = image.getType();
  72. if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB )
  73. image.getRaster().setDataElements( x, y, width, height, pixels );
  74. else
  75. image.setRGB( x, y, width, height, pixels, 0, width );
  76. }
  77. public Object clone() {
  78. try {
  79. return super.clone();
  80. }
  81. catch ( CloneNotSupportedException e ) {
  82. return null;
  83. }
  84. }
  85. }

原图:

高斯滤波:
双边滤波

双边滤波JAVA代码实现相关推荐

  1. [Python从零到壹] 五十六.图像增强及运算篇之图像平滑(中值滤波、双边滤波)

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  2. 双边滤波去噪matlab代码,双边滤波器原理及其matlab实现

    之前做过图像细节增强方面的工作,处理的是红外灰度14bit图像,图像信号由14bit AD量化后,再经FPGA处理得到,使用非锐化掩模的方法,先用双边滤波器(BF)对原图像进行滤波得到低频部分,原图和 ...

  3. opencv-12-高斯滤波-双边滤波(附C++代码实现)

    开始之前 这几天由于自己的原因没有写, 一个是因为自己懒了, 一个是感觉这里遇到点问题不想往下写了, 我们先努力结束这个章节吧, 之前介绍了比较常用而且比较好理解的均值和中值滤波, 但是呢,在例程Sm ...

  4. java 滤波算法_双边滤波算法

    1.原理 高斯滤波是以距离为权重,设计滤波模板作为滤波系数,只考虑了像素间的空间位置上的关系,因此滤波的结果会丢失边缘的信息. 高斯滤波的缺陷如下图所示:平坦区域正常滤波,图像细节没有变化,而在突变的 ...

  5. 作业总结:磨皮滤镜(双边滤波bilateralFilter)代码实现

    双边滤波是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折衷处理,同时考虑空间与信息和灰度相似性,达到保边去噪的目的,具有简单.非迭代.局部处理的特点.之所以能够达到保边去噪的滤波效 ...

  6. c语言双边滤波算法,快速双边滤波 附完整C代码

    很早之前写过<双边滤波算法的简易实现bilateralFilter>. 当时学习参考的代码来自cuda的样例. 相关代码可以参阅: https://github.com/johng12/c ...

  7. python-OpenCV自学,对高斯双边滤波,均值迁移的代码及原理浅析。

    本文对OpenCV中高斯双边模糊以及均值迁移的API及原理做浅析 文章目录 引言 一. 高斯双边模糊(高斯双边滤波) 1. 高斯双边模糊是什么,怎么实现的. 2. 代码层面 3. 参数解析 二. 均值 ...

  8. 双边滤波算法的原理、流程、实现及效果

    一.引言     双边滤波在图像处理领域中有着广泛的应用,比如去噪.去马赛克.光流估计等等,最近,比较流行的Non-Local算法也可以看成是双边滤波的一种扩展.自从Tomasi et al等人提出该 ...

  9. o(1)复杂度之双边滤波算法的原理、流程、实现及效果

    本篇博文来自博主Imageshop,打赏或想要查阅更多内容可以移步至Imageshop. 转载自:https://www.cnblogs.com/Imageshop/p/3406823.html  侵 ...

最新文章

  1. 机器学习中目标函数、损失函数、代价函数之间的区别和联系
  2. linux nm工具 查看静动态库导出函数
  3. c语言遇到非法字符,98行的四则计算器.(支持括号)加入了非法字符的检测
  4. 如何使用 Istio 进行多集群部署管理:多控制平面
  5. AndroidStudio快速生成JNI头文件
  6. getpwnam学习
  7. SQL数据库查询基础(主讲MySQL,必要时补充了SQLServer、Access兼容性说明)
  8. java数据库的量级_程序员学Python还是Java?分析了8张图后得出这个结论
  9. js 数据写到本地记事本_微信小程序连接Mysql数据库步骤
  10. 数据结构与算法:十大排序算法之冒泡排序
  11. java中的函数指的是,函数式接口在Java中是指有且仅有一个抽象方法的接口。( )...
  12. 健康窈窕美女第一课 减肥vs早餐四个关键问题。
  13. 利用MessageUI发送邮件
  14. 10. 大型网站核心架构要素
  15. Docker新手入门基础知识与实战教程
  16. matlab控制信号发生器,Matlab 跳频信号发生器
  17. 计算机用三角函数时如何用弧度制,单元备课三角函数
  18. 简述窄带调频和宽带调频的_宽带调频和窄带调频的简单区别方法
  19. Global land use changes are four times greater than previously estimated
  20. 明码(C语言)——罡罡同学

热门文章

  1. 多master mysql_使用 Rotate Master 实现MySQL 多主复制
  2. java获取keyvault_利用KeyVault来加强存储Azure Storage访问密钥管理
  3. apriori算法c++_使用Apriori进行关联分析
  4. php获取类的熟悉,php如何获取类的所有方法
  5. oracle表空间dbf文件,Oracle 11g表空间dbf文件迁移
  6. h5如何动态获取键盘高度_动态获取键盘高度
  7. 我的世界服务器修改飞行速度,《我的世界》创造模式飞行速度修改方法介绍
  8. android 盒子 airplay,iOS Airplay--Airtunes音乐播放在Android盒子和手机上的实现 (第一篇)...
  9. 一款美轮美奂的JavaScript 小项目
  10. 招聘:PingCAP大范围招募,有兴趣的小伙伴速点!