繁体   English   中英

3D矩阵透视变换

[英]3D matrix perspective transform

我正在使用阴影形状来生成使用安装在移动平台上的相机拍摄的图像的数字地形模型 (DTM)。 用 Python 编写的算法似乎工作得相当好,但是输出是倾斜的并且有点球形,所以我怀疑我需要从 DTM 中去除透视失真和桶形。

如果有人有兴趣尝试一下,可以在此处获取数据。

相机以 41 度的倾角安装,并具有以下相机和失真矩阵:

    cam_matrix = numpy.matrix([[246.00559,0.00000,169.87374],[0.00000,247.37317,132.21396],[0.00000,0.00000,1.00000]])
    distortion_matrix = numpy.matrix([0.04674, -0.11775, -0.00464, -0.00346, 0.00000])

如何应用透视变换并从此矩阵中去除桶形失真以获得平坦的 DTM?

我已经使用 OpenCV 尝试过这个,但它不起作用,因为 OpenCv 需要一个图像,并且转换只是移动像素而不是操纵它们的值。 我也研究了 Numpy 和 Scipy,但还没有得出结论或解决方案。 我对这些变换背后的理论有些熟悉,但主要是在 2D 版本上工作。

有任何想法吗?

您可以使用 4 x 4 变换矩阵,它是可逆的,并允许在您想要的两个坐标系之间进行双向变换。

如果你知道三个旋转abg ,分别关于xyz ,使用右手定则。 x0y0z0是两个坐标系原点之间的平移。

变换矩阵定义为:

T = np.array([[ cos(b)*cos(g), (sin(a)*sin(b)*cos(g) + cos(a)*sin(g)), (sin(a)*sin(g) - cos(a)*sin(b)*cos(g)), x0],
              [-cos(b)*sin(g), (cos(a)*cos(g) - sin(a)*sin(b)*sin(g)), (sin(a)*cos(g) + cos(a)*sin(b)*sin(g)), y0],
              [        sin(b), -sin(a)*cos(b), cos(a)*cos(b), z0]
              [ 0, 0, 0, 1])

为了有效地使用它,你应该把你的点放在一个二维数组中,比如:

orig = np.array([[x0, x1, ..., xn],
                 [y0, y1, ..., yn],
                 [z0, z1, ..., zn],
                 [ 1,  1, ...,  1]])

然后:

new = T.dot(orig)

会给你转换点。

Saullo GP Castro有一个很好的解释。 这是我在 Python 3.8 中使用的代码。 如果您使用 T = make_matrix(90,0,0,1,0,0) 行,您可以看到原始矩阵中 XYZ 位置的变化。

#!/usr/bin/env python3
import numpy as np
import math
'''If you know the three rotations a, b and g, about x, y, z respectively, using the 
right-hand rule.
The x0, y0, z0 are the translations between the origins of the two coordinate 
systems.'''
#https://stackoverflow.com/questions/22175385/3d-matrix-perspective-transform/22311973#22311973

def make_matrix(roll,pitch,heading,x0,y0,z0):
    a = math.radians(roll)
    b = math.radians(pitch)
    g = math.radians(heading)

    T = np.array([[ math.cos(b)*math.cos(g), (math.sin(a)*math.sin(b)*math.cos(g) + 
    math.cos(a)*math.sin(g)), (math.sin(a)*math.sin(g) - 
    math.cos(a)*math.sin(b)*math.cos(g)), x0],
    [-math.cos(b)*math.sin(g), (math.cos(a)*math.cos(g) - 
    math.sin(a)*math.sin(b)*math.sin(g)), (math.sin(a)*math.cos(g) + 
    math.cos(a)*math.sin(b)*math.sin(g)), y0],
    [        math.sin(b), -math.sin(a)*math.cos(b), math.cos(a)*math.cos(b), z0],
    [ 0, 0, 0, 1]])
    return T

def load_orig():
    orig = np.array([[0, 1, 0],
                [0, 0, 1],
                [1, 0, 0],
                [ 1,  1, 1]])
    return orig

if __name__ == '__main__':
    T = make_matrix(90,0,0,1,0,0)
    orig = load_orig()
    new = T.dot(orig)
    print(new)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM