[英]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 變換矩陣,它是可逆的,並允許在您想要的兩個坐標系之間進行雙向變換。
如果你知道三個旋轉a
, b
和g
,分別關於x
, y
, z
,使用右手定則。 x0
、 y0
、 z0
是兩個坐標系原點之間的平移。
變換矩陣定義為:
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.