2012-04-21 28 views
5

我編程比賽,我想colide與透明邊框(精靈)圖像時圖像的邊界像素agnist一個圓。尋找具有透明周邊(用於colision檢測)

可以很容易地知道,如果圓是通過檢查與不是透明的像素colsion重疊的圖像。

我的問題是要知道正常的角度,以使反彈。

我需要給定的圖像,將返回與該是在圖像的邊界,所以我能找到的表面的兩點之間的斜率的像素陣列庫(爪哇)或算法。

是否有任何庫/算法/代碼片段我可以借鑑?

非常感謝你

劉。

回答

8

這裏有一個簡單的方法:

創建從原始圖像口罩,所有透明像素0和所有非透明像素1

然後減去你的面具執行一個簡單的邊緣檢測每個像素(x,y),將是01,來自像素(x+1,y+1)並取絕對值。

這將給你一個1像素的邊緣圖像和0其他地方。

注意:該方法基本上等同於處理所述圖像作爲2D函數並計算其梯度。邊緣是陡峭的部分強度表面(對應於較大的梯度值)。以下是關於gradient-based edge detection的更多信息。


下面是一個例子圖像:

Original Test Image

第一掩模的所有非透明像素:

Image Mask

然後,圖像向下移動和在一個像素和減去它本身。

這會創建下面的圖像。現在簡單地讀出值爲1的矩陣索引。

這就是你的邊緣像素陣列。

Edge Mask

注意:如果你的圖像包含內部透明像素,這種技術也將找到的內部邊緣,這可能是也可能不是你的問題...

3

這就是我心中已經隨時間實施:(detectionStrength最好是10)

public static List<Pixel> getEdges(Image image, int detectionStrength) { 

    boolean[][] opaque = new boolean[image.getWidth(null)][image 
      .getHeight(null)]; 
    LinkedList<Pixel> edges = new LinkedList<Pixel>(); 
    int rgb; 

    /* 
    * convert to BufferedImage to get individual pixel colors 
    */ 
    BufferedImage bufferedImage; 
    if (image instanceof BufferedImage) 
     bufferedImage = (BufferedImage) image; 
    else { 
     bufferedImage = new BufferedImage(image.getWidth(null), 
       image.getHeight(null), BufferedImage.TYPE_INT_ARGB); 
     bufferedImage.createGraphics().drawImage(image, 0, 0, null); 
    } 

    for (int i = 0; i < opaque.length; i++) { 
     for (int j = 0; j < opaque[i].length; j++) { 
      rgb = bufferedImage.getRGB(i, j); 
      opaque[i][j] = (rgb >> 24 & 0xFF) > detectionStrength; // transparency 
     } 
    } 

    /* 
    * If a pixel is opaque, but is surrounded, with at least one 
    * transparent pixel, it is considered an edge. 
    */ 
    for (int x = 0; x < opaque.length; x++) { 
     for (int y = 0; y < opaque[x].length; y++) { 
      if ((x == 0) || (x == opaque.length - 1) || (y == 0) 
        || (y == opaque[x].length - 1)) { // border pixel 
       if (opaque[x][y]) // if opaque, it is automatically an edge, 
            // no matter its surrounding... 
        edges.add(new Pixel(x, y, new Color(bufferedImage 
          .getRGB(x, y)))); 

      } else { // not a border pixel 
       if (opaque[x][y] 
         && (!opaque[x - 1][y - 1] || !opaque[x][y - 1] 
           || !opaque[x + 1][y - 1] 
           || !opaque[x - 1][y] || !opaque[x + 1][y] 
           || !opaque[x - 1][y + 1] 
           || !opaque[x][y + 1] || !opaque[x + 1][y + 1])) 
        edges.add(new Pixel(x, y, new Color(bufferedImage 
          .getRGB(x, y)))); 
      } 
     } 
    } 

    return edges; 
} 

和像素級(只是一個Point非常簡單的擴展名):

public class Pixel extends Point implements Cloneable { 

    private static final long serialVersionUID = -9053911985748552077L; 

    public Color color; 

    public Pixel(int x, int y, Color c) { 
     super(x, y); 
     color = c; 
    } 

    public Pixel(Pixel other) { 
     super(other.x, other.y); 
     color = other.color; 
    } 

    public Color getColor() { 
     return color; 
    } 

    public void setColor(Color newColor) { 
     color = newColor; 
    } 

    public int hashCode() { 
     final int prime = 31; 
     int result = super.hashCode(); 
     result = prime * result + ((color == null) ? 0 : color.hashCode()); 
     return result; 
    } 

    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (!super.equals(obj)) 
      return false; 
     if (!(obj instanceof Pixel)) 
      return false; 
     Pixel other = (Pixel) obj; 
     if (color == null) { 
      if (other.color != null) 
       return false; 
     } else if (!color.equals(other.color)) 
      return false; 
     return true; 
    } 

    public Object clone() { 
     return new Pixel(x, y, color); 
    } 

    public String toString() { 
     return "Pixel [color=" + color + ", x=" + x + ", y=" + y + "]"; 
    } 
} 

的使用該算法創建的圖像將爲:

StackOverflow logo