2012-04-21 17 views
5

Tôi đang lập trình một trò chơi và tôi muốn hình ảnh colide với đường viền trong suốt (sprites) agnist một vòng tròn.Tìm điểm ảnh đường viền của hình ảnh với xung quanh trong suốt (để phát hiện rạch)

Thật dễ dàng để biết liệu vòng tròn có chồng chéo hình ảnh hay không bằng cách kiểm tra colsion bằng các pixel không trong suốt.

Vấn đề tôi phải biết là góc bình thường để thực hiện trả lại.

Tôi sẽ cần một thư viện (Java) hoặc thuật toán đưa ra một hình ảnh nó sẽ trả về một mảng với các điểm ảnh nằm ở biên của hình ảnh để tôi có thể tìm thấy độ dốc giữa hai điểm của bề mặt.

Có bất kỳ thư viện/thuật toán/đoạn mã nào tôi có thể học hỏi không?

Cảm ơn bạn rất nhiều

Lau.

Trả lời

8

Dưới đây là một phương pháp đơn giản:

Tạo một mặt nạ từ ảnh gốc nơi tất cả các pixel trong suốt là 0 và tất cả các pixel không trong suốt được 1

Sau đó, thực hiện một phát hiện cạnh đơn giản trên mặt nạ của bạn bằng cách trừ mỗi pixel (x,y), sẽ là 0 hoặc 1, từ pixel (x+1,y+1) và lấy giá trị tuyệt đối.

Điều này sẽ cung cấp cho bạn 1 cho pixel trên cạnh của hình ảnh và 0 ở mọi nơi khác.

Lưu ý: phương pháp này về cơ bản tương đương với việc xử lý hình ảnh dưới dạng hàm 2d và tính toán độ dốc của nó. Các cạnh là dốc các phần của bề mặt cường độ (tương ứng với các giá trị độ dốc lớn). Dưới đây là một số thông tin khác trên gradient-based edge detection.


Dưới đây là một hình ảnh ví dụ:

Original Test Image

Đầu che tất cả các pixel không trong suốt:

Image Mask

Sau đó chuyển hình ảnh xuống và hơn một pixel và trừ nó từ chính nó.

Điều này tạo hình ảnh bên dưới. Bây giờ chỉ cần đọc các chỉ số ma trận với giá trị 1.

Đó là mảng pixel cạnh của bạn.

Edge Mask

Lưu ý: nếu hình ảnh của bạn có chứa pixel nội thất minh bạch, kỹ thuật này cũng sẽ tìm thấy cạnh nội thất, mà có thể hoặc không thể là một vấn đề cho bạn ...

3

Đây là những gì I'v thực hiện theo thời gian: (detectionStrength tốt nhất là 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; 
} 

Và lớp Pixel (chỉ là một phần mở rộng rất đơn giản của 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 + "]"; 
    } 
} 

Các hình ảnh được tạo bằng thuật toán, sẽ là:

StackOverflow logo