package com.chipmunk.util; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; /** * 算子 * * sobel,prewitt,roberts,laplace,canny * 均有卷积因子,小矩阵 * * @author Administrator * */ public class OperatorUtil { /** * 索贝尔算子(Sobel operator) * * 横向矩阵 卷积因子 * Gx= -1 0 +1 * -2 0 +2 * A * -1 0 +1 * * 纵向矩阵 卷积因子 * Gy= +1 +2 +1 * 0 0 0 * A * -1 -2 -1 * * A= a b c * d e f * g h i * * * G=Math.hypot(Gx,Gy); * 为了简便,用|G|=|Gx|+|Gy| * * @param data * @param w * @param h * @return */ public static int[] sobel(int[]data,int w,int h){ 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; } } return d; } /** * 普利维特算子(Prewitt operate) * * 横向矩阵 卷积因子 * Gx= -1 0 +1 * -1 0 +1 * A * -1 0 +1 * * 纵向矩阵 卷积因子 * Gy= +1 +1 +1 * 0 0 0 * A * -1 -1 -1 * * @param data * @param w * @param h * @return */ public static int[] prewitt(int[]data,int w,int h){ 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; } } return d; } /** * 罗伯茨交叉边缘检测(Roberts Cross operator) * * 横向矩阵 卷积因子 * Gx= +1 0 * A * 0 -1 * * * 纵向矩阵 卷积因子 * Gy= 0 +1 * -1 0 * A * * A = x,y x+1,y = a b * x,y+1 x+1,y+1 c d * * Gx= a+b-c-d * Gy= -a-b+c+d * * @param data * @param w * @param h * @return */ public static int[] roberts(int[]data,int w,int h){ int[] d= new int[w*h]; for(int j=0;j<h-1;j++){ for(int i=0;i<w-1;i++){ int s1 = data[i+j*w]+data[i+1+j*w]-data[i+(j+1)*w]-data[i+1+(j+1)*w]; int s2 = data[i+(j+1)*w]+data[i+1+(j+1)*w]-data[i+j*w]-data[i+1+j*w]; int s = Math.abs(s1)+Math.abs(s2); if(s < 0) s =0; if(s > 255) s = 255; d[i + j * w] = s; } } return d; } /** * 拉普拉斯算子laplace * * 离散拉普拉斯算子的模板: * 0 1 0 * 1 4 1 * 0 1 0 * * 其扩展模板: * 1 1 1 * 1 8 1 * 1 1 1 * @param data * @param w * @param h * @return */ //TODO 未完待续 public static int[] laplace(int[]data,int w,int h){ int[] d= new int[w*h]; for(int j=1;j<h-1;j++){ for(int i=1;i<w-1;i++){ // 1 1 1 // 6 6 6 // 1 1 1 int s1 = data[i-1+(j-1)*w] +data[i+(j-1)*w] +data[i+1+(j-1)*w] +6*data[i-1+j*w] +6*data[i+j*w] +6*data[i+1+j*w] +data[i-1+(j+1)*w] +data[i+(j+1)*w] +data[i+1+(j+1)*w]; int s = Math.abs(s1); if(s < 0) s =0; if(s > 255) s = 255; d[i + j * w] = s; } } return d; } /** * 各种边界算子 * @param src * @param dest * @param type:1-sobel,2-prewitt,3-roberts,4-laplace */ public static void suanzis(File src,File dest,int type){ try { BufferedImage bi = ImageIO.read(src); int w = bi.getWidth(); int h = bi.getHeight(); int[]data = ImageUtil.getImageBW(src); int[]d = null; if (type==1) { d = sobel(data, w, h); }else if (type==2) { d = prewitt(data, w, h); }else if (type==3) { d = roberts(data, w, h); }else if (type==4) { d = laplace(data, w, h); } ImageUtil.writeImageRGB(d, dest, w, h); } catch (IOException e) { e.printStackTrace(); } } }
图像边缘检测算子
猜你喜欢
转载自itace.iteye.com/blog/2352482
今日推荐
周排行