2012-04-21 29 views
5

Programuję grę i chcę obrazować kolimację za pomocą przezroczystych obramowań (sprites).Znajdowanie pikseli obramowania obrazu z przezroczystym otoczeniem (do wykrywania kolizji)

Łatwo jest stwierdzić, czy okrąg pokrywa się z obrazem, sprawdzając kolory z pikselami, które nie są przezroczyste.

Problem polega na tym, aby znać normalny kąt w celu odbicia.

Potrzebowałbym biblioteki (Java) lub algorytmu, który dałby obraz, który zwróciłby tablicę z pikselami znajdującymi się na granicy obrazu, dzięki czemu mogę znaleźć nachylenie między dwoma punktami powierzchni.

Czy istnieje biblioteka/algorytm/fragment kodu, z którego mogę się uczyć?

Bardzo dziękuję

Lau.

Odpowiedz

8

Oto proste podejście:

Tworzenie maski z oryginalnego obrazu, gdzie wszystkie przezroczyste piksele są 0 i wszystkie nieprzezroczyste piksele są 1

Następnie wykonać proste wykrywanie krawędzi na masce przez odjęcie każdy piksel (x,y), który będzie 0 lub 1, z piksela (x+1,y+1) i przyjmowanie wartości bezwzględnej.

To da Ci 1 dla pikseli na krawędzi obrazu i 0 wszędzie indziej.

Uwaga: ta metoda jest w zasadzie równoważna traktowaniu obrazu jako funkcji 2d i obliczaniu gradientu. Krawędzie są stromymi częściami intensywności (które odpowiadają dużym wartościom gradientu). Oto kilka informacji na temat gradient-based edge detection.


Oto przykładowy obraz:

Original Test Image

pierwsza maska ​​wszystkie nieprzezroczyste piksele:

Image Mask

następnie przesunięcie obrazu w dół i ponad jeden piksel i odjąć to od samego siebie.

Spowoduje to utworzenie obrazu poniżej. Teraz po prostu odczytaj indeksy macierzy o wartości 1.

To jest twój zestaw pikseli krawędzi.

Edge Mask

Uwaga: Jeśli obrazy zawierają wewnętrzne przezroczyste piksele, technika ta będzie również znaleźć wewnętrzne krawędzie, które mogą lub nie mogą być problemem dla Ciebie ...

3

To co I'v realizowany w czasie: (detectionStrength najlepiej 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; 
} 

I klasa Pixel (tylko bardzo proste przedłużenie 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 + "]"; 
    } 
} 

Obraz utworzony za pomocą algorytmu będzie:

StackOverflow logo

Powiązane problemy