利用java打开一张图片,并提取其边缘。功能有打开文件,以及提取边缘。
算法原理
由于边缘提取的算法有很多种,而提取的精度在相同阈值的情况下也会有不同的结果。
这次我的边缘提取使用索贝尔算子(Sobel operator)。
该算子会把图像每一点的灰度矢量计算出来。而分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。
算法核心:
public int getGrayPoint(int x, int y) { return grayData[y * width + x]; }
protected final int GradientX(int x, int y) { return getGrayPoint(x - 1, y - 1) + 2*getGrayPoint(x - 1, y)+ getGrayPoint(x - 1, y + 1) - getGrayPoint(x + 1, y - 1)- 2*getGrayPoint(x + 1, y) - getGrayPoint(x + 1, y + 1); } protected final int GradientY(int x, int y) { return getGrayPoint(x - 1, y - 1) + 2*getGrayPoint(x, y - 1)+ getGrayPoint(x + 1, y - 1) - getGrayPoint(x - 1, y + 1)- 2*getGrayPoint(x, y + 1) - getGrayPoint(x + 1, y + 1);
而利用JAVA 的GUI界面将图片打开且直接进行操作:
setTitle("Test"); setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); label = new JLabel(); add(label); chooser = new JFileChooser(); chooser.setCurrentDirectory(new File(".")); JMenuBar menubar = new JMenuBar(); setJMenuBar(menubar); JMenu menu = new JMenu("文件"); JMenu menu2 = new JMenu("操作"); menubar.add(menu); menubar.add(menu2); JMenuItem openItem = new JMenuItem("打开"); JMenuItem Clicktime = new JMenuItem("提取边缘"); menu.add(openItem); menu2.add(Clicktime); JMenuItem exitItem = new JMenuItem("关闭"); menu.add(exitItem); SobelEdgeDetect tp=new SobelEdgeDetect(50); openItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub int result = chooser.showOpenDialog(null); if(result == JFileChooser.APPROVE_OPTION){ String name = chooser.getSelectedFile().getPath(); label.setIcon(new ImageIcon(name)); try { tp.readImage(name); } catch (IOException ex) { Logger.getLogger(ImageViewerFrame.class.getName()).log(Level.SEVERE, null, ex); } } } }); exitItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub System.exit(0); } }); Clicktime.addActionListener(new ActionListener() { private int heightWMI; @Override public void actionPerformed(ActionEvent e) { String desImageName = "1.jpg"; tp.createEdgeImage(desImageName); label.setIcon(new ImageIcon(desImageName)); } }); } private JLabel label; private JFileChooser chooser; private static final int DEFAULT_WIDTH = 1280; private static final int DEFAULT_HEIGHT =800;
执行后可将图片边缘提取:(这里设定阈值为50)
预览: