查找形状上的角/边(可以定义该形状的最小顶点)

时间:2018-10-22 21:21:51

标签: c# image-processing bresenham douglas-peucker

我正在尝试获得以下形状的角:

enter image description here

我指的是每个角落(红色的点):

enter image description here

可以定义此形状的最小点数。

我已经实现了以下内容:

    public Shape Optimize()
    {
        // If the vertices are null or empty this can't be executed
        if (vertices.IsNullOrEmpty())
            return this; // In this case, return the same instance.

        if (!edges.IsNullOrEmpty())
            edges = null; //Reset edges, because a recalculation was requested

        // The corners available on each iteration
        var corners = new Point[] { Point.upperLeft, Point.upperRight, Point.downLeft, Point.downRight };

        //The idea is to know if any of the following or previous vertice is inside of the the array from upside, if it is true then we can add it.

        Point[] vs = vertices.ToArray();

        for (int i = 0; i < vertices.Count - 1; ++i)
        {
            Point backPos = i > 0 ? vs[i - 1] : vs[vertices.Count - 1],
                  curPos = vs[i], //Punto actual
                  nextPos = i < vertices.Count - 1 ? vs[i + 1] : vs[0];

            // We get the difference point between the actual point and the back & next point
            Point backDiff = backPos - curPos,
                  nextDiff = nextPos - curPos,
                  totalDiff = nextPos - backPos;

            if (corners.Contains(backDiff) || corners.Contains(nextDiff) || corners.Contains(totalDiff))
                AddEdge(curPos, center); // If any of the two points are defined in the corners of the point of before or after it means that the actual vertice is a edge/corner
        }

        return this;
    }

这可以处理矩形形状,但是旋转的形状非常锋利,因此此代码无法正常工作:

enter image description here

  • 蓝色像素(在此照片及以下照片中)是通过vertices方法处理的Optimize变量。
  • 绿色像素是检测到的角/边缘(在两张照片上)。

但是形状的清晰度只能定义侧面的倾斜度,那么该怎么做才能改善呢?

此外,我已经测试过Accord.NET BaseCornersDetector inherited classes,但是使用HarrisCornersDetector可获得最佳结果,但是:

enter image description here

许多边缘/角是不必要的,它们不在需要的位置(请参阅第一张照片)。

1 个答案:

答案 0 :(得分:2)

好吧,经过数小时的研究,我发现了一个名为Simplify.NET的库,该库在内部运行Ramer–Douglas–Peucker algorithm

另外,您可能对Bresenham algorithm感兴趣,使用此算法,您可以draw a line using two Points

使用此算法,您可以检查公差是否过高,比较实际点和该算法输出的点并制作某种相似度百分比计算器。

最后,有趣的是提到Concave HullConvex Hull算法。

所有这些都与Unity3D有关。

我的输出:

enter image description here

enter image description here

还有my implementation

非常重要的一点是,必须对点进行排序以迫使它们连接起来。如果您在第二张照片上看到的形状是凹形的,则可能需要对形状的壁进行迭代。

您可以看到实现here的示例。感谢@ Bunny83。