[英]Fit fixed rectangle to set of points
只是解決方案的概述:
pnt2line
給出的pnt2line http://www.fundza.com/vectors/point2line/index.htmldistance[i]
指定為這四個距離中的最小值scipy.optimize.curve_fit
中使用此distance
數組來找到最適合的參數如果有異常值,RANSAC 可以成為你的好朋友。 要進行擬合,您需要從不同側面取三個點。 因此,只需選擇三個隨機點並假設其中兩個屬於一側,另一個屬於正交側。 找到姿勢參數沒什么大不了的。 您可以按照@VBB 的描述從距離 function 計算擬合誤差(對於每個點,到邊的距離最短)。
根據您的喜好,您可以一次使用相同的三個點,並進行任意的邊分配,或者嘗試不同的分配並保持最佳狀態。
對於內點的最終擬合,您可以使用一個技巧。
將每個內點分配給最近的一側;
將每一側的簇集中在其各自的質心上;
將每隔一邊的簇旋轉90°;
這會產生一個單一方向的單一集群; 執行普通線擬合以獲得該方向。
定義position P處的固定大小矩形R(P)與點Q之間的距離d(R(P), Q)為連接兩者的最短直線的長度。 這很容易定義為 function 案例推理。
現在只需使用某種形式的梯度下降來找到最佳 P*,使點集中 Q 的 d(R(P*), Q)^2 之和最小化。
我找不到它所以自己寫了一個代碼。 您可以使用最小二乘矩形來擬合它。
import torch
import numpy as np
import matplotlib.pyplot as plt
import cv2
import matplotlib.pyplot as plt
def plot_graph(X,Y, slopes,constants):
plt.plot(X,Y,"go")
def abline(slope, intercept):
"""Plot a line from slope and intercept"""
axes = plt.gca()
x_vals = np.array(axes.get_xlim())
y_vals = intercept + slope * x_vals
plt.plot(x_vals, y_vals, '--')
abline(float(slopes[0]),float(constants[0]))
abline(float(slopes[0]),float(constants[2]))
abline(float(slopes[1]),float(constants[1]))
abline(float(slopes[1]),float(constants[3]))
plt.show()
points = torch.tensor([[0,2],[2,0],[0.5,1.5],[1,1],[2,2],[3,3],[3,0.8],[2.5,3.5],[2,4],[3,1.5],[0,2.3],[1.5,3],[1,3]])
Y = points[:,1]
X = points[:,0]
learning_rate = 0.01
epochs = 10000
n = X.shape[0]
import cv2
import numpy as np
rect = cv2.minAreaRect(np.array(points))
m = np.tan(np.pi*rect[2]/180)
slope = torch.tensor([[m]],requires_grad=True)
box = cv2.boxPoints(rect)
c0 = box[0][1] - (m*box[0][0])
c1 = box[0][1] + (box[0][0]/m)
c2 = box[2][1] - (m* box[2][0])
c3 = box[2][1] + (box[2][0]/m)
constants = torch.tensor([[c0],[c1],[c2],[c3]],requires_grad=True)
# slope = torch.rand([1,1],requires_grad=True)
# constants = torch.rand([4,1],requires_grad=True)
for i in range(epochs):
slopes = torch.cat((slope,-1/slope) ,0)
num = abs(torch.cat((Y - slopes*X, Y - slopes*X), 0) - constants)
den = torch.cat((torch.sqrt(1 + slopes*slopes), torch.sqrt(1 + slopes*slopes)), 0)
distances = num/den
dists_min = torch.amin(distances,0).sum()/n
dists_min.backward()
if i % 1000 == 0:
print(i)
if i%1000==0:
plot_graph(X,Y, slopes,constants)
with torch.no_grad():
slope -= learning_rate * slope.grad
constants -= learning_rate *10* constants.grad
slope.grad.zero_()
constants.grad.zero_()
Github - https://github.com/PuneetMadan9/fitting_least_square_rectangle/blob/main/least_square_rectangle.py谷歌 Colab - https://colab.research.google.com/drive/1VyxJGLfKkzFuN-MF_38J-Y_Rqroll#bTJqroll#
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.