您的位置:首页 > 编程语言 > Java开发

java 边缘检测 sobel算子和Prewitt算子

2014-07-27 17:15 225 查看
阅读前请看<前言>,谢谢!

在进行本人之前,希望大家先了解卷积。学过概率论的应该都知道,在求解Z=X+Y的概率密度的时候,引入了卷积公式



这就是f与g在连续情况下的卷积。对于图像而言,离散更重要。



这就是离散卷积,公式看得头疼的童鞋不要急。其实对于特定的点而言,卷积就是它附近M*N范围内所有元素的概率和。见下图:



卷积我并不打算详细的去说,不懂的童鞋好好去翻翻资料。可以看看 图像处理(卷积),对于卷积也不要太过纠结,你实现的时候就能很好的理解了。

Prewitt算子的卷积模板为:



它每个点的值等于abs(sx)+abs(sy)

实现代码如下:

public void Prewitt(){
		toGray();//灰度化
		int[] d= new int[w*h];
		for(int j=1;j<h-1;j++){
			for(int i=1;i<w-1;i++){
				int s1 = data[i-1+(j+1)*w]+data[i+(j+1)*w]+data[i+1+(j+1)*w]-data[i-1+(j-1)*w]-data[i+(j-1)*w]-data[i+1+(j-1)*w];
		        int s2 = data[i+1+(j-1)*w]+data[i+1+(j)*w]+data[i+1+(j+1)*w]-data[i-1+(j-1)*w]-data[i-1+(j)*w]-data[i-1+(j+1)*w];
		        int s  = Math.abs(s1)+Math.abs(s2);
		        if(s < 0)
			    	s =0;
		        if(s > 255)
		    	    s = 255;
		        d[i + j * w] = s;
			}    
		}
		
		this.data = d;
	}


运行结果为:



Sobel算子的卷积模板为:



它每个点的值也等于abs(sx)+abs(sy)或者



可以看出他与Prewitt算子的区别就是系数一个为1一个为2,sobel系数为2,它有着平滑的效果,我们知道,平滑可以去噪。

代码如下:

public void sobel(){
		toGray();
		int[] d= new int[w*h];
		for(int j=1;j<h-1;j++){
			for(int i=1;i<w-1;i++){
				int s1 = data[i-1+(j+1)*w]+2*data[i+(j+1)*w]+data[i+1+(j+1)*w]-data[i-1+(j-1)*w]-2*data[i+(j-1)*w]-data[i+1+(j-1)*w];
		        int s2 = data[i+1+(j-1)*w]+2*data[i+1+(j)*w]+data[i+1+(j+1)*w]-data[i-1+(j-1)*w]-2*data[i-1+(j)*w]-data[i-1+(j+1)*w];
		        int s  = Math.abs(s1)+Math.abs(s2);
		        if(s < 0)
			    	s =0;
		        if(s > 255)
		    	    s = 255;
		        d[i + j * w] = s;
			}    
		}
		
		this.data = d;
	}


运行结果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: