双边滤波JAVA代码实现
双边滤波JAVA代码实现
- package test;
- /**
- * A simple and important case of bilateral filtering is shift-invariant Gaussian filtering
- * refer to - http://graphics.ucsd.edu/~iman/Denoising/
- * refer to - http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/MANDUCHI1/Bilateral_Filtering.html
- * thanks to cyber
- */
- import java.awt.Graphics;
- import java.awt.Image;
- import java.awt.image.BufferedImage;
- import java.io.File;
- import java.io.IOException;
- import java.util.Date;
- import javax.imageio.ImageIO;
- /**
- * 双边滤波
- * 转载:http://blog.csdn.net/jia20003/article/details/7740683
- * @author Bob
- * 2017年9月9日12:25:41
- */
- public class BilateralFilter extends AbstractBufferedImageOp {
- private final static double factor = -0.5d;
- private double ds; // distance sigma
- private double rs; // range sigma
- private int radius; // half length of Gaussian kernel Adobe Photoshop
- private double[][] cWeightTable;
- private double[] sWeightTable;
- private int width;
- private int height;
- public BilateralFilter(double ds,double rs) {
- this.ds = ds;
- this.rs = rs;
- }
- private void buildDistanceWeightTable() {
- int size = 2 * radius + 1;
- cWeightTable = new double[size][size];
- for(int semirow = -radius; semirow <= radius; semirow++) {
- for(int semicol = - radius; semicol <= radius; semicol++) {
- // calculate Euclidean distance between center point and close pixels
- double delta = Math.sqrt(semirow * semirow + semicol * semicol)/ds;
- double deltaDelta = delta * delta;
- cWeightTable[semirow+radius][semicol+radius] = Math.exp(deltaDelta * factor);
- }
- }
- }
- /**
- * 灰度图像
- * @param row
- * @param col
- * @param inPixels
- */
- private void buildSimilarityWeightTable() {
- sWeightTable = new double[256]; // since the color scope is 0 ~ 255
- for(int i=0; i<256; i++) {
- double delta = Math.sqrt(i * i ) / rs;
- double deltaDelta = delta * delta;
- sWeightTable[i] = Math.exp(deltaDelta * factor);
- }
- }
- public void setDistanceSigma(double ds) {
- this.ds = ds;
- }
- public void setRangeSigma(double rs) {
- this.rs = rs;
- }
- @Override
- public BufferedImage filter(BufferedImage src, BufferedImage dest) {
- width = src.getWidth();
- height = src.getHeight();
- //int sigmaMax = (int)Math.max(ds, rs);
- //radius = (int)Math.ceil(2 * sigmaMax);
- radius = (int)Math.max(ds, rs);
- buildDistanceWeightTable();
- buildSimilarityWeightTable();
- if ( dest == null )
- dest = createCompatibleDestImage( src, null );
- int[] inPixels = new int[width*height];
- int[] outPixels = new int[width*height];
- getRGB( src, 0, 0, width, height, inPixels );
- int index = 0;
- double redSum = 0, greenSum = 0, blueSum = 0;
- double csRedWeight = 0, csGreenWeight = 0, csBlueWeight = 0;
- double csSumRedWeight = 0, csSumGreenWeight = 0, csSumBlueWeight = 0;
- for(int row=0; row> 24) & 0xff;
- tr = (inPixels[index] >> 16) & 0xff;
- tg = (inPixels[index] >> 8) & 0xff;
- tb = inPixels[index] & 0xff;
- int rowOffset = 0, colOffset = 0;
- int index2 = 0;
- int ta2 = 0, tr2 = 0, tg2 = 0, tb2 = 0;
- for(int semirow = -radius; semirow <= radius; semirow++) {
- for(int semicol = - radius; semicol <= radius; semicol++) {
- if((row + semirow) >= 0 && (row + semirow) < height) {
- rowOffset = row + semirow;
- } else {
- rowOffset = 0;
- }
- if((semicol + col) >= 0 && (semicol + col) < width) {
- colOffset = col + semicol;
- } else {
- colOffset = 0;
- }
- index2 = rowOffset * width + colOffset;
- ta2 = (inPixels[index2] >> 24) & 0xff;
- tr2 = (inPixels[index2] >> 16) & 0xff;
- tg2 = (inPixels[index2] >> 8) & 0xff;
- tb2 = inPixels[index2] & 0xff;
- csRedWeight = cWeightTable[semirow+radius][semicol+radius] * sWeightTable[(Math.abs(tr2 - tr))];
- csGreenWeight = cWeightTable[semirow+radius][semicol+radius] * sWeightTable[(Math.abs(tg2 - tg))];
- csBlueWeight = cWeightTable[semirow+radius][semicol+radius] * sWeightTable[(Math.abs(tb2 - tb))];
- csSumRedWeight += csRedWeight;
- csSumGreenWeight += csGreenWeight;
- csSumBlueWeight += csBlueWeight;
- redSum += (csRedWeight * (double)tr2);
- greenSum += (csGreenWeight * (double)tg2);
- blueSum += (csBlueWeight * (double)tb2);
- }
- }
- tr = (int)Math.floor(redSum / csSumRedWeight);
- tg = (int)Math.floor(greenSum / csSumGreenWeight);
- tb = (int)Math.floor(blueSum / csSumBlueWeight);
- outPixels[index] = (ta << 24) | (clamp(tr) << 16) | (clamp(tg) << 8) | clamp(tb);
- // clean value for next time...
- redSum = greenSum = blueSum = 0;
- csRedWeight = csGreenWeight = csBlueWeight = 0;
- csSumRedWeight = csSumGreenWeight = csSumBlueWeight = 0;
- }
- }
- setRGB( dest, 0, 0, width, height, outPixels );
- return dest;
- }
- public static int clamp(int p) {
- return p < 0 ? 0 : ((p > 255) ? 255 : p);
- }
- public static void main(String[] args) {
- try {
- long l1=System.currentTimeMillis();
- BilateralFilter bf = new BilateralFilter(3,8);//初始化 距离西格玛 和 半径西格玛
- Image a = ImageIO.read(new File("e://old_1504255184945.png"));
- int width = a.getWidth(null);
- int height = a.getHeight(null);
- BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
- Graphics g = image.getGraphics();
- g.drawImage(a, 0, 0, width, height, null);
- g.dispose();
- BufferedImage dest =new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
- image=bf.filter(image, dest);
- ImageIO.write(image, "png",new File("e:/new_" + new Date().getTime() + ".png"));
- long l2=System.currentTimeMillis();
- System.out.println(l2-l1);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- package test;
- /*
- Copyright 2006 Jerry Huxtable
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- import java.awt.*;
- import java.awt.geom.Point2D;
- import java.awt.geom.Rectangle2D;
- import java.awt.image.BufferedImage;
- import java.awt.image.BufferedImageOp;
- import java.awt.image.ColorModel;
- /**
- * A convenience class which implements those methods of BufferedImageOp which are rarely changed.
- */
- public abstract class AbstractBufferedImageOp implements BufferedImageOp, Cloneable {
- public BufferedImage createCompatibleDestImage(BufferedImage src, ColorModel dstCM) {
- if ( dstCM == null )
- dstCM = src.getColorModel();
- return new BufferedImage(dstCM, dstCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()), dstCM.isAlphaPremultiplied(), null);
- }
- public Rectangle2D getBounds2D( BufferedImage src ) {
- return new Rectangle(0, 0, src.getWidth(), src.getHeight());
- }
- public Point2D getPoint2D( Point2D srcPt, Point2D dstPt ) {
- if ( dstPt == null )
- dstPt = new Point2D.Double();
- dstPt.setLocation( srcPt.getX(), srcPt.getY() );
- return dstPt;
- }
- public RenderingHints getRenderingHints() {
- return null;
- }
- /**
- * A convenience method for getting ARGB pixels from an image. This tries to avoid the performance
- * penalty of BufferedImage.getRGB unmanaging the image.
- * @param image a BufferedImage object
- * @param x the left edge of the pixel block
- * @param y the right edge of the pixel block
- * @param width the width of the pixel arry
- * @param height the height of the pixel arry
- * @param pixels the array to hold the returned pixels. May be null.
- * @return the pixels
- * @see #setRGB
- */
- public int[] getRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) {
- int type = image.getType();
- if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB )
- return (int [])image.getRaster().getDataElements( x, y, width, height, pixels );
- return image.getRGB( x, y, width, height, pixels, 0, width );
- }
- /**
- * A convenience method for setting ARGB pixels in an image. This tries to avoid the performance
- * penalty of BufferedImage.setRGB unmanaging the image.
- * @param image a BufferedImage object
- * @param x the left edge of the pixel block
- * @param y the right edge of the pixel block
- * @param width the width of the pixel arry
- * @param height the height of the pixel arry
- * @param pixels the array of pixels to set
- * @see #getRGB
- */
- public void setRGB( BufferedImage image, int x, int y, int width, int height, int[] pixels ) {
- int type = image.getType();
- if ( type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB )
- image.getRaster().setDataElements( x, y, width, height, pixels );
- else
- image.setRGB( x, y, width, height, pixels, 0, width );
- }
- public Object clone() {
- try {
- return super.clone();
- }
- catch ( CloneNotSupportedException e ) {
- return null;
- }
- }
- }
原图:
双边滤波JAVA代码实现相关推荐
- [Python从零到壹] 五十六.图像增强及运算篇之图像平滑(中值滤波、双边滤波)
欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...
- 双边滤波去噪matlab代码,双边滤波器原理及其matlab实现
之前做过图像细节增强方面的工作,处理的是红外灰度14bit图像,图像信号由14bit AD量化后,再经FPGA处理得到,使用非锐化掩模的方法,先用双边滤波器(BF)对原图像进行滤波得到低频部分,原图和 ...
- opencv-12-高斯滤波-双边滤波(附C++代码实现)
开始之前 这几天由于自己的原因没有写, 一个是因为自己懒了, 一个是感觉这里遇到点问题不想往下写了, 我们先努力结束这个章节吧, 之前介绍了比较常用而且比较好理解的均值和中值滤波, 但是呢,在例程Sm ...
- java 滤波算法_双边滤波算法
1.原理 高斯滤波是以距离为权重,设计滤波模板作为滤波系数,只考虑了像素间的空间位置上的关系,因此滤波的结果会丢失边缘的信息. 高斯滤波的缺陷如下图所示:平坦区域正常滤波,图像细节没有变化,而在突变的 ...
- 作业总结:磨皮滤镜(双边滤波bilateralFilter)代码实现
双边滤波是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折衷处理,同时考虑空间与信息和灰度相似性,达到保边去噪的目的,具有简单.非迭代.局部处理的特点.之所以能够达到保边去噪的滤波效 ...
- c语言双边滤波算法,快速双边滤波 附完整C代码
很早之前写过<双边滤波算法的简易实现bilateralFilter>. 当时学习参考的代码来自cuda的样例. 相关代码可以参阅: https://github.com/johng12/c ...
- python-OpenCV自学,对高斯双边滤波,均值迁移的代码及原理浅析。
本文对OpenCV中高斯双边模糊以及均值迁移的API及原理做浅析 文章目录 引言 一. 高斯双边模糊(高斯双边滤波) 1. 高斯双边模糊是什么,怎么实现的. 2. 代码层面 3. 参数解析 二. 均值 ...
- 双边滤波算法的原理、流程、实现及效果
一.引言 双边滤波在图像处理领域中有着广泛的应用,比如去噪.去马赛克.光流估计等等,最近,比较流行的Non-Local算法也可以看成是双边滤波的一种扩展.自从Tomasi et al等人提出该 ...
- o(1)复杂度之双边滤波算法的原理、流程、实现及效果
本篇博文来自博主Imageshop,打赏或想要查阅更多内容可以移步至Imageshop. 转载自:https://www.cnblogs.com/Imageshop/p/3406823.html 侵 ...
最新文章
- 机器学习中目标函数、损失函数、代价函数之间的区别和联系
- linux nm工具 查看静动态库导出函数
- c语言遇到非法字符,98行的四则计算器.(支持括号)加入了非法字符的检测
- 如何使用 Istio 进行多集群部署管理:多控制平面
- AndroidStudio快速生成JNI头文件
- getpwnam学习
- SQL数据库查询基础(主讲MySQL,必要时补充了SQLServer、Access兼容性说明)
- java数据库的量级_程序员学Python还是Java?分析了8张图后得出这个结论
- js 数据写到本地记事本_微信小程序连接Mysql数据库步骤
- 数据结构与算法:十大排序算法之冒泡排序
- java中的函数指的是,函数式接口在Java中是指有且仅有一个抽象方法的接口。( )...
- 健康窈窕美女第一课 减肥vs早餐四个关键问题。
- 利用MessageUI发送邮件
- 10. 大型网站核心架构要素
- Docker新手入门基础知识与实战教程
- matlab控制信号发生器,Matlab 跳频信号发生器
- 计算机用三角函数时如何用弧度制,单元备课三角函数
- 简述窄带调频和宽带调频的_宽带调频和窄带调频的简单区别方法
- Global land use changes are four times greater than previously estimated
- 明码(C语言)——罡罡同学
热门文章
- 多master mysql_使用 Rotate Master 实现MySQL 多主复制
- java获取keyvault_利用KeyVault来加强存储Azure Storage访问密钥管理
- apriori算法c++_使用Apriori进行关联分析
- php获取类的熟悉,php如何获取类的所有方法
- oracle表空间dbf文件,Oracle 11g表空间dbf文件迁移
- h5如何动态获取键盘高度_动态获取键盘高度
- 我的世界服务器修改飞行速度,《我的世界》创造模式飞行速度修改方法介绍
- android 盒子 airplay,iOS Airplay--Airtunes音乐播放在Android盒子和手机上的实现 (第一篇)...
- 一款美轮美奂的JavaScript 小项目
- 招聘:PingCAP大范围招募,有兴趣的小伙伴速点!