利用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)
预览: