2014-12-31 27 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度 轉向方向