【问题标题】:How to best sort the corners of a rectangle without knowing the width or height?如何在不知道宽度或高度的情况下最好地对矩形的角进行排序?
【发布时间】:2014-03-13 17:03:00
【问题描述】:

我有一个检测到的矩形的四个坐标。我想找出其中哪一个是左上角、右上角、左下角和右下角。 我自己编写的方法(不必要地)很长,实际上并没有奏效(可能是因为我在某处犯了错误)。无论哪种方式,我确信有一种更简单的方法,但我找不到使用谷歌的方法。因此,我们将不胜感激。

我的方法是用 max y(most-top), min y(most-bottom), max x(most-right), min x (most-left) 找到角点。然后如果 most-left.y > the most-right.y 那么左上点是最左,右上角是最上等。 这种方法正确吗?还有更简单的方法吗?

我的代码,对不起它的混乱和混乱...... squareX[0] 是第一个 x 坐标 squareY[0] 是第一个 y 坐标等。

编辑:原来我的方法很好,它只是 max() 没有做我认为的事情(从所有输入的数字中返回最大数字)。

            maxx = max(squareX[0], squareX[1], squareX[2], squareX[3]);
            maxy = max(squareY[0], squareY[1], squareY[2], squareY[3]);
            minx = min(squareX[0], squareX[1], squareX[2], squareX[3]);
            miny = min(squareY[0], squareY[1], squareY[2], squareY[3]);

            if (squareX[0] == maxx)
            {
                mx = 0;
            }
            if (squareX[1] == maxx)
            {
                mx = 1;
            }
            if (squareX[2] == maxx)
            {
                mx = 2;
            }
            if (squareX[3] == maxx)
            {
                mx =3;
            }

            if (squareX[0] == minx)
            {
                mix = 0;
            }
            if (squareX[1] == minx)
            {
                mix = 1;
            }
            if (squareX[2] == minx)
            {
                mix = 2;
            }
            if (squareX[3] == minx)
            {
                mix = 3;
            }

            if (squareY[0] == maxy)
            {
                my = 0;
            }
            if (squareY[1] == maxy)
            {
                my = 1;
            }
            if (squareY[2] == maxy)
            {
                my = 2;
            }
            if (squareY[3] == maxy)
            {
                my = 3;
            }

            if (squareY[0] == miny)
            {
                miy = 0;
            }
            if (squareY[1] == miny)
            {
                miy = 1;
            }
            if (squareY[2] == miny)
            {
                miy = 2;
            }
            if (squareY[3] == miny)
            {
                miy = 3;
            }

            if (squareY[mix] > squareY[mx])
            {
                Pt1.x = squareX[mix];
                Pt1.y = squareY[mix];
                Pt2.x = squareX[my];
                Pt2.y = squareY[my];
                Pt3.x = squareX[mx];
                Pt3.y = squareY[mx];
                Pt4.x = squareX[miy];
                Pt4.y = squareY[miy];
            }
            else
            {
                Pt1.x = squareX[my];
                Pt1.y = squareY[my];
                Pt2.x = squareX[mx];
                Pt2.y = squareY[mx];
                Pt3.x = squareX[miy];
                Pt3.y = squareY[miy];
                Pt4.x = squareX[mix];
                Pt4.y = squareY[mix];
            }

谢谢

【问题讨论】:

  • 矩形是否与轴平行?
  • 你的方法似乎是最简单的,所以不清楚你想简化什么。所以请添加您的代码。
  • 它可以在任何方向,但可能不平行于轴。
  • 首先,沿x方向的起点对矩形进行排序,然后沿y方向排序。您最终将对该组进行排序。
  • 如果矩形可以是正方形并且可以有任何方向,如果正方形正好位于尖端,您如何定义左上角?

标签: c++ opencv math


【解决方案1】:

按照点的距离对点进行排序。前两个点是矩形的左侧。按高度对这两个点进行排序。最高的是左上角,另一个是左下角。对右边的两个做同样的事情。

【讨论】:

  • 使用字典顺序(在 X 上比较,然后在 Y 上比较,以防出现平局)将一次性执行。
【解决方案2】:

您可以将标准 C++ 库 min_element 和 max_element 与自定义比较器一起使用。 Here是官方文档。

我有一个简单的例子here(抱歉,它不是纯opencv,但移植很简单)。

【讨论】:

    【解决方案3】:

    我最近遇到了类似的问题,分享一下我的方案:

    1. 计算矩形的中心。
    2. 使用矩形的中心作为角的新原点。
    3. 将角转换为极坐标。
    4. 按角对角进行排序。

    【讨论】:

      【解决方案4】:

      这是尝试使用尽可能少的比较:

      if X0 == X1:
        # P0 and P1 are on a vertical
        if X0 < X2:
          # P0 and P1 are on the left
        else:
          # P2 and P3 are on the left
          swap P0-P2
          swap P1-P3
      else:
        # P0 and P1 are on a diagonal
        if X0 < X1:
          # P0 is on the left
          if X0 < X2:
            # P0 and P3 are on the left
            swap P1-P3
          else:
            # P0 and P2 are on the left
            swap P1-P2
        else:
          # P1 is on the left
          if X1 < X2:
            # P1 and P3 are on the left
            swap P0-P3
          else:
            # P1 and P2 are on the left
            swap P0-P2
      

      在 X 上进行两三次比较后,您已经确定了左右角对(现在是 P0-P1 和 P2-P3)。

      if Y0 > Y1:
        # P1 is upper
        swap P0-P1
      
      if Y2 > Y3:
        # P3 is upper
        swap P2-P3
      

      在 Y 上再进行两次比较(向下增加),矩形为 0231,顺时针方向。

      您不能在少于 5 次比较中做到这一点,因为您需要覆盖 24 种排列 (2^4

      【讨论】:

        猜你喜欢
        • 2012-08-20
        • 1970-01-01
        • 2016-12-29
        • 1970-01-01
        • 1970-01-01
        • 2016-01-31
        • 2015-03-11
        • 2013-08-14
        • 2019-10-13
        相关资源
        最近更新 更多