理解OpenCV项目要点:参考点和起源

问题描述 投票:0回答:1

我已经与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 acis 上的 rvec(为简单起见,相机平行于 XY 平面)。

我已经完成了相机校准并获得了我的相机矩阵和畸变系数。不知道如何测试相机矩阵,但我发现使用畸变系数对图像进行去畸变,我的图像可以获得线性车道并消除畸变。

这里是我的问题的代码和一些示例。

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)

我得到了更多坐标,这些坐标是在同一方向附近的船只,并且应该靠近相机的中心。如果您还尝试其他项目点的预测会发生巨大变化。

为了清楚起见,我添加了第二个代码块的坐标系的图示。

python opencv computer-vision camera-calibration camera-projection
1个回答
0
投票

首先应该检查一下OpenCV中坐标系的定义。

尝试投影点 (10,0,0) 是无稽之谈。
如果您使用正确的输入 (0,0,10),输出将为 (943.93, 560.88),而不是 (0,0)。

© www.soinside.com 2019 - 2024. All rights reserved.