2014-12-31 18 views
0

我想创建一个给定图像和点的对象,它将跟踪该图像的内边缘。BufferedImage的边缘检测代码

为简单起见,边缘将始终为RGB颜色黑色。

我定义RIGHT DOWN LEFT UP(顺时针)

的枚举我开始在点P处。

基于以RIGHT开头的当前Direction,我在图像中移动像素。

如果这不是边框像素我将我的方向移回一步反顺时针。例如(左 - >下) 如果我不能移动我选择的方向,我将移动到下一个方向。 我将点添加到我的边界数组。

我这样做直到我们回到第一个边界像素。

那计划...

到目前为止,我碰钉子的时候,我有后立即从UP到右去,但回来到右再次以保持集中于边缘的方向,而不是走回头路进入图像。

如果使用UP,我尝试使用一个布尔标志,指示右边的下一个方向为UP而不是DOWN。

任何指导将不胜感激。 我有下面的完整代码。

CODE:

package edgedection; 

import static edgedection.EdgeDection.testImage; 
import java.awt.Color; 
import java.awt.Point; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 

    /** 
    * 
    * @author Fionán 
    */ 
    public class EdgeDection { 

     /** 
     * @param args the command line arguments 
     */ 
     static BufferedImage testImage = null; 

     { 
      try { 
       testImage = ImageIO.read(this.getClass().getResourceAsStream("testImage2.png")); 

      } catch (IOException ex) { 
       Logger.getLogger(EdgeDection.class.getName()).log(Level.SEVERE, null, ex); 
      } 
     } 

     static enum DIRECTION { 

      RIGHT, DOWN, LEFT, UP, NOMOVE 
     } 

     BufferedImage bi; 
     int borderColor = Color.black.getRGB(); 

     DIRECTION facing; 
     Point p; 
     ArrayList<Point> borders; 
     boolean upFlag = false; 
     int x = p.x; 
     int y = p.y; 

     public static void main(String[] args) { 

      int x = 150; 
      int y = 60; 
    //forcing instance for loading Images only. 
      EdgeDection test= new EdgeDection(); 

      JFrame show = new JFrame(); 
      show.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

      JLabel picLabel = new JLabel(new ImageIcon(testImage)); 
      show.add(picLabel); 
      show.pack(); 

      show.setVisible(true); 

      EdgeDection dector = new EdgeDection(testImage, new Point(x, y)); 
      dector.start(); 

      dector.highLightEdge(); 

      show.repaint(); 

     } 

     boolean canMove(DIRECTION d, Point p) { 

      switch (d) { 
       case RIGHT: 
        return bi.getRGB(p.x + 1, p.y) != borderColor; 
       case DOWN: 
        return bi.getRGB(p.x, p.y + 1) != borderColor; 
       case LEFT: 
        return bi.getRGB(p.x - 1, p.y) != borderColor; 
       //Deafult is up 
       case UP: 
        return bi.getRGB(p.x, p.y - 1) != borderColor; 
       default: 
        return false; 

      } 

     } 

     public EdgeDection(BufferedImage bi, Point p) { 
      this.facing = DIRECTION.RIGHT; 
      this.bi = bi; 
      this.p = p; 
      this.borders = new ArrayList<>(); 

     } 

     public EdgeDection() { 
     } 

     DIRECTION getDirection() { 
      return null; 
     } 

     void addBorder(Point p) { 
      if(borders.isEmpty()){ 

      x = p.x; 
      y = p.y; 
      } 
      borders.add(p); 
     } 

     void start() { 

      do { 

       System.out.println("Checking " + p.x + " " + p.y + facing); 
       if (canMove(facing, p)) { 


        if (upFlag) { 
         facing = DIRECTION.UP; 
         // p =new Point(p.x+1,p.y); 
        } 
        p = NextPointByDirection(); 


        if(!upFlag) stepBackDirection(); 

        if(upFlag)upFlag=false; 


       } else { 
        addBorder(p); 
        setNextDirection(); 

        System.out.println("going " + facing + " border array size = "+ borders.size()); 
        System.out.println("Up Flag status "+upFlag); 
       } 

      } while (facing != DIRECTION.NOMOVE && (p.x != x || p.y != y)); 



     } 

     private void stepBackDirection() { 

      switch (facing) { 

       case RIGHT: 
        if(upFlag) {facing = DIRECTION.UP;}else{ 
        facing = DIRECTION.RIGHT; 
        } 
        break; 
       case DOWN: 
        facing = DIRECTION.RIGHT; 
        break; 
       case LEFT: 
        facing = DIRECTION.DOWN; 

        break; 
       case UP: 
        facing = DIRECTION.LEFT; 

      } 
     } 

     private void setNextDirection() { 

      switch (facing) { 
       case RIGHT: 

        facing = DIRECTION.DOWN; 

        if (upFlag) { 
         facing = DIRECTION.UP; 
         upFlag = false; 
        } 
        return; 
       case DOWN: 
        facing = DIRECTION.LEFT; 
        return; 
       case LEFT: 
        facing = DIRECTION.UP; 
        return; 
       case UP: 
        upFlag = true; 
        facing = DIRECTION.RIGHT; 

    //    upFlag = true; 
    //    if (canMove(facing, new Point(p.x + 1, p.y - 1))){ 
    //    p = new Point(p.x + 1, p.y - 1); 
    //     
    //    } ; 
    // 
    //    if (upFlag) { 
    //     facing = DIRECTION.RIGHT; 
    //    } 

      } 
     } 

     private Point NextPointByDirection() { 
    //  if (upFlag) { 
    //   facing = DIRECTION.UP; 
    //   upFlag = !upFlag; 
    //  } 
      switch (facing) { 
       case RIGHT: 
        return new Point(p.x + 1, p.y); 
       case DOWN: 
        return new Point(p.x, p.y + 1); 
       case LEFT: 
        return new Point(p.x - 1, p.y); 

       default: 
        return new Point(p.x, p.y - 1); 

      } 
     } 

     private void print() { 

      for (Point p : borders) { 

       System.out.print(p.x + " " + p.y + " "); 

      } 
     } 

     void highLightEdge() { 

      for (Point p : borders) { 

       bi.setRGB(p.x, p.y, Color.RED.getRGB()); 

      } 
     } 

    } 

回答

1

任何有兴趣,我解决了这个问题,使用堆栈的。

预先使用要采取的指示顺序填充堆栈。 开始向一个方向移动。 如果它可以移动的方向是从栈 其他 打一边界 这个方向推到堆栈 弹出添加的边框设置边框 如果边界已经在设定破坏的循环else相对90度 转向方向