了解OpenCV项目点:参考点和原点

nfs0ujit  于 2023-11-22  发布在  其他
关注(0)|答案(1)|浏览(247)

我已经和projectPoints斗争了好几天,却不理解这个函数的基本参考点。我发现很难找到所有输入的单词坐标和参考点。
这里有一个小例子。

  1. import numpy as np
  2. import cv2 as cv
  3. camera_matrix = np.array([
  4. [1062.39, 0., 943.93],
  5. [0., 1062.66, 560.88],
  6. [0., 0., 1.]
  7. ])
  8. points_3d = xyz_to_np_point(10, 0, 0)
  9. rvec = np.zeros((3, 1), np.float32)
  10. tvec = np.zeros((3, 1), np.float32)
  11. dist_coeffs = np.zeros((5, 1), np.float32)
  12. points_2d, _ = cv.projectPoints(points_3d,
  13. rvec, tvec,
  14. camera_matrix,
  15. dist_coeffs)
  16. 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我的图像与失真系数我的图像获得线性车道,并消除失真。
这里的代码我的问题与一些例子。

  1. import numpy as np
  2. import cv2 as cv
  3. from scipy.spatial.transform import Rotation as R
  4. from haversine import haversine, Unit
  5. def distance_between_coordinates(c1, c2):
  6. x = haversine(c1, (c1[0], c2[1]), Unit.METERS)
  7. if c1[1] > c2[1]:
  8. x = -x
  9. y = haversine(c1, (c2[0], c1[1]), Unit.METERS)
  10. if c1[1] > c2[1]:
  11. y = -y
  12. dist = haversine(c1, c2, Unit.METERS)
  13. return dist, x, y
  14. def rotvec_from_euler(orientation):
  15. r = R.from_euler('xyz', [orientation[0], orientation[1], orientation[2]], degrees=True)
  16. return r.as_rotvec()
  17. if __name__ == '__main__':
  18. camera_matrix = np.array([
  19. [1062.39, 0., 943.93],
  20. [0., 1062.66, 560.88],
  21. [0., 0., 1.]
  22. ])
  23. dist_coeffs = np.array([-0.33520254, 0.14872426, 0.00057997, -0.00053154, -0.03600385])
  24. camera_p = (37.4543785, 126.59113666666666)
  25. ship_p = (37.448312, 126.5781)
  26. # Other ships near to the previous one.
  27. # ship_p = (37.450693, 126.577617)
  28. # ship_p = (37.4509, 126.58565)
  29. # ship_p = (37.448635, 126.578202)
  30. camera_orientation = (206.6925, 0, 0) # Euler orientation.
  31. rvec = rotvec_from_euler(camera_orientation)
  32. tvec = np.zeros((3, 1), np.float32)
  33. _, x, y = distance_between_coordinates(camera_p, ship_p)
  34. points_3d = np.array([[[x, y, 0]]], np.float32)
  35. points_2d, _ = cv.projectPoints(points_3d,
  36. rvec, tvec,
  37. camera_matrix,
  38. dist_coeffs)
  39. print(points_2d)


我得到了一些更多的坐标,这些坐标是同一方向附近的船只,应该接近相机的中心。如果你尝试其他方法,projectPoints的预测会发生巨大的变化。
为了清楚起见,我添加了第二个代码块的坐标系的说明。


lvmkulzt

lvmkulzt1#

你应该首先检查OpenCV中坐标系的定义。
没有旋转,X+的方向是正确的(从相机)而不是向前。因此,试图投影点(10,0,0)是无稽之谈。
而且,如果使用正确的输入(0,0,10),输出将是(943.93, 560.88),而不是(0,0)

相关问题