使用Flood Fill 4算法时如何克服“细边界”问题?

tvel 发布于 2019-03-09 java 最后更新 2019-03-09 14:41 0 浏览

我正在编写一个实现Flood Fill 4算法的应用程序。只要边界很厚,它就可以很好地工作。该算法在边界内填充某种颜色。我试图让边界变薄,但在这种情况下,像素能够走出边界,程序崩溃。

enter image description here 填充算法在“厚边框”区域内工作得非常好,这是直角三角形。然而,该算法在其他四个区域内不起作用,因为边界较薄,即发生泄漏。除了使其他寄宿生人士变得厚实,我有什么方法可以使用? 这是完整的代码,它只是一个类:
   import java.awt.Color;
   import java.awt.Container;
   import java.awt.Image;
   import java.awt.image.BufferedImage;
   import javax.swing.ImageIcon;
   import javax.swing.JFrame;
   import javax.swing.JLabel;
   public class MyPolygon extends JFrame {
private JLabel my;
private BufferedImage buffered;
public MyPolygon() throws InterruptedException {
    createMy();
}
private void createMy() throws InterruptedException {
    Container contentPane = getContentPane();
    contentPane.setBackground(Color.WHITE);
    contentPane.setLayout(null);
    contentPane.setSize(1200, 900);
my = new JLabel();
    my.setIcon(new ImageIcon("myImage.png"));
    my.setBounds(10,200, 1000, 800);
    contentPane.add(my);
setSize(1200, 900);
    setVisible(true);
    setLocationRelativeTo(null);
Image img = ((ImageIcon) my.getIcon()).getImage();
    buffered = new BufferedImage(img.getWidth(null),
            img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
    buffered.getGraphics().drawImage(img, 0, 0, null);
int fill = 100;
    boundaryFill4(200, 215, fill, 50);
    my.setIcon(new ImageIcon(buffered));
}
// Flood Fill method
public void boundaryFill4(int x, int y, int fill, int boundary) {
Color c = new Color(buffered.getRGB(x, y));
    int current = c.getRed();
    System.out.println(x + " " + y + " | " + current);
if ((current > boundary) && (current != fill)) {
        int red = fill;
        int green = fill;
        int blue = fill;
        c = new Color(red, green, blue);
        buffered.setRGB(x, y, c.getRGB());
boundaryFill4(x + 1, y, fill, boundary);
        boundaryFill4(x - 1, y, fill, boundary);
        boundaryFill4(x, y + 1, fill, boundary);
        boundaryFill4(x, y - 1, fill, boundary);
    }
}
// Main method
public static void main(String args[]) throws InterruptedException {
    MyPolygon my = new MyPolygon();
    my.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
 }
已邀请:

wmagni

赞同来自:

您的if需要一些工作,除了颜色之外,递归没有结束条件。 1 函数boundaryFill4需要查找x和y小(图片的顶部或左边)或大(底部或顶部边缘)。它看起来像这样:

if (x < 0 || x > 200 || y < 0 || y > 200) {
    return;
}
2 如果仔细观察图像,可以看到边框线的边缘(特别是薄的边缘)使用褪色像素来防止线看起来过于锯齿。这是一种平滑技术。 一个调试技巧是在boundaryFill4函数的顶部添加一个短时间延迟,以便您可以看到正在发生的过程。它应该显示填充物逃逸的位置,你可以看看那个爆炸点以获得更多线索。 该测试目前寻找的像素中的红色比50级更多但与填充颜色的红色不同。 中心的白色可能具有全部三个RGB级别。 边框具有所有三种RGB颜色看起来接近0的像素,但是平滑技术使其在某些像素中放置更高的RGB值以隐藏锯齿。当它很薄时,一定要检查边框实际上是什么颜色。也许线条的中心像素比你想象的要亮。 填充颜​​色是一种深灰色。
  • 代码会找到白色,其规则为“红色50以上”。
  • 代码将避免使用“not RED == fill”
  • 规则重做已填充的代码
  • 它在平滑的边界上的作用在空中。我的猜测是,有一个地方,边界的较亮部分比50更亮(红色)
以下是一些想法:
  1. 当与填充颜色进行比较时,更改规则以查看所有三种颜色,而不仅仅是红色。 (红色==填充,绿色==填充和蓝色==填充)这可能没有帮助。
  2. 也许您可以传递起点的颜色并使用它进行比较,而不是只填充比50更亮的所有内容。要么寻找精确的颜色匹配,要么寻找足够接近的匹配,其中点在10以内传递原始颜色。
  3. 如果这不起作用,请使用延迟来查看它逃脱的地方的唯一性。