如何在不知道宽度或高度的情况下最好地对矩形的角进行排序?

时间:2014-03-13 17:03:00

标签: c++ opencv math

我有一个检测到的矩形的四个坐标。我想找出哪些是左上角,右上角,左下角和右下角。 我自己编写的方法(不必要地)很长并且实际上没有工作(可能是因为我在某处犯了错误)。无论哪种方式,我确信有一种更简单的方法,但我找不到使用谷歌的方法。所以任何帮助都会受到赞赏。

我的方法是找到最大y(最顶部),最小y(最底部),最大x(最右边),最小x(最左边)的角。然后,如果最左边.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];
            }

由于

4 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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

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 <= 24 <= 2 ^ 5)。但是,通过适当的重新编号,可以通过复制必要的最后两个比较(六个位置)来避免所有交换。

答案 3 :(得分:0)

我最近遇到了类似的问题,让我分享我的计划:

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