java实现中值滤波均值滤波拉普拉斯滤波

来对下面的图像滤波,其实就是对各个像素点进行数学运算的过程

均值滤波

均值滤波的实现很简单,把滤波器的各个像素点相加在取平均就可以了。

public static int getAVEcolor(int x,int y,BufferedImage bi)
	{
		int color=0;
		int r=0,g=0,b=0;
		for(int i=x-1;i<=x+1;i++)
			for(int j=y-1;j<=y+1;j++)
			{
				color=bi.getRGB(i, j);
				r += (color >> 16) & 0xff;
	            g += (color >> 8) & 0xff;
	            b += color & 0xff;
			}
		 int ia = 0xff;  
         int ir = (int)(r/9);  
         int ig = (int)(g/9);  
         int ib = (int)(b/9);  
         color = (ia << 24) | (ir << 16) | (ig << 8) | ib;  
			return color;
	}![](https://img2018.cnblogs.com/blog/1475969/201903/1475969-20190324224125916-744413606.jpg)

效果如下图

中值滤波

取滤波器的各个像素点的中值。如3*3的滤波器就取排列后的第5个数

public static int getMidcolor(int x,int y,BufferedImage bi)
	{
		int color=0;
		int m=0;
		int a[]=new int[9];
		for(int i=x-1;i<=x+1;i++)
			for(int j=y-1;j<=y+1;j++)
			{
				color=bi.getRGB(i, j);
				a[m]=color;
				m++;
			}
		Arrays.sort(a);
		color=a[5];
		
		return color;
	}

效果如下图

拉普拉斯滤波

其实也是各个像素点的基本运算

//LPLS滤波中间权重为8
	public static int getLPLScolor8(int x,int y,BufferedImage bi)
	{
		int color=0,r=0,g=0,b=0;
		for(int i=x-1;i<=x+1;i++)
			for(int j=y-1;j<=y+1;j++)
			{
				if(i!=x&&j!=y)
				{
				color=bi.getRGB(i, j);
				r -= (color >> 16) & 0xff;
	            g -= (color >> 8) & 0xff;
	            b -= color & 0xff;
				}
				else if(i==x&&j==y)
				{
				color=bi.getRGB(i, j);
				r += 8*((color >> 16) & 0xff);
	            g += 8*((color >> 8) & 0xff);
	            b += 8*(color & 0xff);
				}
			}
		color=bi.getRGB(x, y);
		r += (color >> 16) & 0xff;
        g += (color >> 8) & 0xff;
        b += color & 0xff;
        int ia = 0xff;  
        
        color = (ia << 24) | (clamp(r) << 16) | (clamp(g) << 8) | clamp(b); 

        return color;
	}
//LPLS中间权重为4
	public static int getLPLScolor4(int x,int y,BufferedImage bi)
	{
		int color=0,r=0,g=0,b=0;
		color=bi.getRGB(x, y+1);
		r -= (color >> 16) & 0xff;
        g -= (color >> 8) & 0xff;
        b -= color & 0xff;
        color=bi.getRGB(x-1, y);
		r -= (color >> 16) & 0xff;
        g -= (color >> 8) & 0xff;
        b -= color & 0xff;
        color=bi.getRGB(x+1, y);
		r -= (color >> 16) & 0xff;
        g -= (color >> 8) & 0xff;
        b -= color & 0xff;
        color=bi.getRGB(x, y-1);
		r -= (color >> 16) & 0xff;
        g -= (color >> 8) & 0xff;
        b -= color & 0xff;
        color=bi.getRGB(x, y);
		r += 5*((color >> 16) & 0xff);
        g += 5*((color >> 8) & 0xff);
        b += 5*(color & 0xff);
     
	    int ia = 0xff;  
	    color = (ia << 24) | (clamp(r) << 16) | (clamp(g) << 8) | clamp(b); 
		return color;
	}

LPLS权重4

LPLS权重8

Sobel滤波

主要用于提取边缘信息,当然也是数学变化

public static int getSobelcolor(int x,int y,BufferedImage bi)
	{
		int color=0;
		int r1=0,g1=0,b1=0;
		int r2=0,g2=0,b2=0;
		int []a1= {-1,-2,-1,0,0,0,1,2,1};
		int []a2= {1,0,-1,2,0,-2,1,0,-1};
		int m=0;
		for(int i=x-1;i<=x+1;i++)
			for(int j=y-1;j<=y+1;j++)
			{
				color=bi.getRGB(i, j);
				r1 += a1[m]*((color >> 16) & 0xff);
	            g1 += a1[m]*((color >> 8) & 0xff);
	            b1 += a1[m]*(color & 0xff);
	            r2 += a2[m]*((color >> 16) & 0xff);
	            g2 += a2[m]*((color >> 8) & 0xff);
	            b2 += a2[m]*(color & 0xff);
	            m+=1;
			}
		r1=(int)Math.sqrt(r1*r1+r2*r2);
		g1=(int)Math.sqrt(g1*g1+g2*g2);
		b1=(int)Math.sqrt(b1*b1+b2*b2);
		int ia = 0xff;  
		color = (ia << 24) | (clamp(r1) << 16) | (clamp(g1) << 8) | clamp(b1); 
		return color;
	}

结果

他可以用于图像转线稿哎

转化后的线稿

应该还要去除下噪声才好用

注意

用java读取的是RGB值,要做位运算转变成在R,G,B的分量。
注意转换后的图像的灰度值要小于255大于0,灰度值不在此区间的要让他等于255或0。一开始做LPLS的变化的时候没有注意到这一点,做出来的图像失真很严重,找了半天原因。。。

完整demo

原文地址:https://www.cnblogs.com/zzc2018/p/10582092.html