2013-06-25 4 views
0

홍수 채우기 알고리즘을 구성하여 정확한 중심의 색상과 그 주변의 색상을 기준으로 사진 중앙에 얼굴을 찾는 것이 좋습니다. 그러나 현재, 내 알고리즘은 int 배열의 범위 내에서 어떤 색상 으로든 가져와 원본 배열의 사본을 만드는 홀더 배열로 전송해야합니다. 그러나 이것은 작동하지 않으며, 그것을 실행할 때 검은 색 이미지를 초래합니다. 아무도 내가 누락 된 문제를 볼 수 있습니까?홍수 채우기 알고리즘 결과가 검은 색으로 나타남

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; 
} 

}

+0

가장 큰 문제는 재귀 홍수 충전 알고리즘을 사용하고 있습니다. 이것은 작은 이미지에서 작동하지만 중간 크기에서 큰 이미지에는 확실히 실패합니다. 알고리즘에 대한 스캔 라인 방식을 사용하는 것이 좋습니다. 자세한 내용은 *** [this] (http://en.wikipedia.org/wiki/Flood_fill) *** 페이지를 참조하십시오. –

답변

0

당신은 INT [] [] 를 작성하고 배열에 아무것도하지 않고 반환 플러드 필 (...)를 호출라는 만듭니다. image.length는 항상 height와 같고 image [0] .length는 항상 width와 같습니다. 따라서 항상 두 번째 if 문에서 반환됩니다.

그런 다음 빈 배열에서 BufferedImage를 만들고 파일에 씁니다. 배열의 모든 값은 0으로 초기화되어 검정을 제공합니다.

findFace (..)의 for 루프를 아래로 변경하면 홀더 배열의 원본 이미지가 저장됩니다.

 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; 
} 
+0

아, 당신은 두 번째 경우에 대해 완전히 맞습니다. 왜 내가 그것을 썼는지 모르겠다. x와 y의 위치를 ​​검사하여 경계선이 아닌지 확인해야한다. 지금 ArrayIndexOutOfBoundsException 오류가 발생하지만 앞으로 나아가 야합니다. 감사! – user2506643

+0

나는 일종의 일하는 방법을 포함하도록 위의 내용을 편집 할 것이다. 지금은 더 이상 조사 할 시간이 없지만 시작하기에 충분할 수 있습니다. – MaxAlexander

+0

이런 거친, 고마워. 그것은 정말 잘 작동합니다. 감사합니다. – user2506643