世界坐标系的正方体投影到二维视角【python实验】

为了更进一步理解相机内外参数对应的几何意义,特意设计了一个Python实验。希望对相关初学者有帮助。

实验思路:在世界坐标系上构建一个正方体,然后通过相机内外参数矩阵映射到屏幕坐标系上,观察映射结果。
实验素材:两个外参数矩阵(表示不同视角的相机),这两个相机共用一套内参数矩阵;一个空间坐标系的正方体。

实验代码:(代码为本人原创,引用须注明出处

import cv2
import numpy as np

extri1 = np.array(
        [[-9.9990e-01,  4.1922e-03, -1.3346e-02, -5.3798e-02],
        [-1.3989e-02, -2.9966e-01,  9.5394e-01,  3.8455e+00],
        [-4.6566e-10,  9.5404e-01,  2.9969e-01,  1.2081e+00],
        [0.0, 0.0, 0.0, 1.0]])
extri2 = np.array(
        [[0.4429636299610138, 0.31377720832824707, -0.8398374915122986, -3.385493516921997],
         [-0.8965396881103516, 0.1550314873456955, -0.41494810581207275, -1.6727094650268555],
         [0.0, 0.936754584312439, 0.3499869406223297, 1.4108426570892334],
         [0.0, 0.0, 0.0, 1.0]])

intrinsics = [[1111.0, 0.0, 400.0],
         [0.0, 1111.0, 400.0],
         [0.0, 0.0, 1.0]]

def world2screen(intri, extri, pw, to_int=False):
	R = extri[:3, :3] # rotation
	T = extri[:3, -1] # trans
	cam_p = np.dot(pw - T, R)
	if not to_int:
	    screen_p = np.array([-cam_p[0] * intri[0][0] / cam_p[2] + intri[0][2],
					  cam_p[1] * intri[1][1] / cam_p[2] + intri[1][2]])
	else:
	    screen_p = np.array([int(-cam_p[0] * intri[0][0] / cam_p[2] + intri[0][2] + .5),
					  int(cam_p[1] * intri[1][1] / cam_p[2] + intri[1][2] + .5)])
	return screen_p

vertex = [[-.5, -.5, -.5], [.5, -.5, -.5], [.5, .5, -.5], [-.5, .5, -.5], [-.5, .5, .5], [.5, .5, .5], [.5, -.5, .5], [-.5, -.5, .5]]
# cube in world

blank = np.zeros((800, 800, 3), np.uint8)

p_s = [world2screen(intrinsics, extri1, p_, to_int=True) for p_ in vertex]

for i in range(len(p_s)):
    p1 = p_s[i]
    p2 = p_s[i + 1] if i < len(p_s) - 1 else p_s[0]
    cv2.line(blank, p1, p2, (255, 255, 0), 1)
cv2.line(blank, p_s[3], p_s[0], (255, 255, 0), 1)
cv2.line(blank, p_s[4], p_s[7], (255, 255, 0), 1)
cv2.line(blank, p_s[1], p_s[6], (255, 255, 0), 1)
cv2.line(blank, p_s[2], p_s[5], (255, 255, 0), 1)
cv2.imwrite("extri1.png", blank)

blank = np.zeros((800, 800, 3), np.uint8)
p_s = [world2screen(intrinsics, extri2, p_, to_int=True) for p_ in vertex]

for i in range(len(p_s)):
    p1 = p_s[i]
    p2 = p_s[i + 1] if i < len(p_s) - 1 else p_s[0]
    cv2.line(blank, p1, p2, (255, 255, 0), 1)
cv2.line(blank, p_s[3], p_s[0], (255, 255, 0), 1)
cv2.line(blank, p_s[4], p_s[7], (255, 255, 0), 1)
cv2.line(blank, p_s[1], p_s[6], (255, 255, 0), 1)
cv2.line(blank, p_s[2], p_s[5], (255, 255, 0), 1)
cv2.imwrite("extri2.png", blank)

得到的结果为:
外参矩阵1:
世界坐标系的正方体投影到二维视角【python实验】_第1张图片
外参矩阵2:
世界坐标系的正方体投影到二维视角【python实验】_第2张图片
不同视角下的正方体的样子~

你可能感兴趣的:(三维重建,python,多视角,世界坐标系,相机位姿)