图像处理之移动模糊

简介: 图像处理之移动模糊

                                                         - created by gloomyfish


卷积模糊或者卷积平滑滤波,可以消除图像噪声,也可以产生一些常见的图像模糊特效,但


是移动模糊特效也是基于卷积,相比于Box Blur, Gaussian Blur的算法,移动模糊只需要完成


一次的一维卷积,所不同的是一维卷积的完成,要基于一定的角度,而不是只是在水平和垂


直两个方向上。移动模糊的一维卷积要考虑一下三个因素:


                    a. 操作数的多少 - 即距离(Distance)


                    b.一维操作数在像素数组中的移动方向 – 即角度(Angle)


                    c.一维操作数的拉影效应 – 即Scale(放大和缩小程度)(Zoom/Scale)


距离和角度的关系可以用三角几何表示如下:

0_1329056684jZ8c.png


假设距离和角度已知的情知道中心点(目标像素点)则可以求出每个操作数的像素点坐标,假


设中心点坐标为Base(x0, y0) 则操作数P(a, b)坐标公式可以表示如下:


            a = sinx * c +y0


            b = cosx * c +x0


放缩功能其实是在XY两个方向对图像计算得到一个一维像素结合,再求这些像素的平均值


即可,假设中心点像素为x0, y0, 防缩比率为s0则每个操作数像素点坐标可以表示为:


        a= x0-x0 * s0 + a


        b= y0-y0*so + b



原理部分的解释大概如此,下面来看一下,实际图像处理效果和源代码详细解释。


程序运行效果如下– 距离50个像素,角度 0 时:

0_1329056751qGQk.png

 

角度30时候的滤镜运行结果:


0_1329056845gHyA.png

放缩模糊效果:

0_1329056902Tz3y.png


角度,距离,放缩三个参数综合效果:

0_1329056940Cai2.png


关键代码解释:


计算三角几何角度sin与cos值的代码如下:

// calculate the trianglegeometry value
float sinAngle = (float)Math.sin(angle/180.0f * onePI);
float coseAngle = (float)Math.cos(angle/180.0f * onePI);

计算距离半径代码如下:

// calculate the distance,same as box blur
float imageRadius = (float)Math.sqrt(cx*cx + cy*cy);
float maxDistance = distance + imageRadius * zoom;

计算操作数像素坐标的代码如下:

// calculate the operatorsource pixel
if(distance > 0) {
newY = (int)Math.floor((newY+ i*sinAngle));
newX = (int)Math.floor((newX + i*coseAngle));
}

完成Scale的代码如下:

// scale the pixels
float scale = 1-zoom*f;
m11 = cx - cx*scale;
m22 = cy - cy*scale;
newY = (int)(newY * scale +m22);
newX = (int)(newX * scale + m11);

求取像素平均值,完成一维卷积的代码如下:

// blur the pixels, here
count++;
int rgb= inPixels[newY*width+newX];
ta += (rgb >> 24) & 0xff;
tr += (rgb >> 16) & 0xff;
tg += (rgb >> 8) & 0xff;
tb += rgb & 0xff;

重新填充目标像素的代码如下:

ta = clamp((int)(ta/count));
tr = clamp((int)(tr/count));
tg = clamp((int)(tg/count));
tb = clamp((int)(tb/count));
outPixels[index] = (ta << 24) | (tr<< 16) | (tg << 8) | tb;

移动模糊算法的完全源代码如下(不包含测试代码):

package com.gloomyfish.process.blur.study;
 
import java.awt.image.BufferedImage;
 
public class MotionFilter {
 
  private float distance = 0;// default;
  private float onePI = (float)Math.PI;
  private float angle = 0.0f;
  private float zoom = 0.4f;
 
  public float getDistance() {
    return distance;
  }
 
  public void setDistance(float distance) {
    this.distance = distance;
  }
 
  public float getAngle() {
    return angle;
  }
 
  public void setAngle(float angle) {
    this.angle = angle;
  }
 
  public BufferedImage filter(BufferedImage src, BufferedImage dst) {
    int width = src.getWidth();
        int height = src.getHeight();
 
        if ( dst == null )
            dst = 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;
        int cx = width/2;
        int cy = height/2;
        
        // calculate the triangle geometry value
        float sinAngle = (float)Math.sin(angle/180.0f * onePI);
        float coseAngle = (float)Math.cos(angle/180.0f * onePI);
        
        // calculate the distance, same as box blur
        float imageRadius = (float)Math.sqrt(cx*cx + cy*cy);
        float maxDistance = distance + imageRadius * zoom;
        
        int iteration = (int)maxDistance;
        for(int row=0; row<height; row++) {
          int ta = 0, tr = 0, tg = 0, tb = 0;
          for(int col=0; col<width; col++) {
            int newX= col, count = 0;
            int newY = row;
            
            // iterate the source pixels according to distance
            float m11 = 0.0f, m22 = 0.0f;
            for(int i=0; i<iteration; i++) {
              newX = col;
              newY = row;
              
              // calculate the operator source pixel
              if(distance > 0) {
                newY = (int)Math.floor((newY + i*sinAngle));
                newX = (int)Math.floor((newX + i*coseAngle));
              }
              float f = (float)i/iteration;
              if (newX < 0 || newX >= width) {
                break;
          }
          if (newY < 0 || newY >= height) {
            break;
          }
          
          // scale the pixels
          float scale = 1-zoom*f;
          m11 = cx - cx*scale;
          m22 = cy - cy*scale;
          newY = (int)(newY * scale + m22);
          newX = (int)(newX * scale + m11);
          
          // blur the pixels, here
          count++;
          int rgb = inPixels[newY*width+newX];
          ta += (rgb >> 24) & 0xff;
          tr += (rgb >> 16) & 0xff;
          tg += (rgb >> 8) & 0xff;
          tb += rgb & 0xff;
            }
            
            // fill the destination pixel with final RGB value
            if (count == 0) {
          outPixels[index] = inPixels[index];
        } else {
          ta = clamp((int)(ta/count));
          tr = clamp((int)(tr/count));
          tg = clamp((int)(tg/count));
          tb = clamp((int)(tb/count));
          outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;
        }
        index++;
          }
        }
 
        setRGB( dst, 0, 0, width, height, outPixels );
        return dst;
  }
  
  public int clamp(int c) {
    if (c < 0)
      return 0;
    if (c > 255)
      return 255;
    return c;
  }
 
}

后记:本滤镜的基点即中心像素,是可以调整的。 感兴趣的可以自己完成,转载文章请务必注明出自本博客

相关文章
|
3月前
|
人工智能 机器人 API
小龙虾OpenClaw怎么部署?阿里云轻量服务器部署OpenClaw接入飞书保姆级教程
2026年,OpenClaw(原Clawdbot、Moltbot,社区昵称“小龙虾”)凭借本地优先、多通道接入、插件化扩展的特性,成为企业与个人搭建AI自动化助理的首选工具。对于零基础用户而言,**阿里云轻量应用服务器**是部署OpenClaw的最优选择——预置官方应用镜像、无需手动配置复杂环境、成本低且稳定性强,搭配飞书接入后,可实现单聊/群聊指令交互、任务自动执行、消息智能处理等能力。
660 9
|
3月前
|
人工智能 算法 测试技术
从工具到搭档:深度拆解 Claude Code 的五大核心机制与实战心法
用了一段时间 Claude Code 之后,我越来越觉得它和传统的 AI 编程助手不是一个物种。大多数 AI 编程工具本质上是"补全器"——你写半行代码,它帮你续写后半行。而 Claude Code 更像是一个能理解整个项目的"系统级协作者",它拥有超过 200K token 的上下文窗口,意味着它可以一次性"阅读"你项目中成百上千个文件,真正理解代码之间的依赖关系。 这篇文章不是官方文档的翻译,而是我在实际使用过程中对其核心架构和最佳实践的理解与总结。
4919 1
|
人工智能 Java API
ChatClient:探索与AI模型通信的Fluent API
【11月更文挑战第22天】随着人工智能(AI)技术的飞速发展,越来越多的应用场景开始融入AI技术以提升用户体验和系统效率。在Java开发中,与AI模型通信成为了一个重要而常见的需求。为了满足这一需求,Spring AI引入了ChatClient,一个提供流畅API(Fluent API)的客户端,用于与各种AI模型进行通信。本文将深入探讨ChatClient的底层原理、业务场景、概念、功能点,并通过Java代码示例展示如何使用Fluent API与AI模型进行通信。
994 8
|
机器学习/深度学习 计算机视觉
RT-DETR改进策略【注意力机制篇】| WACV-2021 Triplet Attention 三重注意力模块 - 跨维度交互注意力机制优化
RT-DETR改进策略【注意力机制篇】| WACV-2021 Triplet Attention 三重注意力模块 - 跨维度交互注意力机制优化
460 1
RT-DETR改进策略【注意力机制篇】| WACV-2021 Triplet Attention 三重注意力模块 - 跨维度交互注意力机制优化
|
机器学习/深度学习 人工智能 自然语言处理
大语言模型的预训练[2]:GPT、GPT2、GPT3、GPT3.5、GPT4相关理论知识和模型实现、模型应用以及各个版本之间的区别详解
大语言模型的预训练[2]:GPT、GPT2、GPT3、GPT3.5、GPT4相关理论知识和模型实现、模型应用以及各个版本之间的区别详解
大语言模型的预训练[2]:GPT、GPT2、GPT3、GPT3.5、GPT4相关理论知识和模型实现、模型应用以及各个版本之间的区别详解
|
安全 数据安全/隐私保护 Android开发
深入探索iOS系统安全机制:从基础到高级
本文旨在全面解析iOS操作系统的安全特性,从基础的权限管理到高级的加密技术,揭示苹果如何构建一个既开放又安全的移动平台。我们将通过实例和分析,探讨iOS系统如何保护用户数据免受恶意软件、网络攻击的威胁,并对比Android系统在安全性方面的差异。
|
机器学习/深度学习 算法 计算机视觉
详解机器视觉性能指标相关概念——混淆矩阵、IoU、ROC曲线、mAP等
详解机器视觉性能指标相关概念——混淆矩阵、IoU、ROC曲线、mAP等
1453 0
|
测试技术 计算机视觉
【YOLOv8性能对比试验】YOLOv8n/s/m/l/x不同模型尺寸大小的实验结果对比及结论参考
【YOLOv8性能对比试验】YOLOv8n/s/m/l/x不同模型尺寸大小的实验结果对比及结论参考
|
存储 消息中间件 程序员
408操作系统学习笔记——进程与线程、处理机调度、同步与互斥(PV操作)、死锁(一)
408操作系统学习笔记——进程与线程、处理机调度、同步与互斥(PV操作)、死锁
1173 1
408操作系统学习笔记——进程与线程、处理机调度、同步与互斥(PV操作)、死锁(一)