2013-06-25 102 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 充滿然後調用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; 
} 
+0

哦,如果說明的話,你完全正確。我不知道我爲什麼寫這個,它應該檢查x和y的位置以確保它們不超出範圍。現在我收到了一個ArrayIndexOutOfBoundsException錯誤,但這是一個進步。謝謝! – user2506643

+0

我將編輯上面的內容以包含一種方法,即...種類的作品。我現在沒有時間進一步調查,但它可能足以讓你開始。 – MaxAlexander

+0

聖路易斯,感謝您的幫助。這真的很好。我很感激。 – user2506643