图像处理之积分图应用二(快速边缘保留滤波算法)

在线体验各类最新模型,更有模型 免费Token 额度领取!
立即体验
简介: 图像处理之积分图应用二(快速边缘保留滤波算法)

图像处理之积分图应用二(快速边缘保留滤波算法)

一:基本原理

传统的图像边缘保留滤波算法-如高斯双边模糊、Mean-Shift模糊等计算复杂、效率比较低,虽然有各种手段优化或者快速计算方法,当时算法相对一般码农来说理解起来比较费劲,不是一个的选择,而通过积分图像实现局部均方差的边缘保留模糊算法,计算简单而且可以做到计算量跟半径无关、跟上面提到两种边缘保留滤波(EPF)算法效率高很多。首先局部均方差滤波中计算局部均值的公式如下:

当边缘很弱的时候系数K趋近于0、该点的矫正之后的像素值就接近平均值。而当边缘很强的时候系数K趋近于1、该点的模糊之后的像素值就接近等于输入像素值。上述计算中最中意的是窗口内像素的均值与方差,计算均值可以根据积分图像很容易得到,而计算方差根据一系列的数学推导可以得到如下:

就是说可以根据积分图像通过常量次数的计算得到局部的均值与方差,让这种情况下的滤波变成一个常量时间完成的操作与窗口半径大小无关。

二:算法流程

1. 根据输入的图像计算得到积分图像,参见《图像处理之积分图像算法》

2. 根据输入的半径大小计算窗口内像素均值与方差、计算得到每个像素新的像素值

3. 循环每个个像素,重复第2步计算,得到最终的局部均方差滤波图像

三:代码实现

package com.gloomyfish.ii.demo;
 
import java.awt.image.BufferedImage;
 
/**
 * fast edge preserve filter algorithm base on integral image
 * @author zhigang jia
 * @E-mail:bfnh1998@hotmail.com
 *
 */
public class FastEPFilter extends AbstractImageOptionFilter {
  // 窗口半径大小
  private int xr;
  private int yr;
  private float sigma;
  public FastEPFilter() {
  }
  
  public void setWinsize(int radius) {
    this.xr = radius;
    this.yr = radius;
  }
 
  public float getSigma() {
    return sigma;
  }
 
  public void setSigma(float sigma) {
    this.sigma = sigma;
  }
 
  @Override
  public BufferedImage process(BufferedImage image) {
    long time = System.currentTimeMillis();
    int width = image.getWidth();
    int height = image.getHeight();
    // get image data
    int[] pixels = new int[width * height];
    int[] outPixels = new int[width * height];
    getRGB(image, 0, 0, width, height, pixels);
    int size = (xr * 2 + 1) * (yr * 2 + 1);
    int r = 0, g = 0, b = 0;
    float sigma2 = sigma*sigma;
    
    // per-calculate integral image
    byte[] R = new byte[width*height];
    byte[] G = new byte[width*height];
    byte[] B = new byte[width*height];
    getRGB(width, height, pixels, R, G, B);
    IntIntegralImage rii = new IntIntegralImage();
    rii.setImage(R);
    rii.process(width, height);
    IntIntegralImage gii = new IntIntegralImage();
    gii.setImage(G);
    gii.process(width, height);
    IntIntegralImage bii = new IntIntegralImage();
    bii.setImage(B);
    bii.process(width, height);
    int index = 0;
    
    for (int row = yr; row < height - yr; row++) {
      for (int col = xr; col < width - xr; col++) {
        index = row * width + col;
        r = ((pixels[index] >> 16) & 0xff);
        g = (pixels[index] >> 8) & 0xff;
        b = (pixels[index] & 0xff);
        
        int sr = rii.getBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));
        int sg = gii.getBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));
        int sb = bii.getBlockSum(col, row, (yr * 2 + 1), (xr * 2 + 1));
        
        float vr = rii.getBlockSquareSum(col, row, (yr * 2 + 1), (xr * 2 + 1));
        float vg = gii.getBlockSquareSum(col, row, (yr * 2 + 1), (xr * 2 + 1));
        float vb = bii.getBlockSquareSum(col, row, (yr * 2 + 1), (xr * 2 + 1));
        
        // 计算均值
        float mr = sr / size;
        float mg = sg / size;
        float mb = sb / size;
        
        // 计算方差
        float dr = (vr - (sr*sr)/size)/size;
        float dg = (vg - (sg*sg)/size)/size;
        float db = (vb - (sb*sb)/size)/size;
        
        // 计算系数K
        float kr = dr / (dr+sigma2);
        float kg = dg / (dg+sigma2);
        float kb = db / (db+sigma2);
        
        // 得到滤波后的像素值
        r = (int)((1-kr)*mr + kr*r);
        g = (int)((1-kg)*mg + kg*g);
        b = (int)((1-kb)*mb + kb*b);
        
        outPixels[row * width + col] = (0xff << 24) | (clamp(r) << 16) | (clamp(g) << 8) | clamp(b);
      }
    }
    System.out.println("FastEPFilter ->> time duration : " + (System.currentTimeMillis() - time));
    BufferedImage dest = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    setRGB(dest, 0, 0, width, height, outPixels);
    return dest;
  }
  
  /** Returns the red, green and blue planes as 3 byte arrays. */
  public void getRGB(int width, int height, int[] pixels, byte[] R, byte[] G, byte[] B) {
    int c, r, g, b;
    for (int i=0; i < width*height; i++) {
      c = pixels[i];
      r = (c&0xff0000)>>16;
      g = (c&0xff00)>>8;
      b = c&0xff;
      R[i] = (byte)r;
      G[i] = (byte)g;
      B[i] = (byte)b;
    }
  }
 
}

四:运行效果

半径设置为5,即窗口大小为5的时候,调整参数sigma的值即可得到此效果

其实很多磨皮的算法都是基于这个算法实现的,这个才是我想说的重点,

只有耐心看到此处才可以得到正确的答案。



五:参考:


http://imagej.net/Integral_Image_Filters#Variance


http://www.activovision.com/octavi/doku.php?id=integral_images

相关文章
|
10月前
|
传感器 算法
船舶运动控制,PID控制算法,反步积分控制器
船舶运动控制,PID控制算法,反步积分控制器
|
11月前
|
存储 监控 JavaScript
基于布隆过滤器的 Node.js 算法在局域网电脑桌面监控设备快速校验中的应用研究
本文探讨了布隆过滤器在局域网电脑桌面监控中的应用,分析其高效空间利用率、快速查询性能及动态扩容优势,并设计了基于MAC地址的校验模型,提供Node.js实现代码,适用于设备准入控制与重复数据过滤场景。
349 0
|
10月前
|
运维 监控 JavaScript
基于 Node.js 图结构的局域网设备拓扑分析算法在局域网内监控软件中的应用研究
本文探讨图结构在局域网监控系统中的应用,通过Node.js实现设备拓扑建模、路径分析与故障定位,提升网络可视化、可追溯性与运维效率,结合模拟实验验证其高效性与准确性。
508 3
|
10月前
|
canal 算法 vr&ar
【图像处理】基于电磁学优化算法的多阈值分割算法研究(Matlab代码实现)
【图像处理】基于电磁学优化算法的多阈值分割算法研究(Matlab代码实现)
263 1
|
10月前
|
机器学习/深度学习 资源调度 算法
遗传算法模型深度解析与实战应用
摘要 遗传算法(GA)作为一种受生物进化启发的优化算法,在复杂问题求解中展现出独特优势。本文系统介绍了GA的核心理论、实现细节和应用经验。算法通过模拟自然选择机制,利用选择、交叉、变异三大操作在解空间中进行全局搜索。与梯度下降等传统方法相比,GA不依赖目标函数的连续性或可微性,特别适合处理离散优化、多目标优化等复杂问题。文中详细阐述了染色体编码、适应度函数设计、遗传操作实现等关键技术,并提供了Python代码实现示例。实践表明,GA的成功应用关键在于平衡探索与开发,通过精心调参维持种群多样性同时确保收敛效率
|
10月前
|
机器学习/深度学习 边缘计算 人工智能
粒子群算法模型深度解析与实战应用
蒋星熠Jaxonic是一位深耕智能优化算法领域多年的技术探索者,专注于粒子群优化(PSO)算法的研究与应用。他深入剖析了PSO的数学模型、核心公式及实现方法,并通过大量实践验证了其在神经网络优化、工程设计等复杂问题上的卓越性能。本文全面展示了PSO的理论基础、改进策略与前沿发展方向,为读者提供了一份详尽的技术指南。
粒子群算法模型深度解析与实战应用
|
10月前
|
机器学习/深度学习 算法 安全
小场景大市场:猫狗识别算法在宠物智能设备中的应用
将猫狗识别算法应用于宠物智能设备,是AIoT领域的重要垂直场景。本文从核心技术、应用场景、挑战与趋势四个方面,全面解析这一融合算法、硬件与用户体验的系统工程。
803 0
|
12月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习模型、算法与应用的全方位解析
深度学习,作为人工智能(AI)的一个重要分支,已经在多个领域产生了革命性的影响。从图像识别到自然语言处理,从语音识别到自动驾驶,深度学习无处不在。本篇博客将深入探讨深度学习的模型、算法及其在各个领域的应用。
2032 3
|
12月前
|
机器学习/深度学习 人工智能 算法
AI-Compass 强化学习模块:理论到实战完整RL技术生态,涵盖10+主流框架、多智能体算法、游戏AI与金融量化应用
AI-Compass 强化学习模块:理论到实战完整RL技术生态,涵盖10+主流框架、多智能体算法、游戏AI与金融量化应用
|
11月前
|
算法 数据可视化
matlab版本粒子群算法(PSO)在路径规划中的应用
matlab版本粒子群算法(PSO)在路径规划中的应用

热门文章

最新文章