使用递归连接像素

时间:2014-10-11 21:12:26

标签: java recursion methods

我正在编写一个程序,该程序读取图像并计算有多少连接的像素。该图像包含4个黑色像素形状,位于白色背景上。

最后,我应该count = 4;

我在编写递归方法时遇到问题,该方法读取每个像素并检查它是黑色还是白色。如果它是黑色的,我需要检查它周围是否有任何其他黑色像素,如果没有,则将计数增加一个。

有什么想法吗?

尝试递归方法:

public int recursive(int[][] g, int i,int j){
        //pseudo code
        if(it is white)
            return 0;
        int north = recursive(g,i,j+1);
        int south = recursive(g,i,j-1);
        int west = recursive(g,i-1,j);
        int east = recursive(g,i+1,j);
        int nw = recursive(g,i-1,j+1);
        int ne = recursive(g,i+1,j+1);
        int sw = recursive(g,i-1,j-1);
        int se = recursive(g,i+1,j-1);
        return north+south+west+east+nw+ne+sw+se+1;
    }

另一种计算方法:

int[][] grid = new int[width][height];

        for(int i = 0; i < width; i++){
            for(int j = 0; j < height; j++){
                recursive(grid,i,j);
            }
        }

2 个答案:

答案 0 :(得分:2)

我想出了以下递归解决方案:

public class Picture {

  private static final int[][] PICTURE = new int[][] { 
    { 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1 },
    { 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0 },
    { 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
    { 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1 },
    { 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0 },
    { 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0 }, 
    { 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 }
  };

  private boolean[][] visited;
  private int[][] picture;

  public Picture(int[][] picture) {
    this.picture = picture;
  }

  public int countBlobs() {
    if (picture.length == 0) {
      return 0;
    }
    int blobCount = 0;
    visited = new boolean[picture.length][picture[0].length];
    for (int i = 0; i < picture.length; i++) {
      for (int j = 0; j < picture[i].length; j++) {
        if (!visited[i][j]) {
          if (!isWhite(i, j)) {
            countHelper(i, j);
            blobCount++;
          }
          visited[i][j] = true;
        }
      }
    }
    return blobCount;
  }

  private void countHelper(int i, int j) {
    visited[i][j] = true;
    if (!isWhite(i, j)) {
      for (int deltaI = -1; deltaI <= 1; deltaI++) {
        for (int deltaJ = -1; deltaJ <= 1; deltaJ++) {
          int adjI = i + deltaI;
          int adjJ = j + deltaJ;
          if (inBounds(adjI, adjJ) && !visited[adjI][adjJ]) {
            countHelper(adjI, adjJ);
          }
        }
      }
    }
  }

  private boolean inBounds(int i, int j) {
    return i >= 0 && j >= 0 && i < picture.length && j < picture[i].length;
  }

  private boolean isWhite(int i, int j) {
    return inBounds(i, j) && picture[i][j] == 0;
  }

  public static void main(String[] args) {
    System.out.println(new Picture(PICTURE).countBlobs());
  }
}

答案 1 :(得分:1)

在我看来,你想要做的是计算图像中单独形状的数量,而不是连接像素的数量。连接像素的数量可能远远高于四个。

我看到它的方式,最好的方法是创建一个单独的数组,用于跟踪天气或不是像素已包含在形状中,以便您可以确保没有像素包含在形状两次。要计算形状的数量,您需要做的就是使用递归方法迭代图像中的每个像素,以找到连续的形状,并标记您在形状中包含的每个像素。

//Pass an array if integers as arguments
//Counts the number of distinct continuous "shapes"(blocks of non-zero integers).
public static int countShapes(int[][] image){
    //this boolean array keeps track of what pixels have been included in a shape
    boolean[][] pixelsInShape = new boolean[image.length][image[0].length];
    int shapeCount=0;
    for(int i = 0; i < image.length; i++){
        for(int j = 0; j < image[0].length; j++){
            if(image[i][j]!=0 && !pixelsInShape[i][j]){
                shapeCount++;
                findShape(image,pixelsInShape,i,j);
            }
        }
    }
    return shapeCount;
}

public static void findShape(int[][] image, boolean[][] pixelsInShape, int row, int col){
    //before being  included in a shape, a pixel must be withing the bounds of the image, not zero, and not already in a shape
    if(row >= 0 && row < image.length && col >= 0 && col < image[0].length && image[row][col]!=0 && !pixelsInShape[row][col]){
        //marks the pixel included in the inclusion array
        pixelsInShape[row][col]=true;
        //recursive calls to all neighboring pixels.
        findShape(image,pixelsInShape,row,col+1);
        findShape(image,pixelsInShape,row,col-1);
        findShape(image,pixelsInShape,row-1,col);
        findShape(image,pixelsInShape,row+1,col);
        findShape(image,pixelsInShape,row-1,col+1);
        findShape(image,pixelsInShape,row+1,col+1);
        findShape(image,pixelsInShape,row-1,col-1);
        findShape(image,pixelsInShape,row+1,col-1);
    }
}