Java Canny边缘检测

import java.awt.image.BufferedImage;

public class CannyUtil {
	int Y;
	int X;
	int src[][];
	int dest[][];
	double tan[][];
	BufferedImage bufferedImage;
	BufferedImage bufferedImage_old;
	public CannyUtil(BufferedImage bi) {
		bufferedImage_old = bi;
		bufferedImage = bi;
		Y = bi.getWidth();
		X = bi.getHeight();
		src = new int[Y][X];
		dest = new int[Y][X];
		tan = new double[Y][X];
	}
	
	//灰度
	public BufferedImage Gray() {
		for(int y=0;y<Y;y++) {
			for(int x=0;x<X;x++) {
				int r=(bufferedImage.getRGB(y,x)>>16)&0x000000ff;
		    	int g=(bufferedImage.getRGB(y,x)>>8)&0x000000ff;
		    	int b=bufferedImage.getRGB(y,x)&0x000000ff;
		    	src[y][x]=(int)(0.2989*r+0.587*g+0.114*b);
				//bufferedImage.setRGB(y,x,0xff000000|src[y][x]|(src[y][x]<<8)|(src[y][x]<<16));
			}
		}
		return bufferedImage;
	}
	
	//高斯平滑
	public BufferedImage Gauss()
	{
		int M[][]={{1,2,1},{2,4,2},{1,2,1}};
    	bufferedImage=new BufferedImage(Y,X,BufferedImage.TYPE_INT_RGB);
		for(int y=1;y<Y-1;y++)
			for(int x=1;x<X-1;x++)
			{
				dest[y][x]= src[y-1][x-1]*M[0][0]+src[y][x-1]*M[1][0]+src[y+1][x-1]*M[2][0]
						+src[y-1][x]  *M[0][1]+src[y][x]  *M[1][1]+src[y+1][x]  *M[2][1]
						+src[y-1][x+1]*M[0][2]+src[y][x+1]*M[1][2]+src[y+1][x+1]*M[2][2];
				dest[y][x]/=16;
				bufferedImage.setRGB(y,x,0xff000000|dest[y][x]|(dest[y][x]<<8)|(dest[y][x]<<16));
			}
		for(int y=1;y<Y-1;y++)
			for(int x=1;x<X-1;x++)
				src[y][x]=dest[y][x];
		return bufferedImage;
	}
	//索贝尔边缘提取
	public BufferedImage Sobel()
    {
    	int Mx[][]={{-1,0,1},{-2,0,2},{-1,0,1}};
    	int My[][]={{-1,-2,-1},{0,0,0},{1,2,1}};
    	bufferedImage=new BufferedImage(Y,X,BufferedImage.TYPE_INT_RGB);
		for(int y=1;y<Y-1;y++)
			for(int x=1;x<X-1;x++)
			{
				int dx=	 src[y-1][x-1]*Mx[0][0]+src[y][x-1]*Mx[1][0]+src[y+1][x-1]*Mx[2][0]
						+src[y-1][x]  *Mx[0][1]+src[y][x]  *Mx[1][1]+src[y+1][x]  *Mx[2][1]
						+src[y-1][x+1]*Mx[0][2]+src[y][x+1]*Mx[1][2]+src[y+1][x+1]*Mx[2][2];
				int dy=	 src[y-1][x-1]*My[0][0]+src[y][x-1]*My[1][0]+src[y+1][x-1]*My[2][0]
						+src[y-1][x]  *My[0][1]+src[y][x]  *My[1][1]+src[y+1][x]  *My[2][1]
						+src[y-1][x+1]*My[0][2]+src[y][x+1]*My[1][2]+src[y+1][x+1]*My[2][2];
				dest[y][x]=(int)(Math.sqrt(dx*dx+dy*dy)+0.5);
				if(dest[y][x]>255) dest[y][x]=255;
				if(dest[y][x]<0) dest[y][x]=0;
				bufferedImage.setRGB(y,x,0xff000000|dest[y][x]|(dest[y][x]<<8)|(dest[y][x]<<16));
				tan[y][x]=1.0*dy/dx;
			}
		for(int y=1;y<Y-1;y++)
			for(int x=1;x<X-1;x++)
				src[y][x]=dest[y][x];
		return bufferedImage;
    }
    //非极大值抑制
	public BufferedImage NMS()
	{
		for(int y=1;y<Y-1;y++)
			for(int x=1;x<X-1;x++)
			{
				if(Math.abs(tan[y][x])<=0.5)
				{
					if(src[y][x]>=src[y][x-1]&&src[y][x]>=src[y][x+1])
						dest[y][x]=src[y][x];
					else
						dest[y][x]=0;
				}
				else if(-2<=tan[y][x]&&tan[y][x]<=-0.5)
				{
					if(src[y][x]>=src[y+1][x-1]&&src[y][x]>=src[y-1][x+1])
						dest[y][x]=src[y][x];
					else
						dest[y][x]=0;
				}
				else if(0.5<=tan[y][x]&&tan[y][x]<=2)
				{
					if(src[y][x]>=src[y-1][x-1]&&src[y][x]>=src[y+1][x+1])
						dest[y][x]=src[y][x];
					else
						dest[y][x]=0;
				}
				else if(2<=Math.abs(tan[y][x]))
				{
					if(src[y][x]>=src[y-1][x]&&src[y][x]>=src[y+1][x])
						dest[y][x]=src[y][x];
					else
						dest[y][x]=0;
				}
				bufferedImage.setRGB(y,x,0xff000000|dest[y][x]|(dest[y][x]<<8)|(dest[y][x]<<16));
			}
		for(int y=1;y<Y-1;y++)
			for(int x=1;x<X-1;x++)
				src[y][x]=dest[y][x];
		return bufferedImage;
	}
	//双阈值连接
	public BufferedImage DT()
	{
		int th1=127;
		int th2=63;
		for(int y=1;y<Y-1;y++)
			for(int x=1;x<X-1;x++)
			{
				if(src[y][x]>=th1)
					dest[y][x]=255;
				else if(src[y][x]<=th2)
					dest[y][x]=0;
				else
				{
					if(src[y-1][x-1]>=th1||src[y-1][x]>=th1||src[y-1][x+1]>=th1||src[y][x-1]>=th1||src[y][x+1]>=th1||src[y+1][x-1]>=th1||src[y+1][x]>=th1||src[y+1][x+1]>=th1)
						dest[y][x]=255;
					else
						dest[y][x]=0;
				}	
				bufferedImage.setRGB(y,x,0xff000000|dest[y][x]|(dest[y][x]<<8)|(dest[y][x]<<16));
			}
		for(int y=1;y<Y-1;y++)
			for(int x=1;x<X-1;x++)
				src[y][x]=dest[y][x];
		return bufferedImage;
	}
	
	//自动裁剪
	public BufferedImage autoClip(int GaussCount) {
		bufferedImage = Gray();
		for(int i=0;i<GaussCount;i++) {
			bufferedImage = Gauss();
		}
		bufferedImage = Sobel();		
		bufferedImage = NMS();
		bufferedImage = DT();
		
		boolean minXb = false, minYb = false;
	    int minX = 0, minY = 0, maxX = 0, maxY = 0;
	    
		for (int x = 0; x < bufferedImage.getWidth(); x++) {
	        for (int y = 0; y < bufferedImage.getHeight(); y++) {
	            // 如果是透明像素 跳过
	            if (bufferedImage.getRGB(x,y) == 0) continue;

	            // 获取该点像素,并以object类型表示
	            Object data = bufferedImage.getRaster().getDataElements(x, y, null);
	            int r = bufferedImage.getColorModel().getRed(data);
	            int g = bufferedImage.getColorModel().getGreen(data);
	            int b = bufferedImage.getColorModel().getBlue(data);
	            
	            if (r == 0 && g == 0 && b == 0) continue;

	            if (!minXb) {
	                minX = x;
	                minXb = true;
	            }

	            if (!minYb) {
	                minY = y;
	                minYb = true;
	            }

	            minX = Math.min(minX, x);
	            minY = Math.min(minY, y);

	            maxX = Math.max(maxX, x);
	            maxY = Math.max(maxY, y);
	        }
	    }
		System.out.printf("minX=%d,minY=%d,maxX=%d,maxY=%d\n", minX,minY,maxX,maxY);
		return bufferedImage_old.getSubimage(minX, minY, maxX - minX, maxY - minY);
	}
}

Java Canny边缘检测

Java 文件操作工具类

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.io.FileUtils;

import com.bcap_systemlib.config.Configuration;

public class FileUtil {
    /**
     * 将多个文件打包到一个zip中
     *
     * @param sourceFolder
     * @param zipFile
     * @return
     * @throws Exception 
     */
    public static boolean zipFile(String sourceFolder, File zipFile) throws Exception{
        boolean isOk = true;
        File f = new File(sourceFolder);
        ZipOutputStream out = null;
        try{
            if(!f.exists()){
                f.mkdirs();
            }
            out = new ZipOutputStream(new FileOutputStream(zipFile));
            zip(out, f, "");
            out.flush();
            FileUtils.deleteDirectory(f);
        } catch (Exception e){
            e.printStackTrace();
            throw new Exception("压缩文件出错!");
        } finally
        {
            if(null != out){
                try{ out.close(); } catch (Exception e){ e.printStackTrace();}
            }
        }
        return isOk;
    }

    /**
     * 递归压缩文件
     * @param out
     * @param f
     * @param base
     * @throws Exception
     */
    private static void zip(ZipOutputStream out, File f, String base) throws Exception {
        if (f.isDirectory()) {
            File[] fl = f.listFiles();
            out.putNextEntry(new ZipEntry(base + "/"));
            base = base.length() == 0 ? "" : base + "/";
            for (int i = 0; i < fl.length; i++) {
                zip(out, fl[i], base + fl[i].getName());
            }
        }else {
            out.putNextEntry(new ZipEntry(base));
            FileInputStream in = new FileInputStream(f);
            int b;
            while ( (b = in.read()) != -1) {
                out.write(b);
            }
            in.close();
        }
    }

    /**
     * 下载单个文件
     *
     * @param file
     * @param request
     * @param response
     * @return
     */
    public static boolean downFile(File file, HttpServletRequest request, HttpServletResponse response) {
        boolean isOk = true;
        OutputStream myout = null;
        FileInputStream fis = null;
        BufferedInputStream buff = null;
        HttpSession session = request.getSession();
        if (session != null) {
            session.setAttribute("state", "");
        }
        try {
            response.setContentType("application/x-msdownload");
            response.setContentLength((int) file.length());
            response.setHeader("content-disposition", "attachment;filename=" + EncodingConvertUtil.utf2iso(file.getName()));
            fis = new FileInputStream(file);
            buff = new BufferedInputStream(fis);
            byte[] b = new byte[1024 * 10];//相当于我们的缓存
            long k = 0;//该值用于计算当前实际下载了多少字节
            //从response对象中得到输出流,准备下载
            myout = response.getOutputStream();
            while (k < file.length()) {
                int j = buff.read(b, 0, b.length);
                k += j;
                //将b中的数据写到客户端的内存
                myout.write(b, 0, j);
            }
            myout.flush();
        } catch (Exception e) {
            e.printStackTrace();
            isOk = false;
        } finally {
            try {
                if (null != myout) {
                    myout.close();
                    myout = null;
                }
                if (null != buff) {
                    buff.close();
                    buff = null;
                }
                if (null != fis) {
                    fis.close();
                    fis = null;
                }
                if(file.exists()){
                    FileUtil.delFile(file);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return isOk;
    }

    /**
     * 删除单个文件
     *
     * @param file
     * @return
     */
    public static boolean delFile(File file) {
        boolean isOk = true;
        try {
            if (file.isFile() && file.exists()) {
                file.delete();
            }
        } catch (Exception e) {
            e.printStackTrace();
            isOk = false;
        } finally {
            // log ...
        }
        return isOk;
    }
    
    public static void downloadFileFromRemote(String remoteFilePath, String localFilePath){
        URL urlfile = null;
        HttpURLConnection httpUrl = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        File f = new File(localFilePath);
        try
        {
            urlfile = new URL(remoteFilePath);
            httpUrl = (HttpURLConnection)urlfile.openConnection();
            httpUrl.connect();
            bis = new BufferedInputStream(httpUrl.getInputStream());
            bos = new BufferedOutputStream(new FileOutputStream(f));
            int len = 2048;
            byte[] b = new byte[len];
            while ((len = bis.read(b)) != -1)
            {
                bos.write(b, 0, len);
            }
            System.out.println("下载成功");
            bos.flush();
            bis.close();
            httpUrl.disconnect();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            try
            {
                bis.close();
                bos.close();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }
    
    public static void writeFile(String filePathAndName, String fileContent) {
    	try {
    		File f = new File(filePathAndName);
    		if (!f.exists()) {
    			f.createNewFile();
    		}
    		OutputStreamWriter write = new OutputStreamWriter(new FileOutputStream(f),Configuration.SERVLET_CHARACTER_ENCODING);
    		BufferedWriter writer=new BufferedWriter(write);   
    		writer.write(fileContent);
    		writer.close();
    	} catch (Exception e) {
			System.out.println("写文件内容操作出错");
			e.printStackTrace();
    	}
    }
    
    public static String readFile(String filePathAndName) {
    	String fileContent = "";
    	try {  
    		File f = new File(filePathAndName);
    		if(f.isFile()&&f.exists()){
    			InputStreamReader read = new InputStreamReader(new FileInputStream(f),Configuration.SERVLET_CHARACTER_ENCODING);
    			BufferedReader reader=new BufferedReader(read);
    			String line;
    			while ((line = reader.readLine()) != null) {
    				fileContent += line;
    			}   
    			read.close();
    		}
    	} catch (Exception e) {
    		System.out.println("读取文件内容操作出错");
    		e.printStackTrace();
    	}
    	return fileContent;
    }
    
    public static String getExtName(String filename) {
        int index = filename.lastIndexOf(".");
 
        if (index == -1) {
            return null;
        }
        String result = filename.substring(index);
        return result;
    }
}

Java 文件操作工具类