daf*_*ero 12 java image-manipulation flood-fill
我在Java中使用递归Flood填充算法来填充图像的某些区域.使用非常小的图像可以正常工作,但是当de image变大时,JVM会给出Stack Over Flow Error.
这就是我必须使用我自己的堆栈使用Flood Fill重新实现该方法的原因.(我认为这是在这种情况下做到这一点的最好方法)
任何人都可以解释我如何编码吗?(如果你手边没有代码,算法的伪代码就可以了)
我在互联网上看了很多,但我还不太清楚.
编辑:我添加了我的递归代码
public void floodFill(int x, int y, Color targetColor,Color replacementColor) {
if (img.getRGB(x, y) != targetColor.getRGB()) return;
img.setRGB(x, y, replacementColor.getRGB());
floodFill(x - 1, y, targetColor, replacementColor);
floodFill(x + 1, y, targetColor, replacementColor);
floodFill(x, y - 1, targetColor, replacementColor);
floodFill(x, y + 1, targetColor, replacementColor);
return;
}
Run Code Online (Sandbox Code Playgroud)
谢谢!
Gan*_*ant 17
您可以使用Queue从floodfill算法中删除递归.以下是一些基本想法:
下面是我的Java代码,用于解决类似但不同的blob检测问题.我希望你能从中得到一些想法,并能使问题适应它.但是代码并没有很好的考虑.
package blobdetector;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;
import javax.imageio.ImageIO;
import javax.management.Query;
public class Main {
public Main() {
}
public static boolean isBlack(BufferedImage image, int posX, int posY) {
int color = image.getRGB(posX, posY);
int brightness = (color & 0xFF) + ((color >> 2) & 0xFF)
+ ((color >> 4) & 0xFF);
brightness /= 3;
return brightness < 128;
}
public static void main(String[] args) {
if (args.length != 1) {
System.err.println("ERROR: Pass filename as argument.");
return;
}
String filename = args[0];
// String filename =
// "C:\\Users\\Natthawut\\Desktop\\blob.jpg";
try {
BufferedImage bimg = ImageIO.read(new File(filename));
boolean[][] painted = new boolean[bimg.getHeight()][bimg.getWidth()];
for (int i = 0; i < bimg.getHeight(); i++) {
for (int j = 0; j < bimg.getWidth(); j++) {
if (isBlack(bimg, j, i) && !painted[i][j]) {
Queue<Point> queue = new LinkedList<Point>();
queue.add(new Point(j, i));
int pixelCount = 0;
while (!queue.isEmpty()) {
Point p = queue.remove();
if ((p.x >= 0)
&& (p.x < bimg.getWidth() && (p.y >= 0) && (p.y < bimg
.getHeight()))) {
if (!painted[p.y][p.x]
&& isBlack(bimg, p.x, p.y)) {
painted[p.y][p.x] = true;
pixelCount++;
queue.add(new Point(p.x + 1, p.y));
queue.add(new Point(p.x - 1, p.y));
queue.add(new Point(p.x, p.y + 1));
queue.add(new Point(p.x, p.y - 1));
}
}
}
System.out.println("Blob detected : " + pixelCount
+ " pixels");
}
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
测试输入:

这是我在此页面上的信息的实施基础和其他在网络上收集的(测试和工作)
玩得开心 ;-)
public static void floodFillImage(BufferedImage image,int x, int y, Color color)
{
int srcColor = image.getRGB(x, y);
boolean[][] hits = new boolean[image.getHeight()][image.getWidth()];
Queue<Point> queue = new LinkedList<Point>();
queue.add(new Point(x, y));
while (!queue.isEmpty())
{
Point p = queue.remove();
if(floodFillImageDo(image,hits,p.x,p.y, srcColor, color.getRGB()))
{
queue.add(new Point(p.x,p.y - 1));
queue.add(new Point(p.x,p.y + 1));
queue.add(new Point(p.x - 1,p.y));
queue.add(new Point(p.x + 1,p.y));
}
}
}
private static boolean floodFillImageDo(BufferedImage image, boolean[][] hits,int x, int y, int srcColor, int tgtColor)
{
if (y < 0) return false;
if (x < 0) return false;
if (y > image.getHeight()-1) return false;
if (x > image.getWidth()-1) return false;
if (hits[y][x]) return false;
if (image.getRGB(x, y)!=srcColor)
return false;
// valid, paint it
image.setRGB(x, y, tgtColor);
hits[y][x] = true;
return true;
}
Run Code Online (Sandbox Code Playgroud)