- created by gloomyfish
卷积模糊或者卷积平滑滤波,可以消除图像噪声,也可以产生一些常见的图像模糊特效,但
是移动模糊特效也是基于卷积,相比于Box Blur, Gaussian Blur的算法,移动模糊只需要完成
一次的一维卷积,所不同的是一维卷积的完成,要基于一定的角度,而不是只是在水平和垂
直两个方向上。移动模糊的一维卷积要考虑一下三个因素:
a. 操作数的多少 - 即距离(Distance)
b.一维操作数在像素数组中的移动方向 – 即角度(Angle)
c.一维操作数的拉影效应 – 即Scale(放大和缩小程度)(Zoom/Scale)
距离和角度的关系可以用三角几何表示如下:
假设距离和角度已知的情知道中心点(目标像素点)则可以求出每个操作数的像素点坐标,假
设中心点坐标为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 时:
角度30时候的滤镜运行结果:
放缩模糊效果:
角度,距离,放缩三个参数综合效果:
关键代码解释:
计算三角几何角度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;
}
}
后记:本滤镜的基点即中心像素,是可以调整的。 感兴趣的可以自己完成,转载文章请务必注明出自本博客
分享到:
相关推荐
图形图像处理是计算机应用最广泛的领域之一。计算机图形图像处理软件的种类很多,本书在简单介绍图形图像处理基本概念的基础上,介绍了目前流行的图像处理软件Photoshop、图形绘制软件CorelDRAW和网络图像处理软件...
【项目资源】:图像处理。包含前端、后端、移动开发、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源等各种技术项目的源码。包括C++、Java、python、web、C#、EDA等项目的源码。 【适用人群】:...
【项目资源】:包含前端、后端、移动开发、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源等各种技术项目的源码。包括C++、Java、python、web、C#、EDA等项目的源码。 【适用人群】:适用于希望...
对模糊车牌图像进行清晰处理;2.对高斯模糊图像进行高斯平滑滤波处理;3.对椒盐噪声图像进行中值滤波处理;4.对雾化图像进行直方图均衡化处理;5.对模糊图像进行对比度拉伸与灰度拉伸处理;6.对运动模糊图像进行维纳...
【项目资源】:包含前端、后端、移动开发、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源等各种技术项目的源码。包括C++、Java、python、web、C#、EDA等项目的源码。 【适用人群】:适用于希望...
“魔幻画板”是一个在线图像处理、编辑、制作、合成的控件。除了继承传统的图像处理功能外,还具有图像制作、图像合成、炫彩画笔、模版加载等功能。也可以算是一个轻量级的在线PhotoShop,但是图像制作方面的应用...
这个更新简直太人性化了,以后做图像处理终于不用每次都要打开PS把Jpg转换为Bmp再操作了! 最后,再次谢谢师姐能够读完这个文档,如果还有什么问题的话就联系我吧,联系方式就在软件中了欢迎点击- -,谢谢! ======...
大眼仔旭给大家分享一款轻量级的图像处理工具。Hornil StylePix Pro 中文注册版是一个拥有许多先进功能的图形编辑程序。Stylepix是“样式图片”缩写,这意味着你的图片具有一个良好的风格。Hornil StylePix Pro 中文...
恩智浦半导体(NXP Semiconductors)发布了一款具有的运动图像处理(Motion Accurate Picture Processing... 恩智浦的移动图像处理技术采用了一种革命性的向上转变(up-conversion)技术,以及三格画面高清影像抖动
【项目资源】:图像处理。包含前端、后端、移动开发、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源等各种技术项目的源码。包括C++、Java、python、web、C#、EDA等项目的源码。 【适用人群】:...
恩智浦半导体发布了具有专利的运动精确图像处理(Motion Accurate Picture Processing)技术的视频后处理器(postprocessor),... 恩智浦的移动精确图像处理技术采用了一种革命性的向上转变(up-conversion)技术,
针对这一问题,我们提出了一种基于维纳滤波器和生成对抗网络的动态模糊图像处理方法.首先使用维纳滤波去模糊算法,通过均方差最小化去除噪声,但由于无法判断拍摄装置的移动范围并未得到预期效果.再考虑使用自由性强...
具备图像处理的基础功能如:(1)添加、复制、剪切图像(2)放大、缩小、移动图像(3)水平、垂直旋转图像(4)画笔功能:改变颜色、画笔大小(5)橡皮擦功能:改变橡皮擦大小 具备图像特效处理功能:灰度、边缘处理...
基于WinCE与S3C2440的嵌入式图像运动模糊恢复与JPEG压缩系统,王靖琰,,移动设备的快速发展, 使得图像处理与压缩系统大量地从实验室的PC 平台转移到嵌入式设备中。针对实际应用中数码相机和高空摄影等应�
移动机器人集人工智能、智能控制、信息处理、图像处理等专业技术于一体,成为当今机器人研究领域的热点之一。计算机视觉具有信息量丰富,信号探测范围广,获取信息完整等优点。近年来广泛应用于自主移动机器人领域,...
图像处理任务主要仅使用Numpy执行了以下操作,并且Pillow库仅用于加载和保存图像。1.图像旋转图像可以旋转任意角度的范围或入站角度,包括找到矩阵的中心并使用``旋转矩阵''沿中心移动。上述方法有两种旋转图像的...
IUT的图像处理车间 00 读取图像并访问像素 01 在图像上绘图 02 移动旋转并调整图像大小 03 加减 04 在图像上按位 05 掩盖图像 06 影像频道 07 色彩空间 08 直方图 09 颜色直方图 10 均衡历史 11 模糊...
在曝光时间内相机和被摄物体的相对移动会使图像产生严重的退化,有必要对退化图像进行恢复。但是由于相对运动的方向和形式的任意性,运动模糊图像的恢复是一个难以解决的问题。提出一种可以对被二维任意方向、任意形式...