高斯模糊


高斯模糊


高斯模糊是一种可以让图像过渡平滑的算法,不保留边缘。

实现步骤:

1.输入模糊半径R和标准差σ

2.根据R和σ和二维正态函数生成一个边长为2R+1的权值方阵,方阵中心坐标为(0,0)

3.对图像的每一个像素p进行处理,以p为中心选择半径为2R+1的正方形,用正方形中的RGB分量分别和权值方阵对应位置相乘然后相加,得到模糊后的像素p’


详细步骤:

1.输入模糊半径R和标准差σ

这个是最难解释的,但是大家都懂,就是两个数字R取正整数,σ可以取0.8R。这两个参数可以决定最终的模糊效果。R越大中心点像素可以受到更远像素的影响。σ值越大,周围的像素对中心像素影响越大。

2.假设R=2,σ=1.6,建造一个5*5的方阵.


现在方阵建好了,中心点是(0,0),左上角坐标是(-2,-2),下面要根据二维的正态分布函数(即二维高斯函数)填写权值了,二维高斯函数如下:



R=2,σ=1.6,π≈3.1415,e≈2.71828

下面计算(-2,-2)的值:

将这些已知量带入G(x,y)

G(-2,-2)=1/(2*3.1415*1.6*1.6)*2.71828^(((-2)*(-2)+(-2)*(-2))/(2*1.6*1.6))≈0.0105

计算(-1,-2)的值:

G(-1,-2)=1/(2*3.1415*1.6*1.6)*2.71828^(((-1)*(-1)+(-2)*(-2))/(2*1.6*1.6))≈0.0227

。。。

。。。

计算(2,2)的值:

G(2,2)=1/(2*3.1415*1.6*1.6)*2.71828^(((2)*(2)+(2)*(2))/(2*1.6*1.6))≈0.0105

填写完毕,得到的方阵如下:


到了这里,这个高斯方阵已经计算完毕了,但是我们想要的是权值方阵,这个方阵中的所有权值之和大约为0.8686,并不等于1,如果使用这个方阵做权值,最终得到的图片经过了高斯模糊,但是亮度会比原图暗一些,为了不让处理后的图像变暗,把方阵中的每一个权值除以0.8686,这样,他们的和就等于1了,图像就不会变暗了,计算后,我们得到最终的权值方阵:



3.对图像的每一个像素p进行处理,以p为中心选择半径为2R+1的正方形,用正方形中的RGB分量分别和权值方阵对应位置相乘然后相加,得到模糊后的像素p’

众所周知,计算机通过RGB三原色合成其他各种颜色。

一组RGB可以表示一个像素。

一张平面图片,是由w*h个像素组成的,w图像宽度,h图像高度。一张平面图像是由w*h组RGB组成的。

对于图像的大多数像素点x,y而言,都可以找到一个R*R的方阵,(x,y)在方阵中央。

例如下面这张图片(如果侵犯了版权,请及时联系我,本人QQ:79221571,立刻进行修改):


从这里面可以选择许多5*5的像素方阵,某个颜色方阵如下:


这里虽然用颜色展示了,其本质是5*5*3个byte型数字。其中25个R分量,25G分量,25个B分量。假设其红色分量方阵如下:



sum=0.0121*20+0.0261*30+...+0.0261*94+0.0121*15.

将sum值填到一个新的图片对应位置中心,也就是69的位置。

边缘处可能不能找到一个5*5的像素方阵,这时用它的对称位置补全。

public static int[] gaussianBlur(int[] src,int w,int h,int r,double sigma2){
		double kernel[]=gaussianBlurkernel(r, sigma2);
		int side=(r<<1)|1;
		double weight;
		int res[]=new int[src.length];
		int x,y;
		double R,G,B;
		int rr,gg,bb,color;
		for(int i=0;i<h;i++){
			for(int j=0;j<w;j++){
				//中心点坐标(j,i)
				R=0f; G=0f; B=0f; 这里我们使用的是灰度图,只计算B即可
				B=0f;
				for(int p=-r;p<=r;p++){
					for(int q=-r;q<=r;q++){
						weight=kernel[(p+r)*side+q+r];
						y=i+p;
						x=j+q;
						if(x<0||x>=w){
							x=2*j-x;
						}
						if(y<0||y>=h){
							y=2*i-y;
						}
						color=src[y*w+x];
						R+=((color>>16)&0xff)*weight;
						G+=((color>>8)&0xff)*weight;
						B+=(color&0xff)*weight;
					}
				}
				rr=(int)R;gg=(int)G;bb=(int)B;
				bb=(int)B;
				res[i*w+j]=(bb<<16)|(bb<<8)|bb;
				//res[i*w+j]=bb;
			}
		}
		
		return res;
	}
	public static double[] gaussianBlurkernel(int r,double sigma2){
		int side=(r<<1)|1;
		double[] kernel=new double[side*side];
		double sigma2X2=sigma2*2f;
		double sigma2X2XPI=sigma2X2*Math.PI;
		double w,sw=0;
		for(int i=0;i<side;i++){
			for(int j=0;j<side;j++){
				double x=j-r;
				double y=i-r;
				w=Math.exp(-(x*x+y*y)/sigma2X2)/sigma2X2XPI;
				kernel[i*side+j]=w;
				sw+=w;
			}
		}
		
		for(int i=0;i<kernel.length;i++){
			kernel[i]/=sw;
		}
		
		return kernel;
	}

终于写完了,图片真难做!!!!!看效果图吧,取R=10,σ=8









  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值