2012-04-21 15 views
5

私はゲームをプログラミングしています。透明な枠線(スプライト)で円を描いてみたいと思います。透明な周囲の画像の境界ピクセルを見つける(コリジョン検出のため)

透明でないピクセルとの照合を確認することで、円がイメージと重なっているかどうかを知ることは簡単です。

私が持っている問題は、跳ね返りを作るために通常の角度を知ることです。

イメージを与えたライブラリ(Java)またはアルゴリズムが必要です。イメージの境界にあるピクセルを持つ配列が返されるので、サーフェスの2つの点の間の傾きを見つけることができます。

私が学ぶことができるライブラリ/アルゴリズム/コードスニペットはありますか?

ありがとうございました

ローです。ここ

答えて

8

は単純な方法は次のとおり

を減算して、マスク上の単純なエッジ検出を行い、すべての透明ピクセルが0であり、すべての非透明なピクセルは次に1

ある原画像からマスクを作成しますピクセル(x,y)0または1で、ピクセルは(x+1,y+1)で絶対値をとっています。

これは、画像の端にあるピクセルの場合は1、それ以外の場合は0になります。

注:この方法は、画像を2次元関数として扱い、その勾配を計算することと本質的に同じです。エッジは、輝度表面のの急な部分(大きな勾配値に対応する)である。 gradient-based edge detectionに関するさらに詳しい情報があります。


ここで例えば画像です:ダウンと一つの画素と減算上に画像をシフトそして

Image Mask

Original Test Image

最初に全ての非透明ピクセルをマスクそれ自体から。

これにより、以下の画像が作成されます。今度は値1の行列インデックスを読み出すだけです。

これはエッジピクセルの配列です。

Edge Mask

注:あなたのイメージは、内部透明なピクセルが含まれている場合、この技術はまた、またはあなたのための問題であってもなくてもよいインテリアエッジを、見つけます...

3

これはI'vは、時間をかけて実装するものである:(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

関連する問題