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

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

我已经和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的预测会发生巨大的变化。
为了清楚起见,我添加了第二个代码块的坐标系的说明。


lvmkulzt

lvmkulzt1#

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

相关问题