2D坐标系与3D坐标系的相互转换--python实现

并不是做关于SLAM方向的,但由于某些任务涉及到,故作此笔记~

相机内参矩阵:
不同的的深度摄像头具有不同的特征参数,在计算机视觉里,将这组参数设置为相机的内参矩阵C:
[ f x 0 c x 0 f y c y 0 0 1 ] \begin{bmatrix} f_x& 0 &c_x \\\\ 0 & f_y & c_y \\\\ 0 & 0 & 1 \end{bmatrix} fx000fy0cxcy1

fx,fy指相机在x轴和y轴上的焦距,cx,cy是相机的光圈中心,这组参数是摄像头生产制作之后就固定的。

世界坐标系: 用户定义的三维世界坐标系,以某个点为远点,为描述目标物在真实世界里的位置而被引入

相机坐标系: 以相机为原点建立的坐标系,为了从相机的角度描述物体的位置而定义,作为沟通世界坐标系和图像/像素坐标系的中间一环。

学习自: 三维坐标变换——旋转矩阵与旋转向量

旋转矩阵:

使用矩阵来表示一个旋转关系有两个缺点: 1)通过旋转矩阵不能直观地看出旋转的方向和角度 2)另一方面:旋转变换有3个自由度,旋转矩阵中的元素不是相互独立的。

旋转向量:
设旋转向量的单位向量为r,模为θ。三维点(或者说三维向量)p在旋转向量 r 的作用下变换至 p′,则:
p ′ = cos ⁡ θ ⋅ p + ( 1 − cos ⁡ θ ) ( p ⋅ r ) r + sin ⁡ θ ⋅ r × p'=\cos\theta\cdot p+(1-\cos\theta)(p\cdot r)r+\sin\theta\cdot r \times p=cosθp+(1cosθ)(pr)r+sinθr× p

学习自:计算机视觉:相机成像原理:世界坐标系、相机坐标系、图像坐标系、像素坐标系之间的转换

从世界坐标系到相机坐标系:

相机坐标系与图像坐标系:

图像坐标系与像素坐标系:

像素坐标系和图像坐标系都在成像平面,只是各自的原点和度量单位不大一样,图像坐标系的原点为相机光轴与成像平面的交点。图像坐标系的单位是mm,属于物理单位,而像素坐标系的单位是pixel

像素坐标系与世界坐标系:

convert2Dto3D

通过上面的公式,将像素坐标系的点映射到世界坐标系上,由于二维坐标映射到三维坐标会多了一个深度信息,因此二维点映射到三维坐标系,得到的是一条射线。虽然通过下面的代码得到的确实是一个三维的坐标点,但是其实是不确定的,与光点连线上(射线)所有的点都满足条件

convert3Dto2D

将3D平面的box转成2D平面的box,通过cv.projectPoint(三维平面下的8个点,旋转矩阵, 平移向量, 相机内参, 0)可以得到3D平面下的8个点映射到2维平面下8个点的坐标

代码


# 此函数只是外部定义而已,大家可自行定义
camera_matrix, rvec, tvec = camera_params()

print("相机内参:", camera_matrix)

print("平移向量:", tvec)

print("旋转矩阵:", rvec)

# (R T, 0 1)矩阵
Trans = np.hstack((rvec, [[tvec[0]], [tvec[1]], [tvec[2]]]))

# 相机内参和相机外参 矩阵相乘
temp = np.dot(camera_matrix, Trans)

Pp = np.linalg.pinv(temp)

# 点(u, v, 1) 对应代码里的 [605,341,1]
p1 = np.array([605, 341, 1], np.float)

print("像素坐标系的点:", p1)


X = np.dot(Pp, p1)

print("X:", X)

# 与Zc相除 得到世界坐标系的某一个点
X1 = np.array(X[:3], np.float)/X[3]

print("X1:", X1)


## 3D 转成 2D
from utils import *
import numpy as np
import cv2

## 2D 转成 3D

# 此函数只是外部定义而已,大家可自行定义
camera_matrix, rvec, tvec = camera_params()

print("相机内参:", camera_matrix)

print("平移向量:", tvec)

print("旋转矩阵:", rvec)

# (R T, 0 1)矩阵
Trans = np.hstack((rvec, [[tvec[0]], [tvec[1]], [tvec[2]]]))

# 相机内参和相机外参 矩阵相乘
temp = np.dot(camera_matrix, Trans)

Pp = np.linalg.pinv(temp)

# 点(u, v, 1) 对应代码里的 [605,341,1]
p1 = np.array([605, 341, 1], np.float)

print("像素坐标系的点:", p1)


X = np.dot(Pp, p1)

print("X:", X)

# 与Zc相除 得到世界坐标系的某一个点
X1 = np.array(X[:3], np.float)/X[3]

print("X1:", X1)


## 3D 转成 2D
## cube为世界坐标系的8个点的三维坐标
cube = np.float64([[-3.102,-1.58400011, 9.29399872],[-3.102, -0.08400005, 9.29399872]
 ,[-1.27200007,-0.08400005 , 9.29399872]
 ,[-1.27200007, -1.58400011  ,9.29399872]
 ,[-3.102   ,   -1.58400011 ,13.8939991 ]
 ,[-3.102   ,   -0.08400005, 13.8939991 ]
 ,[-1.27200007 ,-0.08400005, 13.8939991 ]
 ,[-1.27200007, -1.58400011 ,13.8939991 ]])
result, _ = cv2.projectPoints(cube, rvec, tvec, camera_matrix, 0)
print("3D to 2D 的 8个点的坐标:", result)

  • 18
    点赞
  • 232
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
要在Python中绘制坐标系,你可以使用Matplotlib库。下面是一种绘制2D坐标系的方法: ```python import matplotlib.pyplot as plt # 创建数据 x = [1, 2, 3, 4, 5] y = [2, 4, 6, 8, 10] # 绘制坐标系 plt.plot(x, y) # 设置坐标轴标签 plt.xlabel('X轴') plt.ylabel('Y轴') # 显示图形 plt.show() ``` 这段代码会创建一个简单的2D坐标系,其中x轴的数据为[1, 2, 3, 4, 5],y轴的数据为[2, 4, 6, 8, 10]。通过`plt.plot(x, y)`可以绘制出坐标系。使用`plt.xlabel('X轴')`和`plt.ylabel('Y轴')`可以设置x轴和y轴的标签。最后,通过`plt.show()`可以显示出图形。 如果你想绘制3D坐标系,你可以使用Matplotlib的mplot3d模块。下面是绘制3D坐标系的代码: ```python import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D # 创建数据 x = np.array([1, 2, 3, 4, 5]) y = np.array([2, 4, 6, 8, 10]) z = np.array([3, 6, 9, 12, 15]) # 创建3D坐标系 fig = plt.figure() ax = fig.add_subplot(111, projection='3d') # 绘制3D曲线 ax.plot(x, y, z) # 设置坐标轴标签 ax.set_xlabel('X轴') ax.set_ylabel('Y轴') ax.set_zlabel('Z轴') # 显示图形 plt.show() ``` 这段代码会创建一个简单的3D坐标系,其中x轴的数据为[1, 2, 3, 4, 5],y轴的数据为[2, 4, 6, 8, 10],z轴的数据为[3, 6, 9, 12, 15]。通过`ax.plot(x, y, z)`可以绘制出3D曲线。同样,使用`ax.set_xlabel('X轴')`、`ax.set_ylabel('Y轴')`和`ax.set_zlabel('Z轴')`可以设置x轴、y轴和z轴的标签。最后,通过`plt.show()`可以显示出图形。 以上是绘制2D和3D坐标系的简单示例。你可以根据自己的需求调整数据和绘图设置来创建更复杂的坐标系

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值