分组和排序框(坐标数组)

2024-05-23 14:40:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个多维numpy数组,其中包含四个点(坐标),表示一个长方体:

[startX,startY], [endX,startY], [endX,endY], [startX, endY]

例如:

[[[298.      404.     ]
  [354.      404.     ]
  [354.      430.     ]
  [298.      430.     ]]

 [[358.      404.     ]
  [416.      404.     ]
  [416.      428.     ]
  [358.      428.     ]]

 [[136.      406.     ]
  [190.      406.     ]
  [190.      428.     ]
  [136.      428.     ]]

 [[194.      406.     ]
  [246.      406.     ]
  [246.      430.     ]
  [194.      430.     ]]

 [[422.49792 403.28558]
  [505.2563  408.01465]
  [503.85352 432.56305]
  [421.09515 427.83398]]

 [[246.68146 410.22128]
  [291.68146 407.22128]
  [293.1947  429.92038]
  [248.1947  432.92038]]

 [[234.      436.     ]
  [296.      436.     ]
  [296.      460.     ]
  [234.      460.     ]]

 [[298.      436.     ]
  [342.      436.     ]
  [342.      462.     ]
  [298.      462.     ]]

 [[343.37756 438.08197]
  [455.64294 434.57367]
  [456.55414 463.73267]
  [344.28876 467.24097]]

 [[186.      440.     ]
  [230.      440.     ]
  [230.      464.     ]
  [186.      464.     ]]]

因为每个框都代表一个单词在图像中的位置,所以我想按照它们的读取方式对这些框进行排序。从左上角开始,到右下角结束。 我在考虑按星号值对箱子进行排序,方法是:

box_group = box_group[np.argsort(box_group[:, 0, 1])]

这个很好用。现在,我必须将每个在高度上与另一个重叠的框组合成一行。我用以下方法对此进行检查:

def isOnSameLine(boxOne, boxTwo):
    boxOneStartY = boxOne[0,1]
    boxOneEndY = boxOne[2,1]
    boxTwoStartY = boxTwo[0,1]
    boxTwoEndY = boxTwo[2,1]
    if((boxTwoStartY < boxOneEndY and boxTwoStartY > boxOneStartY)
    or(boxTwoEndY < boxOneEndY and boxTwoEndY > boxOneStartY)):
        return True
    else:
        return False

将分组的框放在一行上,我可以根据它们的startX值对它们进行排序,应该这样做。但我不知道如何迭代所有的框,并在这样做时对它们进行分组/排序。有什么想法吗


Tags: and方法box排序groupstartxstartyendx
2条回答

听起来lexsort可能是您所需要的全部(可能与x/y相反):

startY = boxes[:, 0, 1]
startX = boxes[:, 0, 0]
order = np.lexsort([startY, startX])

这就行了

def isOnSameLine(boxOne, boxTwo):
    boxOneStartY = boxOne[0,1]
    boxOneEndY = boxOne[2,1]
    boxTwoStartY = boxTwo[0,1]
    boxTwoEndY = boxTwo[2,1]
    if((boxTwoStartY <= boxOneEndY and boxTwoStartY >= boxOneStartY)
    or(boxTwoEndY <= boxOneEndY and boxTwoEndY >= boxOneStartY)
    or(boxTwoEndY >= boxOneEndY and boxTwoStartY <= boxOneStartY)):
        return True
    else:
        return False

# list of indexes
temp = []
i = 0

# TODO: check if there is more than one box_group
while i < len(box_group):
    for j in range(i + 1, len(box_group)):
        if(isOnSameLine(box_group[i],box_group[j])):
            print(str(i) + " and " + str(j) + " on same line")
            if i not in temp:
                temp.append(i)
            if j not in temp:
                temp.append(j)
        else:
            print(str(i) + " and " + str(j) + " not on same line")
        # append temp with i if the current box (i) is not on the same line with any other box
        if len(temp) == 0:
            temp.append(i)

    # put boxes on same line into lined_box_group array
    lined_box_group = box_group[np.array(temp)]
    # sort boxes by startX value
    lined_box_group = lined_box_group[np.argsort(lined_box_group[:, 0, 0])]
    # copy sorted boxes on same line into sorted_box_group
    sorted_box_group[i:temp[-1]+1] = lined_box_group

    # skip to the index of the box that is not on the same line
    i = temp[-1] + 1
    # clear list of indexes
    temp = []

相关问题 更多 >