- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试使用 OpenCV 来估计相机相对于另一个的一个姿势,使用 SIFT 特征跟踪、FLANN 匹配以及基本矩阵和基本矩阵的后续计算。分解基本矩阵后,我检查退化配置并获得“正确的”R 和 t。
问题是,他们似乎从来都不是对的。我包括几个图像对:
结果
结果
第二种情况下的平移向量似乎高估了 Y 方向的运动而低估了 X 方向的运动。在这两种情况下,转换为欧拉角的旋转矩阵都会给出错误的结果。许多其他数据集也会发生这种情况。我已经尝试在 RANSAC、LMEDS 等之间切换基本矩阵计算技术,现在我正在使用 RANSAC 进行计算,第二次计算仅使用 8 点法的内点。更改特征检测方法也无济于事。对极线似乎是适当的,基本矩阵满足x'.F.x = 0
我是否遗漏了一些根本性的错误?如果程序正确理解对极几何,可能会发生什么导致完全错误的姿势?我正在检查以确保点位于两个摄像头前面。任何想法/建议都会非常有帮助。谢谢!
编辑:尝试使用相同的技术,将两个不同的校准相机隔开;并计算基本矩阵为 K2'.F.K1,但平移和旋转仍然有很大差距。
Code供引用
import cv2
import numpy as np
from matplotlib import pyplot as plt
# K2 = np.float32([[1357.3, 0, 441.413], [0, 1355.9, 259.393], [0, 0, 1]]).reshape(3,3)
# K1 = np.float32([[1345.8, 0, 394.9141], [0, 1342.9, 291.6181], [0, 0, 1]]).reshape(3,3)
# K1_inv = np.linalg.inv(K1)
# K2_inv = np.linalg.inv(K2)
K = np.float32([3541.5, 0, 2088.8, 0, 3546.9, 1161.4, 0, 0, 1]).reshape(3,3)
K_inv = np.linalg.inv(K)
def in_front_of_both_cameras(first_points, second_points, rot, trans):
# check if the point correspondences are in front of both images
rot_inv = rot
for first, second in zip(first_points, second_points):
first_z = np.dot(rot[0, :] - second[0]*rot[2, :], trans) / np.dot(rot[0, :] - second[0]*rot[2, :], second)
first_3d_point = np.array([first[0] * first_z, second[0] * first_z, first_z])
second_3d_point = np.dot(rot.T, first_3d_point) - np.dot(rot.T, trans)
if first_3d_point[2] < 0 or second_3d_point[2] < 0:
return False
return True
def drawlines(img1,img2,lines,pts1,pts2):
''' img1 - image on which we draw the epilines for the points in img1
lines - corresponding epilines '''
pts1 = np.int32(pts1)
pts2 = np.int32(pts2)
r,c = img1.shape
img1 = cv2.cvtColor(img1,cv2.COLOR_GRAY2BGR)
img2 = cv2.cvtColor(img2,cv2.COLOR_GRAY2BGR)
for r,pt1,pt2 in zip(lines,pts1,pts2):
color = tuple(np.random.randint(0,255,3).tolist())
x0,y0 = map(int, [0, -r[2]/r[1] ])
x1,y1 = map(int, [c, -(r[2]+r[0]*c)/r[1] ])
cv2.line(img1, (x0,y0), (x1,y1), color,1)
cv2.circle(img1,tuple(pt1), 10, color, -1)
cv2.circle(img2,tuple(pt2), 10,color,-1)
return img1,img2
img1 = cv2.imread('C:\\Users\\Sai\\Desktop\\room1.jpg', 0)
img2 = cv2.imread('C:\\Users\\Sai\\Desktop\\room0.jpg', 0)
img1 = cv2.resize(img1, (0,0), fx=0.5, fy=0.5)
img2 = cv2.resize(img2, (0,0), fx=0.5, fy=0.5)
sift = cv2.SIFT()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1,None)
kp2, des2 = sift.detectAndCompute(img2,None)
# FLANN parameters
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks=50) # or pass empty dictionary
flann = cv2.FlannBasedMatcher(index_params,search_params)
matches = flann.knnMatch(des1,des2,k=2)
good = []
pts1 = []
pts2 = []
# ratio test as per Lowe's paper
for i,(m,n) in enumerate(matches):
if m.distance < 0.7*n.distance:
good.append(m)
pts2.append(kp2[m.trainIdx].pt)
pts1.append(kp1[m.queryIdx].pt)
pts2 = np.float32(pts2)
pts1 = np.float32(pts1)
F, mask = cv2.findFundamentalMat(pts1,pts2,cv2.FM_RANSAC)
# Selecting only the inliers
pts1 = pts1[mask.ravel()==1]
pts2 = pts2[mask.ravel()==1]
F, mask = cv2.findFundamentalMat(pts1,pts2,cv2.FM_8POINT)
print "Fundamental matrix is"
print
print F
pt1 = np.array([[pts1[0][0]], [pts1[0][1]], [1]])
pt2 = np.array([[pts2[0][0], pts2[0][1], 1]])
print "Fundamental matrix error check: %f"%np.dot(np.dot(pt2,F),pt1)
print " "
# drawing lines on left image
lines1 = cv2.computeCorrespondEpilines(pts2.reshape(-1,1,2), 2,F)
lines1 = lines1.reshape(-1,3)
img5,img6 = drawlines(img1,img2,lines1,pts1,pts2)
# drawing lines on right image
lines2 = cv2.computeCorrespondEpilines(pts1.reshape(-1,1,2), 1,F)
lines2 = lines2.reshape(-1,3)
img3,img4 = drawlines(img2,img1,lines2,pts2,pts1)
E = K.T.dot(F).dot(K)
print "The essential matrix is"
print E
print
U, S, Vt = np.linalg.svd(E)
W = np.array([0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]).reshape(3, 3)
first_inliers = []
second_inliers = []
for i in range(len(pts1)):
# normalize and homogenize the image coordinates
first_inliers.append(K_inv.dot([pts1[i][0], pts1[i][1], 1.0]))
second_inliers.append(K_inv.dot([pts2[i][0], pts2[i][1], 1.0]))
# Determine the correct choice of second camera matrix
# only in one of the four configurations will all the points be in front of both cameras
# First choice: R = U * Wt * Vt, T = +u_3 (See Hartley Zisserman 9.19)
R = U.dot(W).dot(Vt)
T = U[:, 2]
if not in_front_of_both_cameras(first_inliers, second_inliers, R, T):
# Second choice: R = U * W * Vt, T = -u_3
T = - U[:, 2]
if not in_front_of_both_cameras(first_inliers, second_inliers, R, T):
# Third choice: R = U * Wt * Vt, T = u_3
R = U.dot(W.T).dot(Vt)
T = U[:, 2]
if not in_front_of_both_cameras(first_inliers, second_inliers, R, T):
# Fourth choice: R = U * Wt * Vt, T = -u_3
T = - U[:, 2]
# Computing Euler angles
thetaX = np.arctan2(R[1][2], R[2][2])
c2 = np.sqrt((R[0][0]*R[0][0] + R[0][1]*R[0][1]))
thetaY = np.arctan2(-R[0][2], c2)
s1 = np.sin(thetaX)
c1 = np.cos(thetaX)
thetaZ = np.arctan2((s1*R[2][0] - c1*R[1][0]), (c1*R[1][1] - s1*R[2][1]))
print "Pitch: %f, Yaw: %f, Roll: %f"%(thetaX*180/3.1415, thetaY*180/3.1415, thetaZ*180/3.1415)
print "Rotation matrix:"
print R
print
print "Translation vector:"
print T
plt.subplot(121),plt.imshow(img5)
plt.subplot(122),plt.imshow(img3)
plt.show()
最佳答案
有很多因素会导致根据点对应关系对相机位姿的估计不准确。您必须考虑的一些因素:-
(*) 8 点法最小化代数误差 ( x'.F.x = 0)。通常最好找到一个能最小化有意义的几何误差的解决方案。例如,您可以在 RANSAC 实现中使用重新投影误差。
(*) 从8点求解基本矩阵的线性算法对噪声敏感。亚像素级精确点匹配、适当的数据归一化和精确的相机校准对于获得更好的结果都很重要。
(*) 特征点定位和匹配导致噪声点匹配,因此通过求解代数方程 x'Fx 得到的解应该真正用作初始估计,并且需要应用参数优化等进一步步骤优化解决方案。
(*) 一些双 View 相机配置可能会导致模糊的解决方案,因此需要进一步的方法(例如第三 View 消歧)以获得可靠的结果。
关于python - 对极几何姿态估计 : Epipolar lines look good but wrong pose,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31737688/
我正在使用react-pose使窗口内和窗口外的通知动画化。 “进入”过渡非常流畅,但是退出时 - 动画非常激进。 有人遇到过这个问题吗?我可以在任何地方上传视频屏幕截图来说明问题(除了 YouTub
我已经尝试了几天在我的游戏中创建 3D 骨骼动画。我正在将 Java 与 LWJGL 结合使用。 在尝试制作动画之前,我试图在程序中实现绑定(bind)姿势。我从 Blender 导出的 collad
我指的是 33 个 body 点和它们之间的连接线。我想更改它们的颜色,尤其是连接线的白色默认颜色。 这是我的代码,我已经为 mediapipe 创建了一个类模块,我可以在我的其他程序中导入和使用它
我指的是 33 个 body 点和它们之间的连接线。我想更改它们的颜色,尤其是连接线的白色默认颜色。 这是我的代码,我已经为 mediapipe 创建了一个类模块,我可以在我的其他程序中导入和使用它
来自文档 https://developers.google.com/ar/reference/java/arcore/reference/com/google/ar/core/Pose我看到 Pos
我正在尝试创建一个包含不同姿势的物体图像的数据集,其中每个图像都用相机姿势(或物体姿势)进行注释。 例如,如果我有一个世界坐标系,我将感兴趣的对象放在原点并将相机放在已知位置 (x,y,z) 并使其面
我关注了the documentation和 this blog post但我正在努力让任何事情发挥作用。 在本地,我收到以下错误:嘿,听着!找不到有效的 DOM 引用。如果您通过 posed(Com
我正在尝试为一个 ios 项目实现摆姿势。 场景: Defining class of controller at run time 我意识到poseAsClass或class_poseAs不适用于i
我正在尝试为一个 ios 项目实现摆姿势。 场景: Defining class of controller at run time 我意识到poseAsClass或class_poseAs不适用于i
我需要获取手机面向的方向和地平线之间的 Angular theta(见图)。 为此,我使用了 web-vr polyfill 库,它允许我访问 VRPose.orientation,即作为四元数的相机
我有一个服务器功能,可以从图像中检测和估计 aruco 标记的姿势。 使用函数 estimatePoseSingleMarkers 我找到了旋转和平移向量。我需要在带有 ARCore 的 Androi
所以我有一个小型 React 应用程序。尝试使用 React Pose 来制作页面转换动画。我遵循了与 one of the official demos with react-router-dom
我目前正在尝试从NERF模型重建网格,我注意到大多数NERF实现都提供了一个Python脚本,用于通过COLMAP从图像中提取相机姿势。我的理解是,这些脚本使用稀疏重建,或者至少使用COLMAP的特征
我在一个使用tflite Posenet在Flutter Framework的移动设备上运行的项目中。我们希望在测试中获得更高的精度得分,但是我们意识到Dart API文档https://pub.de
在 NDK 中使用此函数时: void ArPose_getMatrix( const ArSession *session, const ArPose *pose, floa
我正在尝试使用 OpenCV 来估计相机相对于另一个的一个姿势,使用 SIFT 特征跟踪、FLANN 匹配以及基本矩阵和基本矩阵的后续计算。分解基本矩阵后,我检查退化配置并获得“正确的”R 和 t。
我在使用 OpenCV 从 iPad 相机获取正确的相机姿势时遇到问题。 我正在使用定制的 2D 标记(基于 AruCo library)- 我想使用 OpenGL 在该标记上渲染 3D 立方体。 为
我想在像 Pinterest 这样的网站中实现图像/div 所使用或遵循的样式。或 Pose不管他们的个人决议是什么。我试过像这样将 div 并排放置 CSS: #mainCont
我有一个带有使用 React Pose 的动画的 React 应用程序 ( https://popmotion.io/pose/ )。 这工作正常,但是当我为组件编写集成测试(使用react-test
在谷歌上 Samples我可以获得有关从 ArAnchor 生成的 Pose 中获取 Matrix 的样本。或来自 ArPlane .但是当我试图从 ArCamera不起作用,我的结果是一个单位矩阵。
我是一名优秀的程序员,十分优秀!