图像处理------高斯模糊
2015-07-24 09:32
246 查看
高斯模糊是一种两维的卷积模糊操作,在图像完成高斯模糊相对于均值模糊来说,计算量会增加,但是高斯模糊可以实现一些特殊效果,特别是在图像噪声(非椒盐噪声)消去方面,更是有着非常好的效果。一维高斯公式如下:
![](http://hi.csdn.net/attachment/201202/5/0_13284239677foc.gif)
其中x是制定[-n,n]范围的整数,sigma代表标准方差。通常取值为1.一维高斯函数Java代码如下:[java] view plaincopyprivate float[] get1DKernalData(int n, float sigma) {
float sigma22 = 2*sigma*sigma;
float Pi2 = 2*(float)Math.PI;
float sqrtSigmaPi2 = (float)Math.sqrt(Pi2) * sigma ;
int size = 2*n + 1;
int index = 0;
float[] kernalData = new float[size];
for(int i=-n; i<=n; i++) {
float distance = i*i;
kernalData[index] = (float)Math.exp((-distance)/sigma22)/sqrtSigmaPi2;
System.out.println("\t" + kernalData[index]);
index++;
}
return kernalData;
}
假设输入 n= 1, sigma = 1时,输出的Kernel数据为:0.24197073, 0.3989423,0.24197073
两维的高斯分布函数为:
![](http://hi.csdn.net/attachment/201202/5/0_132842411591QN.gif)
对应的Java实现代码为:[java] view plaincopypublic float[][] get2DKernalData(int n, float sigma) {
int size = 2*n +1;
float sigma22 = 2*sigma*sigma;
float sigma22PI = (float)Math.PI * sigma22;
float[][] kernalData = new float[size][size];
int row = 0;
for(int i=-n; i<=n; i++) {
int column = 0;
for(int j=-n; j<=n; j++) {
float xDistance = i*i;
float yDistance = j*j;
kernalData[row][column] = (float)Math.exp(-(xDistance + yDistance)/sigma22)/sigma22PI;
column++;
}
row++;
}
for(int i=0; i<size; i++) {
for(int j=0; j<size; j++) {
System.out.print("\t" + kernalData[i][j]);
}
System.out.println();
System.out.println("\t ---------------------------");
}
return kernalData;
}
当n=1, sigma=1时对应输出的Kernel数据为: 0.058549833 0.09653235 0.058549833 0.09653235 0.15915494 0.09653235 0.058549833 0.09653235 0.058549833一个2D高斯分布的图可以表示如下:
![](http://hi.csdn.net/attachment/201202/5/0_13284242238wO8.gif)
高斯过滤在图像处理是一种低通滤波,会除去图像的细节而保持整体不变化,在图像美化和特效方面,高斯过滤有这很多应用。高斯模糊不同于均值模糊! 本文实现完整的高斯模糊算法包括下面几个步骤:1. 生成高斯操作数即Kernel Data2. 从图像中读取像素,利用第一步的操作数,完成卷积。3. 发现图像处理前后的最大像素值peak得出rate4. 完成归一化操作,返回处理后像素数组
关键程序解析:利用操作数完成卷积的代码参看以前的Blog文章《图像处理之理解卷积》完成归一化操作的算法非常简单, 主要是利用第三步计算出来的rate[java] view plaincopy // normalization
float rate = inMax/outMax;
System.out.println("Rate = " + rate);
for(int row=0; row<height; row++) {
for(int col=0; col<width; col++) {
index = row * width + col;
int rgb1 = tempoutPixels[index];
int red = (rgb1 >> 16) & 0xff;
int green = (rgb1 >> 8) & 0xff;
int blue = rgb1 & 0xff;
red = (int)(rate * red);
green = (int)(rate * green);
blue = (int)(rate * blue);
outPixels[index] = (rgb1 & 0xff000000) | (red << 16) | (green << 8) | blue;
}
}
高斯模糊效果如下:
![](http://hi.csdn.net/attachment/201202/5/0_1328424429dWPh.gif)
- 左边为原图 - 右边为高斯模糊之后效果,发现皱纹和手部滑了等等现在还不最cool的效果,高斯模糊之后如果与原图像叠加会出现一种Glow的效果,好像灯光打在图像上一样,Glow处理之后的运行效果如下:原图:
![](http://hi.csdn.net/attachment/201202/5/0_13284245408c4Z.gif)
实现Glow Filter之后的图像:
![](http://hi.csdn.net/attachment/201202/5/0_1328424693c17f.gif)
实现Glow算法只是高斯模糊输出像素值叠加原来的像素值。[java] view plaincopyint index = 0;
for ( int y = 0; y < height; y++ ) {
for ( int x = 0; x < width; x++ ) {
int rgb1 = outPixels[index];
int r1 = (rgb1 >> 16) & 0xff;
int g1 = (rgb1 >> 8) & 0xff;
int b1 = rgb1 & 0xff;
int rgb2 = inPixels[index];
int r2 = (rgb2 >> 16) & 0xff;
int g2 = (rgb2 >> 8) & 0xff;
int b2 = rgb2 & 0xff;
r1 = PixelUtils.clamp( (int)(r1 + a * r2) );
g1 = PixelUtils.clamp( (int)(g1 + a * g2) );
b1 = PixelUtils.clamp( (int)(b1 + a * b2) );
inPixels[index] = (rgb1 & 0xff000000) | (r1 << 16) | (g1 << 8) | b1;
index++;
}
}
![](http://hi.csdn.net/attachment/201202/5/0_13284239677foc.gif)
其中x是制定[-n,n]范围的整数,sigma代表标准方差。通常取值为1.一维高斯函数Java代码如下:[java] view plaincopyprivate float[] get1DKernalData(int n, float sigma) {
float sigma22 = 2*sigma*sigma;
float Pi2 = 2*(float)Math.PI;
float sqrtSigmaPi2 = (float)Math.sqrt(Pi2) * sigma ;
int size = 2*n + 1;
int index = 0;
float[] kernalData = new float[size];
for(int i=-n; i<=n; i++) {
float distance = i*i;
kernalData[index] = (float)Math.exp((-distance)/sigma22)/sqrtSigmaPi2;
System.out.println("\t" + kernalData[index]);
index++;
}
return kernalData;
}
假设输入 n= 1, sigma = 1时,输出的Kernel数据为:0.24197073, 0.3989423,0.24197073
两维的高斯分布函数为:
![](http://hi.csdn.net/attachment/201202/5/0_132842411591QN.gif)
对应的Java实现代码为:[java] view plaincopypublic float[][] get2DKernalData(int n, float sigma) {
int size = 2*n +1;
float sigma22 = 2*sigma*sigma;
float sigma22PI = (float)Math.PI * sigma22;
float[][] kernalData = new float[size][size];
int row = 0;
for(int i=-n; i<=n; i++) {
int column = 0;
for(int j=-n; j<=n; j++) {
float xDistance = i*i;
float yDistance = j*j;
kernalData[row][column] = (float)Math.exp(-(xDistance + yDistance)/sigma22)/sigma22PI;
column++;
}
row++;
}
for(int i=0; i<size; i++) {
for(int j=0; j<size; j++) {
System.out.print("\t" + kernalData[i][j]);
}
System.out.println();
System.out.println("\t ---------------------------");
}
return kernalData;
}
当n=1, sigma=1时对应输出的Kernel数据为: 0.058549833 0.09653235 0.058549833 0.09653235 0.15915494 0.09653235 0.058549833 0.09653235 0.058549833一个2D高斯分布的图可以表示如下:
![](http://hi.csdn.net/attachment/201202/5/0_13284242238wO8.gif)
高斯过滤在图像处理是一种低通滤波,会除去图像的细节而保持整体不变化,在图像美化和特效方面,高斯过滤有这很多应用。高斯模糊不同于均值模糊! 本文实现完整的高斯模糊算法包括下面几个步骤:1. 生成高斯操作数即Kernel Data2. 从图像中读取像素,利用第一步的操作数,完成卷积。3. 发现图像处理前后的最大像素值peak得出rate4. 完成归一化操作,返回处理后像素数组
关键程序解析:利用操作数完成卷积的代码参看以前的Blog文章《图像处理之理解卷积》完成归一化操作的算法非常简单, 主要是利用第三步计算出来的rate[java] view plaincopy // normalization
float rate = inMax/outMax;
System.out.println("Rate = " + rate);
for(int row=0; row<height; row++) {
for(int col=0; col<width; col++) {
index = row * width + col;
int rgb1 = tempoutPixels[index];
int red = (rgb1 >> 16) & 0xff;
int green = (rgb1 >> 8) & 0xff;
int blue = rgb1 & 0xff;
red = (int)(rate * red);
green = (int)(rate * green);
blue = (int)(rate * blue);
outPixels[index] = (rgb1 & 0xff000000) | (red << 16) | (green << 8) | blue;
}
}
高斯模糊效果如下:
![](http://hi.csdn.net/attachment/201202/5/0_1328424429dWPh.gif)
- 左边为原图 - 右边为高斯模糊之后效果,发现皱纹和手部滑了等等现在还不最cool的效果,高斯模糊之后如果与原图像叠加会出现一种Glow的效果,好像灯光打在图像上一样,Glow处理之后的运行效果如下:原图:
![](http://hi.csdn.net/attachment/201202/5/0_13284245408c4Z.gif)
实现Glow Filter之后的图像:
![](http://hi.csdn.net/attachment/201202/5/0_1328424693c17f.gif)
实现Glow算法只是高斯模糊输出像素值叠加原来的像素值。[java] view plaincopyint index = 0;
for ( int y = 0; y < height; y++ ) {
for ( int x = 0; x < width; x++ ) {
int rgb1 = outPixels[index];
int r1 = (rgb1 >> 16) & 0xff;
int g1 = (rgb1 >> 8) & 0xff;
int b1 = rgb1 & 0xff;
int rgb2 = inPixels[index];
int r2 = (rgb2 >> 16) & 0xff;
int g2 = (rgb2 >> 8) & 0xff;
int b2 = rgb2 & 0xff;
r1 = PixelUtils.clamp( (int)(r1 + a * r2) );
g1 = PixelUtils.clamp( (int)(g1 + a * g2) );
b1 = PixelUtils.clamp( (int)(b1 + a * b2) );
inPixels[index] = (rgb1 & 0xff000000) | (r1 << 16) | (g1 << 8) | b1;
index++;
}
}
相关文章推荐
- 柏林噪声产生火焰等纹理
- Linux下使用U盘
- 【system】cmd命令大全
- 普通的年轻状态机,纯C语言
- 图像处理------高斯模糊 分类: 视频图像处理 2015-07-24 09:32 29人阅读 评论(0) 收藏
- ZooKeeper群集安装
- BC430-Unit2:Data Types in the ABAP Dictionary
- mac下网页中文字体优化
- 一种最简单的Java环境变量配置
- 搭建简单的 mongodb
- TFT液晶屏显示原理
- JVM 垃圾回收器工作原理及使用实例介绍
- 巧用dimens适配多个分辨率
- setting
- Linux declare声明
- 毕业生大礼包之论文查重
- 【算法学习】【图像增强】【Retinex】源码运行
- 无法连接到SQL Server 2008 R2
- eclipse运行maven的jetty插件内存溢出
- 程序员的作息时间表