我正在编写一个程序,该程序读取图像并计算有多少连接的像素。该图像包含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);
}
}
答案 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);
}
}