很抱歉,如果标题含糊不清。用简短易懂的方式表达我的问题是很难的。
所以,我正处于3D重建项目的中间。管道与标准管道或多或少相同
等等。唯一不同的部分是在步骤2,我使用线段检测器并跨帧跟踪它。
因此,如果我使用关键点检测器,给出两帧图像,我将得到两组关键点(每组对应于每一帧)。但至于我的情况,我有四组关键点(每一组对应于每一帧,因为一条线有一个起点和一个终点)。
为了计算基本矩阵,我需要连接每一帧的两组点。
一种方法是直接连接它:np.vstack([start_point, end_point])
。
另一种方式是:np.hstack([start_point, end_point]).reshape(-1, 2)
。手段,它是“交替”连接,即
[[start_point[0],
end_point[0],
start_point[1],
end_point[1],
...]]
两者最终会形成相同的形状。但公平地说,它们产生了截然不同的结果。根据我的观察,vstack
产生了更像'3D'的结果,而hstack
产生了更像'平面状'的重建结果。
问题是这是为什么?谁应该更好?
以下是提供此问题视图的示例代码:
import numpy as np
import cv2
np.random.seed(0)
def prepare_points(pts_frame1, pts_frame2):
# Prepare the four sets of points
(p1_f1, p2_f1) = pts_frame1
(p1_f2, p2_f2) = pts_frame2
v_stacked_f1f2 = (np.vstack([p1_f1, p2_f1]), np.vstack([p1_f2, p2_f2]))
h_stacked_f1f2 = (np.hstack([p1_f1, p2_f1]).reshape(-1, 2),
np.hstack([p1_f2, p2_f2]).reshape(-1, 2))
return (v_stacked_f1f2, h_stacked_f1f2)
pts_frame1 = np.random.random_sample((60, 2)).astype("float32")
pts_frame2 = np.random.random_sample((60, 2)).astype("float32")
# Emulate the two sets of points for each frame where
# the first set is the start point, while
# the second set is the end point of a line
pts_frame1 = (pts_frame1[::2], pts_frame1[1::2])
pts_frame2 = (pts_frame2[::2], pts_frame2[1::2])
(v_stacked_f1f2, h_stacked_f1f2) = prepare_points(pts_frame1, pts_frame2)
F_vstacked = cv2.findFundamentalMat(v_stacked_f1f2[0], v_stacked_f1f2[1],
cv2.FM_RANSAC, 3, 0.99)[0]
F_hstacked = cv2.findFundamentalMat(h_stacked_f1f2[0], h_stacked_f1f2[1],
cv2.FM_RANSAC, 3, 0.99)[0]
print("F_vstacked:\n", F_vstacked, "\n")
print("F_hstacked:\n", F_hstacked, "\n")
# F_vstacked:
# [[ 3.31788127 -2.24336615 -0.77866782]
# [ 0.83418839 -1.4066019 -0.92088302]
# [-2.75413748 2.27311637 1. ]]
# F_hstacked:
# [[ 7.70558741 25.29966782 -16.20835082]
# [-12.95357284 -0.54474384 14.95490469]
# [ 1.79050172 -10.40077071 1. ]]
答案 0 :(得分:0)
findFundamentalMat函数处理这样的点格式:2 * N,其中N是点数。所以我认为" F_hstacked"是正确的。 还有一件事我不清楚,为什么你只想使用线的终点来估计运动?这是准确的功能点吗?因为你无法确切地知道每个线的终点(像素)。