有没有办法找到给定点的多边形?

时间:2019-06-18 09:33:11

标签: python math scikit-learn

我目前正在设法在最多15个给定点中找到矩形/多边形(下图)。

Given Points

我的目标是要在该点阵列中找到多边形,就像我在下图中标记的那样。多边形在现实世界中是矩形,但它们有些扭曲,这就是它们看起来像多边形或其他形状的原因。我必须找到最好的矩形/多边形。

我的想法是检查点之间的所有连接,但是总的来说要花很多时间。

有人知道如何解决这个问题吗?我在网上进行了研究,发现sklearn中的k-Nearest算法适用于python,但是如果这是解决问题的正确方法以及如何解决这一问题,我没有经验去做。也许我还需要一种方法来过滤掉一些离群值,以使算法更容易找到多边形的右角点。

下面的代码片段将给定的点字符串分成单独的数组,数组坐标仅包含点的x和y值。

非常感谢您的帮助。

Polygon in Given Points

import math
import numpy as np
import matplotlib.pyplot as plt
import time

from sklearn.neighbors import NearestNeighbors


millis = round(int(time.time())) / 1000

####input String
print("2D to 3D convert")

resultString = "0,487.50,399.46,176.84,99.99;1,485.93,423.43,-4.01,95.43;2,380.53,433.28,1.52,94.90;3,454.47,397.68,177.07,90.63;4,490.20,404.10,-6.17,89.90;5,623.56,430.52,-176.09,89.00;6,394.66,385.44,90.22,87.74;7,625.61,416.77,-177.95,87.02;8,597.21,591.66,-91.04,86.49;9,374.03,540.89,-11.20,85.77;10,600.51,552.91,178.29,85.52;11,605.29,530.78,-179.89,85.34;12,583.73,653.92,-82.39,84.42;13,483.56,449.58,-91.12,83.37;14,379.01,451.62,-6.21,81.51"


resultString = resultString.split(";")

resultStringSplitted = list()
coordinatesOnly = list()
for i in range(len(resultString)):
        resultStringSplitted .append(resultString[i].split(","))
        newList = ((float(resultString[i].split(",")[1]),float(resultString[i].split(",")[2])))
        coordinatesOnly.append(newList)
        for j in range(len(resultStringSplitted[i])):
                resultStringSplitted[i][j] = float(resultStringSplitted[i][j])

#Check if score is valid
validScoreList = list()
for i in range(len(resultStringSplitted)):
        if resultStringSplitted[i][len(resultStringSplitted[i])-1] != 0:
                validScoreList.append(resultStringSplitted[i])
resultStringSplitted = validScoreList

#Result String array contains all 2D results
# [Point Number, X Coordinate, Y Coordinate, Angle, Point Score]
for i in range(len(resultStringSplitted)):
        plt.scatter(resultStringSplitted[i][1],resultStringSplitted[i][2])

plt.show(block=True)

1 个答案:

答案 0 :(得分:0)

由于您提到最多可以有15个点,因此我建议检查4个点的所有可能组合,并保留所有与理想矩形足够接近的矩形。对于15点,它是“仅” 15*14*13*12=32760个可能的矩形。

import math
import itertools
import numpy as np

coordinatesOnly = ((0,0),(0,1),(1,0),(1,1),(2,0),(2,1),(1,3)) # Test data
rectangles = []

# Returns True if l0 and l1 are within 10% deviation
def isValid(l0, l1):
    if l0 == 0 or l1 == 0:
        return False
    return abs(max(l0,l1)/min(l0,l1) - 1) < 0.1

for p in itertools.combinations(np.array(coordinatesOnly),4):
    for r in itertools.permutations(p,4):
        l01 = np.linalg.norm(r[1]-r[0]) # Side
        l12 = np.linalg.norm(r[2]-r[1]) # Side
        l23 = np.linalg.norm(r[3]-r[2]) # Side
        l30 = np.linalg.norm(r[0]-r[3]) # Side
        l02 = np.linalg.norm(r[2]-r[0]) # Diagonal
        l13 = np.linalg.norm(r[2]-r[0]) # Diagonal
        areSidesEqual = isValid(l01,l23) and isValid(l12,l30)
        isDiag1Valid = isValid(math.sqrt(l01*l01+l30*l30),l13) # Pythagore
        isDiag2Valid = isValid(math.sqrt(l01*l01+l12*l12),l02) # Pythagore
        if areSidesEqual and isDiag1Valid and isDiag2Valid:
            rectangles.append(r)
            break

print(rectangles)

在计算机上以15个点运行需要大约1秒钟。这实际上取决于您对计算时间的要求,即实时,交互时间,即“我只是不想花几天时间等待答案”。