偶尔在网上看到的,关于Smart blur效果的算法实现:

原图

Smart Blur效果图

算法过程如下:

1,每个像素计算一次;

2,每个像素计算以该像素为中心的半径R的正方形区域(边长2R+1)内的方差delta;

3,设定方差阈值Threshold;

4,计算原图的模糊效果图A(均值模糊或者高斯模糊);

5,如果像素P(x,y)对应的方差delta<Threshold,则按照delta/Threshold的比例将原图与A进行混合或插值,得到结果像素Q(x,y),如果delta >= Threshold,则Q(x,y) = P(x,y);

The algorithm is quite straightforward:

1. March through the image pixel by pixel.
2. For each pixel, analyze an adjacent region (say, the adjoining 5 pixel by 5 pixel square).
3. Calculate some metric of pixel variance for that region.
4. Compare the variance to some predetermined threshold value.
5. If the variance exceeds the threshold, do nothing.

6. If the variance is less than the threshold, apply blurring to the source pixel. But vary the amount of blurring according to the variance: low variance, more blurring (high variance, less blurring).

Here's the full code for SmartBlurFilter:

import java.awt.image.Kernel;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.Graphics;public class SmartBlurFilter {double SENSITIVITY = 10;int REGION_SIZE = 5;float [] kernelArray = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};Kernel kernel = new Kernel( 9,9, normalizeKernel( kernelArray ) );float [] normalizeKernel( float [] ar ) {int n = 0;for (int i = 0; i < ar.length; i++)n += ar[i];for (int i = 0; i < ar.length; i++)ar[i] /= n;return ar;}public double lerp( double a,double b, double amt) {return a + amt * ( b - a );}public double getLerpAmount( double a, double cutoff ) {if ( a > cutoff )return 1.0;return a / cutoff;}public double rmsError( int [] pixels ) {double ave = 0;for ( int i = 0; i < pixels.length; i++ )ave += ( pixels[ i ] >> 8 ) & 255;ave /= pixels.length;double diff = 0;double accumulator = 0;for ( int i = 0; i < pixels.length; i++ ) {diff = ( ( pixels[ i ] >> 8 ) & 255 ) - ave;diff *= diff;accumulator += diff;}double rms = accumulator / pixels.length;rms = Math.sqrt( rms );return rms;}int [] getSample( BufferedImage image, int x, int y, int size ) {int [] pixels = {};try {BufferedImage subimage = image.getSubimage( x,y, size, size );pixels = subimage.getRGB( 0,0,size,size,null,0,size );}catch( Exception e ) {// will arrive here if we requested// pixels outside the image bounds}return pixels;}int lerpPixel( int oldpixel, int newpixel, double amt ) {int oldRed = ( oldpixel >> 16 ) & 255;int newRed = ( newpixel >> 16 ) & 255;int red = (int) lerp( (double)oldRed, (double)newRed, amt ) & 255;int oldGreen = ( oldpixel >> 8 ) & 255;int newGreen = ( newpixel >> 8 ) & 255;int green = (int) lerp( (double)oldGreen, (double)newGreen, amt ) & 255;int oldBlue = oldpixel & 255;int newBlue = newpixel & 255;int blue = (int) lerp( (double)oldBlue, (double)newBlue, amt ) & 255;return ( red << 16 ) | ( green << 8 ) | blue;}int [] blurImage( BufferedImage image,int [] orig, int [] blur, double sensitivity ) {int newPixel = 0;double amt = 0;int size = REGION_SIZE;for ( int i = 0; i < orig.length; i++ ) {int w = image.getWidth();int [] pix = getSample( image, i % w, i / w, size );if ( pix.length == 0 )continue;amt = getLerpAmount ( rmsError( pix ), sensitivity );newPixel = lerpPixel( blur[ i ], orig[ i ],  amt );orig[ i ] = newPixel;}return orig;}public BufferedImage filter( BufferedImage image ) {ConvolveOp convolver = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP,null);// clone image into targetBufferedImage target = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());Graphics g = target.createGraphics();g.drawImage(image, 0, 0, null);g.dispose();int w = target.getWidth();int h = target.getHeight();// get source pixelsint [] pixels = image.getRGB(0, 0, w, h, null, 0, w);// blur the cloned imagetarget = convolver.filter(target, image);// get the blurred pixelsint [] blurryPixels = target.getRGB(0, 0, w, h, null, 0, w);// go thru the image and interpolate valuespixels = blurImage(image, pixels, blurryPixels, SENSITIVITY);// replace original pixels with new onesimage.setRGB(0, 0, w, h, pixels, 0, w);return image;}
}

PS------Smart blur算法实现相关推荐

  1. 数字图像算法研究---PS USM锐化算法详解

    图像USM锐化是图像处理软件中常见的功能,而PHOTOSHOP中的USM锐化相对而言效果较好,网上有很多揭秘PhotoShop USM锐化算法的文章,但是,算法效果与PS相比,差距较大,今天本人针对P ...

  2. PS 图像调整算法——阈值

    PS里面这个算法,先将图像转成灰度图像,然后根据给定的阈值,大于该阈值的像素赋值为1,小于该阈值的赋值为0. if x>T, x=1; if x<T, x=0; 原图: 效果图:阈值为 1 ...

  3. PS 滤镜——素描算法(一)

    这个算法结合高斯滤波和图层混合中的颜色减淡模式实现. 可以参考相关博客: http://blog.csdn.net/wsfdl/article/details/7610634 本文增加了一点调色,使得 ...

  4. Python: PS 图层混合算法汇总

    本文用 Python 实现了PS 中的图层混合算法,把很多常见的图层混合算法都汇总到了一起,比起以前写的算法,就是用矩阵运算代替了很耗时的for 循环,运行效率有所提升.具体的代码如下: import ...

  5. PS 图像调整算法——饱和度调整

    算法参考自 阿发伯 的博客. http://blog.csdn.net/maozefa 饱和度调整 图像的饱和度调整有很多方法,最简单的就是判断每个象素的R.G.B值是否大于或小于128,大于加上调整 ...

  6. PS 滤镜——素描算法(二)

    利用另外一种算法完成素描特效的生成. %%% Sketch clc; clear all; Image=imread('4.jpg'); Image=double(Image); [row,col,l ...

  7. PS 图像调整算法——黑白

    这个算法是参考自 阿发伯 的博客: http://blog.csdn.net/maozefa 黑白调整 Photoshop CS的图像黑白调整功能,是通过对红.黄.绿.青.蓝和洋红等6种颜色的比例调节 ...

  8. PS 图像特效算法— —渐变

    这个特效利用图层的混合原理,先设置一个遮罩层,然后用遮罩层与原图进行相乘,遮罩层不同,图像最后呈现的渐变效果也不一样. clc; clear all; close all; addpath('E:\P ...

  9. PS 图像调整算法——亮度调整

    这个算法是参考自 阿发伯 的博客,在此对 阿发伯 表示感谢, http://blog.csdn.net/maozefa 亮度调整 非线性亮度调整: 对于R,G,B三个通道,每个通道增加相同的增量. 线 ...

最新文章

  1. 具有Python&OpenCV的本地二进制模式
  2. Atom.io设置ctrl+delete
  3. JavaBean网页电子时钟
  4. div实现返回符,倒三角,椭圆+小知识收集
  5. 一个亿的融资在一家芯片初创公司可以烧多久?
  6. 东莞 小学计算机编程大赛,关于举办第二十一届东莞市中小学电脑制作活动的通知...
  7. http://www.easyui.info/archives/396.html
  8. 轻量化网络:MobileNets
  9. 更新性能服务器图片介绍,图文并茂 讲述企业版Linux性能发展史
  10. Akka向设备组添加Actor注册《thirteen》译
  11. 不错的Nginx详解
  12. idea断点调试继续执行快捷键(keymap设置了eclipse)
  13. Android利用canvas画各种图形(点、直线、弧、圆、椭圆、文字、矩形、多边形、曲线、圆角矩形...
  14. java开发面试自我介绍模板_java开发工程师面试自我介绍_应聘Java工作自我介绍...
  15. 介绍我国计算机的发展的作文600字,五年级描写电脑的说明作文600字
  16. 【供应链案例】屈臣氏是如何优化供应链系统的
  17. LeetCode动画 | 218.天际线问题
  18. Esp8266天猫精灵_RGB灯_非点灯平台
  19. [转] Scalers:刻意练习的本质就是持续行动+刻意学习
  20. C#接口与继承的区别

热门文章

  1. H3C HCL模拟器 VLAN间路由实验
  2. java碎碎碎碎碎碎
  3. cc37a_demo_C++_异常_(1)-txwtech-_打开-读取文件-写入文件-使用方法
  4. 笔记本PhotoCaptureStartTimoout
  5. Vue错误日记 ——关于Vue-Router出现esm-bundler.js?6c02:2127 Uncaught TypeError: Object(...) is no的解决方案
  6. 51单片机温度传感器
  7. 【金融】金融数学(一)——术语概念
  8. 经济金融领域简单数学建模和分析:MATLAB成本曲线方程和销售收入直线方程
  9. 介紹HyperSnap使用方法!
  10. 与游戏频繁挂钩的SCP是什么?