def buildOBB2d(points): """ 3D点群のOBB(Oriented Bounding Box)生成 max_p: 最大の頂点[xmax, ymax] min_p: 最小の頂点[xmin, ymin] l: OBBの対角線の長さ """ # 分散共分散行列Sを生成 S = np.cov(points, rowvar=0, bias=1) # 固有ベクトルを算出 w, svd_vector = LA.eig(S) # 固有値が小さい順に固有ベクトルを並べる svd_vector = svd_vector[np.argsort(w)] # 正規直交座標にする(=直行行列にする) # u = [sの単位ベクトル, tの単位ベクトル]になる u = np.asarray( [svd_vector[i] / np.linalg.norm(svd_vector[i]) for i in range(2)]) # 点群の各点と各固有ベクトルとの内積を取る # P V^T = [[p1*v1, p1*v2], ... ,[pN*v1, pN*v2]] inner_product = np.dot(points, u.T) # 各固有値の内積最大、最小を抽出(max_st_point = [s座標max, tmax]) max_st_point = np.amax(inner_product, axis=0) min_st_point = np.amin(inner_product, axis=0) # xyz座標に変換・・・単位ベクトル*座標 # max_xyz_point = [[xs, ys], [xt, yt]] max_xy_point = np.asarray([u[i] * max_st_point[i] for i in range(2)]) min_xy_point = np.asarray([u[i] * min_st_point[i] for i in range(2)]) ################################################################# # 図形作成処理 # s, t軸の単位ベクトル s, t = u # 法線: s, -s, t, -s # c: 法線と1点(smaxなど)との内積 lx1 = F2.line([s[0], s[1], np.dot(max_xy_point[0], s)]) lx2 = F2.line([-s[0], -s[1], -np.dot(min_xy_point[0], s)]) ly1 = F2.line([t[0], t[1], np.dot(max_xy_point[1], t)]) ly2 = F2.line([-t[0], -t[1], -np.dot(min_xy_point[1], t)]) OBB = F2.inter(lx1, F2.inter(lx2, F2.inter(ly1, ly2))) # 対角線の長さ算出 vert_max = min_xy_point[0] + min_xy_point[1] vert_min = max_xy_point[0] + max_xy_point[1] l = np.linalg.norm(vert_max - vert_min) # 面積算出 area = abs((max_st_point[0] - min_st_point[0]) * (max_st_point[1] - min_st_point[1])) return max_xy_point, min_xy_point, OBB, l, area
def ConstructAABBObject2d(max_p, min_p): # 図形作成処理 lx1 = F.line([1, 0, max_p[0]]) lx2 = F.line([-1, 0, -min_p[0]]) ly1 = F.line([0, 1, max_p[1]]) ly2 = F.line([0, -1, -min_p[1]]) AABB = F.inter(lx1, F.inter(lx2, F.inter(ly1, ly2))) return AABB
def LastIoU(goal, opti, AABB, path): # Figureの初期化 #fig = plt.figure(figsize=(12, 8)) # intersectionの面積 inter_fig = F.inter(goal, opti) inter_points = ContourPoints(inter_fig.f_rep, AABB=AABB, grid_step=1000) inter_points = np.array(inter_points, dtype=np.float32) inter_area = cv2.contourArea(cv2.convexHull(inter_points)) # unionの面積 union_fig = F.union(goal, opti) union_points = ContourPoints(union_fig.f_rep, AABB=AABB, grid_step=1000) union_points = np.array(union_points, dtype=np.float32) union_area = cv2.contourArea(cv2.convexHull(union_points)) X1, Y1 = Disassemble2d(inter_points) X2, Y2 = Disassemble2d(union_points) plt.plot(X1, Y1, marker=".", linestyle="None", color="red") plt.plot(X2, Y2, marker=".", linestyle="None", color="yellow") plt.savefig(path) plt.close() if len(goal.p) != len(opti.p): return -1 if inter_points.shape[0] <= 2: return -2 # print("{} / {}".format(inter_area, union_area)) return inter_area / union_area
def buildAABB2d(points): # (x,y)の最大と最小をとる max_p = np.amax(points, axis=0) min_p = np.amin(points, axis=0) # 図形作成処理 lx1 = F.line([1, 0, max_p[0]]) lx2 = F.line([-1, 0, -min_p[0]]) ly1 = F.line([0, 1, max_p[1]]) ly2 = F.line([0, -1, -min_p[1]]) AABB = F.inter(lx1, F.inter(lx2, F.inter(ly1, ly2))) # 面積算出 area = abs((max_p[0] - min_p[0]) * (max_p[1] - min_p[1])) return max_p, min_p, AABB, LA.norm(max_p - min_p), area