问题
I'm constructing a flood fill algorithm that will hopefully, eventually, find a face in the center of a photograph based on the color at the exact center, and similar colors surrounding that. At the moment, however, my algorithm should take in any color within the bounds of the int array and transfer it over to a holder array, essentially making a copy of the original image. But this isn't working, and is resulting in a black image when I run it. Can anyone see the problem I'm missing?
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;
}
}
回答1:
You create int[][] called filled and then call floodFill(...) which returns without doing anything to the array. image.length is always equal to height and image[0].length is always equal to width, so it always returns from the second if statement.
You then build a BufferedImage from that blank array and write it to a file. All of the values in the array are initialized to 0, which gives you black.
Changing the for loop in findFace(..) to the below will save out the original image from your holder array.
for (int x = 0; x < height; x++) {
for (int y = 0; y < width; y++) {
bufferImage2.setRGB(y, x, image[x][y]);
}
}
But I'm not sure if this is what you're asking or not.
Edit: Try this out and see if it sends you in the right direction:
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;
}
来源:https://stackoverflow.com/questions/17302334/flood-fill-algorithm-resulting-in-black-image