【问题标题】:What's the best way to merge a set of rectangles in an image?在图像中合并一组矩形的最佳方法是什么?
【发布时间】:2012-08-30 07:48:55
【问题描述】:

这不是作业问题:)

我有一组散布在图像上的矩形。我想合并(创建一个联合)每组相交的矩形。如果一个矩形不与其相邻的矩形相交,则它保持不变。

问题是合并的矩形可以与以前没有考虑过的矩形相交;合并的矩形也可以与新合并的矩形相交。我想抓住那些案件。

因此,在我看来,它需要是迭代的(尝试每个矩形与集合中的每个其他矩形)和递归(再次尝试每个合并的矩形对集合,包括合并的矩形)。

我该怎么办?我正在使用 Java,但这更像是一个算法问题,而不是面向语言的问题。

谢谢!

编辑:添加相关代码以更好地说明我现在处理它的糟糕方式。

public static List<BinaryRegion> mergeRegions(List<BinaryRegion> regions)
{
    List<BinaryRegion> merged = new ArrayList<BinaryRegion>();
    geoModel = new GeometryFactory();

    Polygon polys[] = new Polygon[regions.size()];
    for (int i = 0; i < regions.size(); i++)
    {
        Polygon p = convertRectangleToPolygon(regions.get(i)
                .getBoundingBox());
        polys[i] = p;
    }

    System.out.println("Converted " + regions.size() + " polys");

    for (int i = 0; i < regions.size(); i++)
    {
        System.out.println("Sending in poly " + i);
        ArrayList<Polygon> result = mergePoly(polys[i], polys);
        System.out.println("After run, size=" + result.size());
    }
    return merged;

}

private static ArrayList<Polygon> mergePoly(Polygon p, Polygon[] polys)
{
    ArrayList<Polygon> merges = new ArrayList<Polygon>();

    for (int i = 0; i < polys.length; i++)
    {
        if (p.equals(polys[i]))
            System.out.println("found the exact match at " + i);
        else if (p.intersects(polys[i]))
        {
            System.out.println("Found intersection at " + i);
            System.out.println("Other poly is area "+polys[i].getArea());
            Polygon u = (Polygon) p.union(polys[i]);
            System.out.println("Merge size="+u.getArea());
            merges.add(u);
        }
        else
            merges.add(polys[i]);
    }
    return merges;
}

【问题讨论】:

  • 很明显这不是一个家庭作业问题:)
  • 你有多少个矩形?十?数百?百万?..
  • “创建联合”是指“创建一个覆盖两个相交矩形的矩形”,还是“创建一个看起来像两个相交矩形的几何联合的形状”?
  • 几千个矩形。创建一个覆盖两个相交矩形的矩形;基本上是两者的边界框。
  • 如果有一些 API 或包可以为我做这件事,我很乐意使用它。只是想完成它。

标签: algorithm image-processing geometry


【解决方案1】:

不完全确定这种嵌套迭代方法是否真的可行(尤其是因为我不知道您在调用mergePoly 后如何准确地处理合并区域)。与所有其他多边形相比,不是一次使用一个多边形,为什么不保留中间步骤并重新运行合并,直到没有更多的交叉点?大致如下:

private static ArrayList<Polygon> mergePoly(Polygon[] polys)
{
    List<Polygon> polygons = new ArrayList<Polygon>(Arrays.asList(polys));
    boolean foundIntersection = false;
    do
    {
        foundIntersection = false;
        for (int i = 0; i < polygons.size(); i++)
        {
            Polygon current = polygons.get(i);
            for (int j = i + 1; j < polygons.size(); j++)
            {
                if (current.intersects(polygons.get(j)))
                {
                    foundIntersection = true;
                    current = (Polygon)current.union(polygons.remove(j--));
                    System.out.println("Merge size="+u.getArea());
                }
            }
            polygons.set(i, current);
        }
    } while(foundIntersection);
    return polygons;
}

自从我使用 Java 以来已经有一段时间了,但逻辑是不言自明的。您执行多边形的两次迭代。外部迭代是您的“当前”多边形,您将合并所有内部多边形(随着您的进行,将它们从集合中删除)。在每次外部迭代之后,您只需使用(可能)合并的多边形设置该索引处的元素,然后移动到系列中的下一个多边形。您将继续这样做,直到您不再获得合并。请记住,这是一个非常幼稚的实现,您最好将其分成“两半”并合并这些较小的子集(想想合并排序)。

【讨论】:

    【解决方案2】:

    您可以使用扫描线算法找到矩形(example1example2)和union-find algorithm 的交点,从而有效地合并矩形集。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-17
      • 2020-09-13
      • 1970-01-01
      • 1970-01-01
      • 2010-09-18
      • 2011-03-01
      • 2019-04-18
      • 1970-01-01
      相关资源
      最近更新 更多