【问题标题】:How to overcome "thin border" issue when using Flood Fill 4 algorithm?使用 Flood Fill 4 算法时如何克服“细边框”问题?
【发布时间】:2013-04-03 23:22:43
【问题描述】:

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

洪水填充算法在“厚边界”区域(即直角三角形)内表现出色。但是,该算法在其他四个区域内不起作用,因为边界很薄,即发生泄漏。除了让其他寄宿生变厚,还有什么方法可以用吗?

这是完整的代码,它只是一个类:

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

【问题讨论】:

  • @Lee Meador 我已插入完整代码。

标签: java flood-fill


【解决方案1】:

您的if 需要一些工作,并且除了颜色之外,您的递归没有结束条件。

1

函数boundaryFill4 需要寻找x 和y 是小(图片的顶部或左侧边缘)还是大(底部或顶部边缘)。它看起来像这样:

if (x < 0 || x > 200 || y < 0 || y > 200) {
    return;
}

2

如果您仔细观察图像,您会发现边界线的边缘(尤其是细时)使用褪色像素来防止线条看起来过于锯齿。这是一种平滑技术。

一个调试技巧是在boundaryFill4 函数的顶部添加一个短时间延迟,以便您可以看到正在发生的过程。它应该会向您显示填充物正在逃逸的位置,您可以查看被炸毁的位置以获得更多线索。

测试当前寻找一个像素中的 RED 多于 50 级但与填充颜色不同的 RED。

中心的白色可能具有全部三个 RGB 级别。

边框具有所有三种 RGB 颜色的像素看似接近 0,但平滑技术使其在某些像素中放置更高的 RGB 值以隐藏锯齿。一定要检查边框薄时实际上是什么颜色。也许线条的中心像素比你想象的要亮。

填充颜色是一种深灰色。

  • 代码将找到具有“RED 50 以上”规则的白色。
  • 代码将避免使用“not RED == fill”规则重做已填充的代码
  • 它在平滑边框上的作用尚不明确。我的猜测是,有一个地方边界的较亮部分比 50 亮(在 RED 中)

这里有一些想法:

  1. 在与填充颜色进行比较时,更改规则以查看所有三种颜色,而不仅仅是红色。 (红色==填充,绿色==填充和蓝色==填充)这可能没有帮助。
  2. 也许您可以将起始点的颜色传入并使用它进行比较,而不是仅仅填充所有比 50 亮的颜色。要么寻找精确的颜色匹配,要么寻找一个足够接近的匹配,其中点在 10 以内传入的原始颜色。
  3. 如果这不起作用,请使用延迟查看它逃脱的地方的独特之处。

【讨论】:

  • 很抱歉造成混乱。我的 .jpg 文件由几个部分组成:abcteach.com/free/p/polygon0303rgb.jpg 这是一个黑白多边形。问题不在于像素从画布中泄漏...问题在于这些像素泄漏到相邻部分。我可以加厚部分的边界,这解决了问题……但它看起来很讨厌,即不那么整洁
  • 该图像有粗边框还是细边框?我可以看到一个带有其他宽度边框的吗?
  • 链接是:dl.dropboxusercontent.com/u/41007907/myIm.png我改造了一段(加厚了boearder),它在那里工作。但是,该算法不适用于其他四个区域
  • 我在上面自己的答案中插入了图像。请看一下。
  • 您可以编辑您的原始问题以添加该图片和您的文字。这将是这里的正常方式。我有另一个问题。您能否发布代码,当它在一个特定像素上时,决定将哪些相邻像素添加到相邻像素列表(或堆栈)中以进行下一步操作?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-16
  • 1970-01-01
  • 2021-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多