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



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

我的方法是找到具有max y(most-top), min y(most-bottom), max x(most-right), min x(most-left)的角。然后如果最左边的。Y>最右边。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];
            }

谢谢

按左距排序。前两点是矩形的左边。把这两个点按高度排序。最高的是左上点,另一个是左下点。对右边的两个做同样的操作

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

  1. 计算矩形的圆心
  2. 使用你的矩形的中心作为你的角的新原点。
  3. 将角转换为极坐标
  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 <= 24 <= 2^5)。但是,通过在必要的地方复制最后两次比较(六个位置),并适当地重新编号,可以避免所有的交换。

您可以使用标准c++库,min_elementmax_element与自定义比较器。这是官方文件。

我在这里有一个简单的例子(它不是纯opencv抱歉,但移植是微不足道的)。

最新更新