import java.awt.image.BufferedImage;
import java.util.Arrays;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
/**
* <p><em>This software has been released into the public domain.
* <strong>Please read the notes in this source file for additional information.
* </strong></em></p>
*
* <p>This class provides a configurable implementation of the Canny edge
* detection algorithm. This classic algorithm has a number of shortcomings,
* but remains an effective tool in many scenarios. <em>This class is designed
* for single threaded use only.</em></p>
*
* <p>Sample usage:</p>
*
* <pre><code>
* //create the detector
* CannyEdgeDetector detector = new CannyEdgeDetector();
* //adjust its parameters as desired
* detector.setLowThreshold(0.5f);
* detector.setHighThreshold(1f);
* //apply it to an image
/* detector.setSourceImage(frame);
* detector.process();
* BufferedImage edges = detector.getEdgesImage();
* </code></pre>
*
* <p>For a more complete understanding of this edge detector's parameters
* consult an explanation of the algorithm.</p>
*
* @author Tom Gibara
*
*/
public class CannyEdgeDetector extends Frame {
// statics
private final static float GAUSSIAN_CUT_OFF = 0.005f;
private final static float MAGNITUDE_SCALE = 100F;
private final static float MAGNITUDE_LIMIT = 1000F;
private final static int MAGNITUDE_MAX = (int) (MAGNITUDE_SCALE * MAGNITUDE_LIMIT);
// fields
private int height;
private int width;
private int picsize;
private int[] data;
private int[] pixels;
private int[] magnitude;
private BufferedImage sourceImage;
private BufferedImage edgesImage;
private Image im;
private Image tmp;
private Boolean flag;
private float gaussianKernelRadius;
private float lowThreshold=0.5f;
private float highThreshold=1f;
private int gaussianKernelWidth;
private boolean contrastNormalized;
private float[] xConv;
private float[] yConv;
private float[] xGradient;
private float[] yGradient;
// constructors
/**
* Constructs a new detector with default parameters.
*/
public CannyEdgeDetector() {
super("canny检测");
Panel pdown;
Button load,run,save,quit;
//添加窗口监听事件
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
pdown = new Panel();
pdown.setBackground(Color.lightGray);
load=new Button("装载图像");
run = new Button("canny检测");
save=new Button("保存");
quit=new Button("退出");
this.add(pdown,BorderLayout.SOUTH);
pdown.add(load);
pdown.add(run);
pdown.add(save);
pdown.add(quit);
load.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
jLoad_ActionPerformed(e);
}
});
run.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
jRun_ActionPerformed(e);
}
});
quit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
jQuit_ActionPerformed(e);
}
});
save.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
jSave_ActionPerformed(e);
}
});
lowThreshold = 1.0f;
highThreshold = 3.0f;
gaussianKernelRadius = 2f;
gaussianKernelWidth = 16;
contrastNormalized = false;
}
public void jLoad_ActionPerformed(ActionEvent e){
//利用MediaTracker跟踪图像的加载
MediaTracker tracker = new MediaTracker(this);
im=Toolkit.getDefaultToolkit().getImage("girl1.jpg");//读入内存
tracker.addImage(im,0);
//等待图像的完全加载
try{
tracker.waitForID(0);
}catch(InterruptedException e2){ e2.printStackTrace();}
//获取图像的宽度iw和高度ih
width=im.getWidth(this);
height=im.getHeight(this);
picsize=width*height;
//data=new int[height*width];
pixels=new int[height*width];
try{
PixelGrabber pg=new PixelGrabber(im,0,0,width,height,pixels,0,width);
pg.grabPixels();
}catch (InterruptedException e3) {
e3.printStackTrace();
}
//将数组中的象素产生一个图像
ImageProducer ip=new MemoryImageSource(width,height,pixels,0,width);//从内存到显示器
tmp=createImage(ip);
flag=true;
repaint();
}
public void jRun_ActionPerformed(ActionEvent e){
if(flag){//flag==1则图片加载成功
try{
PixelGrabber pg=new PixelGrabber(im,0,0,width,height,pixels,0,width);//抓出像素点?
pg.grabPixels();
}catch (InterruptedException e3) {
e3.printStackTrace();
}
initArrays();
//对图像进行平滑化处理,Alpha值保持不变
ColorModel cm=ColorModel.getRGBdefault();
//data=new int[height*width];
/*int m;
for (int i = 0; i < 10; i++) {
float r = (float)(cm.getRed(pixels[i]));
float g =( float)(cm.getGreen(pixels[i]));
float b = (float)(cm.getBlue(pixels[i]));
m=luminance(r, g, b);
System.out.print(m);
System.out.print(" ");
}*/
for (int i = 0; i < picsize; i++) {
float r = (float)(cm.getRed(pixels[i]));
float g =( float)(cm.getGreen(pixels[i]));
float b = (float)(cm.getBlue(pixels[i]));
data[i] = luminance(r, g, b);
}
computeGradients(gaussianKernelRadius, gaussianKernelWidth);
//readLuminance();
//if (contrastNormalized) normalizeContrast();
//computeGradients(gaussianKernelRadius, gaussianKernelWidth);
int low = Math.round(lowThreshold * MAGNITUDE_SCALE);
int high = Math.round( highThreshold * MAGNITUDE_SCALE);
performHysteresis(low, high);
//for (int i = 0; i < picsize; i++) {
//data[i] = data[i] > 0 ? -1 : 0xff000000;
// if(data[i]>0){
// pixels[i]=0xFFDC143C;
// }
//}
//thresholdEdges();
//writeEdges(data);
for(int i=40000;i<40100;i++){
pixels[i]=0xFFDC143C;
}
//将数组中的象素产生一个图像
ImageProducer ip=new MemoryImageSource(width,height,pixels,0,width);
tmp=createImage(ip);
flag=true;
repaint();
}
else{
JOptionPane.showMessageDialog(null,"请先打开一幅图片!",
"Alert",JOptionPane.WARNING_MESSAGE);
}
}
public void jSave_ActionPerformed(ActionEvent e){
}
public void jQuit_ActionPerformed(ActionEvent e){
//System.exit(0);
JOptionPane op =new JOptionPane();
int exit=op.showConfirmDialog(this,"你要退出吗? ? ?","退出",JOptionPane.YES_NO_OPTION);
if(exit==JOptionPane.YES_OPTION)
{
System.exit(0);
}else{ }
}
//The image that provides the luminance data used by this detector to
//generate edges.
//@return the source image, or null
/*
public BufferedImage getSourceImage() {
return sourceImage;
}
//Specifies the image that will provide the luminance data in which edges
// will be detected. A source image must be set before the process method
//is called.
// @param image a source of luminance data
public void setSourceImage(BufferedImage image) {
sourceImage = image;
}
// Obtains an image containing the edges detected during the last call to
// the process method. The buffered image is an opaque image of type
// BufferedImage.TYPE_INT_ARGB in which edge pixels are white and all other
// pixels are black.
//@return an image containing the detected edges, or null if the process
// method has not yet been called.
public BufferedImage getEdgesImage() {
return edgesImage;
}
// Sets the edges image. Calling this method will not change the operation
//of the edge detector in any way. It is intended to provide a means by
// which the memory referenced by the detector object may be reduced.
// @param edgesImage expected (though not required) to be null
public void setEdgesImage(BufferedImage edgesImage)
- 1
- 2
- 3
前往页