我已经和projectPoints斗争了好几天,却不理解这个函数的基本参考点。我发现很难找到所有输入的单词坐标和参考点。
这里有一个小例子。
import numpy as np
import cv2 as cv
camera_matrix = np.array([
[1062.39, 0., 943.93],
[0., 1062.66, 560.88],
[0., 0., 1.]
])
points_3d = xyz_to_np_point(10, 0, 0)
rvec = np.zeros((3, 1), np.float32)
tvec = np.zeros((3, 1), np.float32)
dist_coeffs = np.zeros((5, 1), np.float32)
points_2d, _ = cv.projectPoints(points_3d,
rvec, tvec,
camera_matrix,
dist_coeffs)
print(points_2d)
字符串
相机没有旋转,因此rvec=(0,0,0),我们将相机位置作为我们世界的原点,使tvec=(0,0,0)。我们想要计算3D到2D的对象然后位于相机前面的10个单位。
这里有一个例子:
的数据
代码的输出是(11567.83 560.88),而不是我期望的(0,0)。
一个更长的解释。我试图在我的图像中投影船只的位置。我有我的相机和船只的GPS位置。我通过在X轴上取距离(东方的X点)和在Y轴上取距离(北方的Y点)将GPS坐标转换为平面。由于船只被分配在海平面上,我将投影的3D点取为(X,Y,0)
对于相机的外部参数,我假设相机再次是参考世界,tvec仅考虑相机在海平面上的高度(tvec =(0,0,4))。作为旋转,我有一个绝对IMU,所以我可以计算X轴上的rvec(为了简单起见,相机平行于XY平面)。
我做了一个相机校准,并获得了我的相机矩阵和我的失真系数。不知道如何测试相机矩阵,但我看到,undistorting我的图像与失真系数我的图像获得线性车道,并消除失真。
这里的代码我的问题与一些例子。
import numpy as np
import cv2 as cv
from scipy.spatial.transform import Rotation as R
from haversine import haversine, Unit
def distance_between_coordinates(c1, c2):
x = haversine(c1, (c1[0], c2[1]), Unit.METERS)
if c1[1] > c2[1]:
x = -x
y = haversine(c1, (c2[0], c1[1]), Unit.METERS)
if c1[1] > c2[1]:
y = -y
dist = haversine(c1, c2, Unit.METERS)
return dist, x, y
def rotvec_from_euler(orientation):
r = R.from_euler('xyz', [orientation[0], orientation[1], orientation[2]], degrees=True)
return r.as_rotvec()
if __name__ == '__main__':
camera_matrix = np.array([
[1062.39, 0., 943.93],
[0., 1062.66, 560.88],
[0., 0., 1.]
])
dist_coeffs = np.array([-0.33520254, 0.14872426, 0.00057997, -0.00053154, -0.03600385])
camera_p = (37.4543785, 126.59113666666666)
ship_p = (37.448312, 126.5781)
# Other ships near to the previous one.
# ship_p = (37.450693, 126.577617)
# ship_p = (37.4509, 126.58565)
# ship_p = (37.448635, 126.578202)
camera_orientation = (206.6925, 0, 0) # Euler orientation.
rvec = rotvec_from_euler(camera_orientation)
tvec = np.zeros((3, 1), np.float32)
_, x, y = distance_between_coordinates(camera_p, ship_p)
points_3d = np.array([[[x, y, 0]]], np.float32)
points_2d, _ = cv.projectPoints(points_3d,
rvec, tvec,
camera_matrix,
dist_coeffs)
print(points_2d)
型
我得到了一些更多的坐标,这些坐标是同一方向附近的船只,应该接近相机的中心。如果你尝试其他方法,projectPoints的预测会发生巨大的变化。
为了清楚起见,我添加了第二个代码块的坐标系的说明。
的
1条答案
按热度按时间lvmkulzt1#
你应该首先检查OpenCV中坐标系的定义。
没有旋转,X+的方向是正确的(从相机)而不是向前。因此,试图投影点
(10,0,0)
是无稽之谈。而且,如果使用正确的输入
(0,0,10)
,输出将是(943.93, 560.88)
,而不是(0,0)
。