0

我正在构建一个泛光填充算法,希望最终能够根据确切中心的颜色以及周围的类似颜色在照片的中心找到一张脸。然而,目前,我的算法应该采用 int 数组范围内的任何颜色,并将其转移到 holder 数组,本质上是制作原始图像的副本。但这不起作用,并且在我运行它时会导致黑色图像。谁能看到我缺少的问题?

public class TemplateMaker {

public static void main(String[] args) throws IOException {
    importPhoto();
}

public static void importPhoto() throws IOException {
    File imgPath = new File("/Pictures/BaseImage.JPG");
    BufferedImage bufferedImage = ImageIO.read(imgPath);
    establishArray(bufferedImage);
}

public static void establishArray(BufferedImage bufferedImage) throws IOException {
    //byte[] pixels = hugeImage.getData();
    int width = bufferedImage.getWidth();
    System.out.println(width);
    int height = bufferedImage.getHeight();
    System.out.println(height);
    int[][] result = new int[height][width];
    for (int i = 0; i < height; i++)
        for (int j = 0; j < width; j++) {
            result[i][j] = bufferedImage.getRGB(j, i);
        }
    findFace(result);
}

public static void findFace(int[][] image) throws IOException {
    int height = image.length;
    int width = image[0].length;
    Color centerStart = new Color(image[height / 2][width / 2], true);
    System.out.println(centerStart.getRGB());
    System.out.println(Color.blue.getRGB());

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

    floodFill(height / 2, width / 2, centerStart, image, filled, height, width);

    //construct the filled array as image.
    BufferedImage bufferImage2 = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    for (int x = 0; x < height; x++) {
        for (int y = 0; y < width; y++) {
            bufferImage2.setRGB(y, x, filled[x][y]);
        }
    }
    //save filled array as image file
    File outputfile = new File("/Pictures/saved.jpg");
    ImageIO.write(bufferImage2, "jpg", outputfile);
}

public static int[][] floodFill(int x, int y, Color targetColor, int[][] image, int[][] filled, int height, int width) {

    //execute something similar once algorithm works. 
    // if (image[x][y] < targetColor.getRGB()/2 || image[x][y] > targetColor.getRGB()*2) return filled;

    if (image[x][y] == Color.blue.getRGB()) {
        return filled;
    }
    if (image.length < 0 || image[0].length < 0 || image.length >= height || image[0].length >= width) {
        return filled;
    }
    filled[x][y] = image[x][y];
    image[x][y] = Color.blue.getRGB();

    floodFill(x - 1, y, targetColor, image, filled, height, width);
    floodFill(x + 1, y, targetColor, image, filled, height, width);
    floodFill(x, y - 1, targetColor, image, filled, height, width);
    floodFill(x, y + 1, targetColor, image, filled, height, width);
    return filled;
}

}

4

1 回答 1

0

您创建 int[][] 称为填充,然后调用 floodFill(...) 无需对数组执行任何操作即可返回。image.length 总是等于 height 并且 image[0].length 总是等于 width,所以它总是从第二个 if 语句返回。

然后,您从该空白数组构建一个 BufferedImage 并将其写入文件。数组中的所有值都初始化为 0,即为黑色。

将 findFace(..) 中的 for 循环更改为以下内容将从您的 holder 数组中保存原始图像。

        for (int x = 0; x < height; x++) {
        for (int y = 0; y < width; y++) {
            bufferImage2.setRGB(y, x, image[x][y]);
        }
    }

但我不确定这是否是你要问的。

编辑:试试这个,看看它是否向你发送了正确的方向:

    public static int[][] floodFill(int x, int y, Color targetColor, int[][] image, int[][] filled, int height, int width) {

    //execute something similar once algorithm works. 
    // if (image[x][y] < targetColor.getRGB()/2 || image[x][y] > targetColor.getRGB()*2) return filled;

    if (image[x][y] == Color.blue.getRGB()) {
        System.out.println("returned if 1");
        return filled;
    }
    /*if (image.length < 0 || image[0].length < 0 || image.length >= height || image[0].length >= width) {
        return filled;
    }*/
    filled[x][y] = image[x][y];
    image[x][y] = Color.blue.getRGB();

    if (x - 1 <= 0 && y < width) {
        floodFill(x - 1, y, targetColor, image, filled, height, width);
    }

    if(x + 1 < height && y >= 0 && y < width) {
        floodFill(x + 1, y, targetColor, image, filled, height, width);
    }

    if(x >= 0 && x < height && y - 1 <= 0) {
        floodFill(x, y - 1, targetColor, image, filled, height, width);
    }

    if(x >= 0 && x < height && y + 1 < width) {
        floodFill(x, y + 1, targetColor, image, filled, height, width);
    }

    return filled;
}
于 2013-06-25T17:12:43.167 回答