【问题标题】:How to check if four points form a rectangle如何检查四个点是否形成一个矩形
【发布时间】:2012-08-22 21:50:27
【问题描述】:

我正在开发一个形状识别应用程序。此时一组点 (x,y) 由角检测器确定(红点,img.2.)。其中四个点(在红色框中,img.2.)是一个矩形的顶点(有时是一个有点变形的矩形)。找到它们的最佳方式是什么?

以下是输入图像的示例:

角点检测后是这样的:

【问题讨论】:

    标签: matlab image-processing shape-recognition


    【解决方案1】:

    这不是对您问题的回答 - 这只是建议。

    在我看来,角检测器是检测矩形的不好方法 - 正如 ma​​thematician1975 建议的那样,计算所有点距离需要很长时间。在这种情况下,您必须使用另一种技术:

    1. 那个印章是紫罗兰色的,所以首先应该做的是颜色分割。
    2. 完成步骤 1 后,您可以使用Houhg transform 检测二值图像上的线条。或者查找图像中的所有轮廓。
    3. 最后一步是检测矩形。

    更新:

    这是另一种也适用于灰色图像的解决方案。

    1. 做一个阈值将图像转换为 1bit(我使用 200 从 255 作为阈值)。
    2. 在新图像中查找面积大于某个常数的所有轮廓(我取了 1000)。
    3. 找到每个轮廓的边界矩形并进行检查:

    ContourArea / BoundingReactangleArea > 常量

    我将此constant 视为0.9

    这个算法给了我下一个结果:

    这是 OpenCV 代码:

    Mat src = imread("input.jpg"), gray, result;
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    
    result = Mat(src.size(), CV_8UC1);
    
    cvtColor(src, src, CV_BGR2GRAY);
    threshold(src, gray, 200, 255, THRESH_BINARY_INV);
    findContours(gray, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
    
    result = Scalar::all(0);
    for (size_t i=0; i<contours.size(); i++)
    {
        Rect rect = boundingRect(contours[i]);
        if (rect.area() > 1000)
        {
            double area = contourArea(contours[i]);
            if (area/rect.area() > 0.9)
            {
                drawContours(result, contours, i, Scalar(255), -1);
            }
        }
    }
    

    【讨论】:

    • 是的,正如您指出的那样,即使对于 small 输入图像,计算所有距离也会消耗大量时间。我已经检查了该解决方案。颜色分割对灰度图像没有用(示例有点令人困惑,抱歉),但我将它用于 RGB 图像。至于霍夫变换,我做了一些测试,效果很好,但检测到的线相互交叉,如下所示:hough.
    • 这在大多数情况下都很好用,所以我将其标记为答案。但是在某些情况下,它会失败,因为没有封闭区域。形态学运算在那时派上用场,但几乎在每种情况下,它们都需要不同的参数,这使得它们不是那么有用。任何想法如何解决这个问题?以下是这种情况的示例:click
    • @HighPerformanceMark 你可以使用minAreaRect
    • 确实如此,但这不是您的解决方案所做的。
    • @sowizz 将阈值更改为 210 怎么样?或者阈值在不同情况下也可以不同?
    【解决方案2】:

    计算每对 4 个不同点之间的 6 个长度。如果有超过 3 个不同的值,则在这 6 个长度的集合中,您没有矩形(2 个相等的边长加上相等的对角线长度)

    【讨论】:

    • 很好的解决方案,但在这个确切的问题中并没有真正有用。即使有 100 个点,计算所有距离也需要很长时间,而我通常会得到 2500 左右。
    • 等一下。你说你有四个点,而不是 2500。这个答案告诉你四个点是否形成一个矩形,并且似乎是该任务的有效解决方案。如果您的问题与您描述的不一样,那么您需要更具体一些。
    • 对,不过也说了这四个点不是唯一的,我要先找到合适的点。
    • @sowizz 我明白了 - 也许您可以稍微澄清一下这个问题,因为问题标题本身要求一种从 4 个点检测矩形的方法,而不是从任意数字中的 4 个。
    • 您可以稍微降低复杂性。首先,您可以只考虑 3 个点 - 这需要是一个直角三角形(也许使用毕达哥拉斯)。第二点是第四点,在很多情况下,只计算一个距离就可以排除它。
    【解决方案3】:

    您是否知道,通过目视检查点云,您已经可以区分多个矩形?换句话说,如果您不进行某种预选例程,您可能会发现很多矩形......

    无论如何,除了@mathematician1975 已经给出的方法之外,您还可以检查边是否(或多或少)平行。

    让我们调用@mathematician1975 的方法method 1 和并行检查method 2。 然后:

    %# method 1: 
    n1 = |u1-u2|    %#  3 sub., 3 mult, 2 add. per distance
    n2 = |u3-u2|    %#  total of 6 distances to compute.
    n3 = |u4-u3|    %#  then max 5+4+3+2+1 = 15 comp. to find unique distances
    n4 = |u1-u4|    
    n5 = |u4-u2|    %#  Total:
    n6 = |u3-u1|    %#  12 sub., 18 mult., 12 add, 15 comp
    
    
    
    %# method 2:
    w1 = u1-u2       %#  3 subtractions per vector
    w2 = u3-u2       %#  total of 4 vectors to compute 
    w3 = u3-u2
    w4 = u1-u4                
                            %#  12 sub.
    abs(w1-w3) == [0 0 0]   %#  3 sub., 3 comp., 1 sign.
    abs(w2-w4) == [0 0 0]   %#  3 sub., 3 comp., 1 sign.
    
                            %# Total: 18 sub., 6 comp. 2 sign.
    

    请注意,这些都是最坏的情况;通过一些簿记,您可以大大降低两者的成本。

    还要注意method 2 需要事先知道顶点的顺序是正确的。如果不是这样,成本会增加 4 倍,比method 1. 还要多。

    请问您是如何计算距离的?

    【讨论】:

    • 是的,我知道有这么多点会形成很多矩形,但我不确定在这个阶段我能做些什么(稍后我会计算一些统计数据将允许我只选择合适的矩形)。两点之间的距离计算为欧几里得距离:distance = sqrt( (x2-x1)^2 + (y2-y1)^2 );,我不确定它是否是 2500x4,因为您必须选择一个点,然后选择另一个 3,计算距离,然后对于同一个拳头点,您选择另一个 3超过 2500x4 组合的点(不同于以前的点)。
    • @sowizz 试试norm——应该会快很多。或者,如果您愿意,只需省略平方根——比较距离的平方或距离并不重要。或者,使用城市街区距离:abs(x2-x1) + abs(y2-y1)。这将给出一个非常粗略但更快的距离近似值,如果是矩形,它也必须相等。
    【解决方案4】:

    考虑你应该有号码8,但你有号码7,那么你将添加号码1(称为增量或纠错)来更正它。

    以类似的方式有一个delta矩形坐标来校正矩形。检查点(坐标)是否在 delta 矩形内。

    矩形坐标如下:

    x+delta,y+delta
    x-delta,y+delta
    x+delta,y-delta
    x-delta,y-delta
    

    让我知道这是否适合您或者您是否找到了更好的解决方案

    【讨论】:

      猜你喜欢
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-12
      • 1970-01-01
      相关资源
      最近更新 更多