3d坐标变换为2d坐标,3d坐标转换成屏幕坐标
世界坐标系、相机坐标系、影像坐标系的转换(Python))。
相机内部参考和外部参考描述:quan.blog.csdn.net/article/details/102502213盘锦3359号
计算机视觉:相机成像原理:世界坐标系、相机坐标系、图像坐标系、像素坐标系之间的转换33603359 blog.csdn.net/Chen旅游/文章/详情/5358096
1.世界坐标-相机坐标
2.摄像机坐标系-图像坐标系
此时投影点p的单位仍然是mm,需要进一步变换到像素坐标系,而不是像素。
3.图像坐标系和像素坐标系
像素坐标系和图像坐标系都位于成像平面上,但各自的原点和测量单位不同。图像坐标系的原点是相机光轴与成像平面的交点,通常称为成像平面的中点或主点。说明图像坐标系的单位是毫米,是物理单位,而像素坐标系的单位是像素。通常一个像素点是几行几列。所以这两种变换如下:其中dx和dy分别代表每列每行代表多少mm,即1pixel=dx mm。
通过以上四个坐标系的变换,我们可以得到点是如何从世界坐标系变换到像素坐标系的。
Python代码实现:
用于实现转换的关键代码如下
相关可视化部分已推送到GitHub:Quan/Python-Learning-Notes。
3359全/python-learning-notes/blob/master/modules/utils _ 3d/camera _ tools . py
#-*-编码:utf-8-*-
""
请参考。
# @ project:3d人体姿态估计的整体人体姿态回归
# @作者:panjq
# @电子邮件:[受电子邮件保护]
# @日期:2020-02-041633600:01
# @网址:https://www。建5627 ad 019 df
请参考。
""
进口系统
导入操作系统
sys.path.append(OS.getcwd))
导入cv2
进口编号为NP
来自modules . utils _ 3d importvis _ 3d as vis
fromutilsimportimage _ processing
human36m_camera_intrinsic={
# R,旋转矩阵
r : [ [-0.91536173,0.40180837,0.02574754 ],
[ 0.05154812,0.18037357,-0.98224649],
[-0.39931903、-0.89778361、-0.18581953]]、
# t,平移向量
t : [ 1841.10702775,4955.28462345,1563.453959],
#焦距,f/dx,f/dy
f : [ 1145.04940459,1143.109572],
#主点、主点、主轴和图像平面的交点
[12.54150496]
}
kinect2_camera_intrinsic={
# R,旋转矩阵
R: [[0.999853,- 0.00340388,0.0167495 ],
[0.00300206、0.999708、0.0239986]、
[-0.0168257,- 0.0239459,0.999571 ],
# t,平移向量
t : [ 15.2562,70.2212,-10.9926],
#焦距,f/dx,f/dy
f :
[367.535, 367.535],
#主点,主点、主轴和图像平面的交点
[260.166,205.197]
}
相机_内在=人类36m _相机_内在
# camera _ intrinsic=Kinect 2 _ camera _ intrinsic
类CameraTools(对象):
@静态方法
def convert_wc_to_cc(关节_世界):
世界坐标系-相机坐标系:R * (pt-T):
joint_cam=np.dot(R,(joint_world - T)。t)。T
:返回:
联合_世界=np.asarray(联合_世界)
R=NP . as array(camera _ intrinsic[ R ])
T=NP . as array(camera _ intrinsic[ T ])
联合编号=len(联合世界)
#世界坐标系-相机坐标系
# [Rt]世界坐标-相机坐标
# joint_cam=np.zeros((joint_num,3)) #关节相机
#对于范围内的I(关节编号):#关节I
# joint_cam[i]=np.dot(R,joint_world[i] - T) # R * (pt - T)
# .T是换位,T是翻译垫
joint_cam=np.dot(R,(joint_world - T)。t)。T # R * (pt - T)
返回接头_凸轮
@静态方法
def convert_cc_to_wc(关节_世界):
相机坐标系-世界坐标系:inv(R) * pt T
joint_cam=np.dot(inv(R),joint_world。T) T
:返回:
联合_世界=np.asarray(联合_世界)
R=NP . as array(camera _ intrinsic[ R ])
T=NP . as array(camera _ intrinsic[ T ])
#相机坐标系-世界坐标系
joint _ cam=NP . dot(NP . linalg . inv(R),joint_world。t)。T T
返回接头_凸轮
@静态方法
def __cam2pixel(cam_coord,f,c):
相机坐标系-像素坐标系:(f/dx) * (X/Z)=f * (X/Z)/dx
cx,ppx=260.166cy,PPy=205.197 FX=367.535 fy=367.535
将从三维(X,Y,Z)映射到2D像素坐标P(u,v)计算公式为:
u=X * fx/Z cx
v=Y * fy/Z cy
D(v,u)=Z/Alpha
=====================================================
camera _ matrix=[428.30114,0 . 316.41648],
[ 0. 427.00564, 218.34591],
[ 0. 0. 1.]])
fx=camera_intrinsic[0,0]
fy=camera_intrinsic[1,1]
cx=camera_intrinsic[0,2]
cy=camera_intrinsic[1,2]
=====================================================
:参数cam_coord:
:param f: [fx,fy]
:param c: [cx,cy]
:返回:
# 等价于:(f/dx) * (X/Z)=f * (X/Z)/dx
# 三角变换,/dx,center_x
u=cam_coord[.0]/cam_coord[.2] * f[0] c[0]
v=cam_coord[.1]/cam_coord[.2] * f[1] c[1]
d=cam_coord[. 2]
返回u,v,d
@静态方法
def convert_cc_to_ic(joint_cam):
相机坐标系-像素坐标系
:参数关节_凸轮:
:返回:
# 相机坐标系-像素坐标系,并获取相对深度
#减去中心深度
# 选择骨盆骨盆所在位置作为相机中心,后面用之求相对深度
root_idx=0
center _ cam=joint _ cam[root _ idx]#(x,y,z) mm
关节数量=长度(关节凸轮)
f=camera_intrinsic[f]
c=camera_intrinsic[c]
#联合图像_字典,像素坐标系,深度为相对深度毫米
joint_img=np.zeros((joint_num,3))
joint_img[:0],joint_img[:1],joint_img[:2]=CameraTools .__cam2pixel(joint_cam,f,c) # x,y
joint_img[:2]=joint_img[:2] - center_cam[2] # z
返回关节_img
def demo_for_human36m():
joint_world=[[-91.679,154.404,907.261],
[-223.23566, 163.80551, 890.5342],
[-188.4703, 14.077106, 475.1688],
[-261.84055, 186.55286, 61.438915],
[39.877888, 145.00247, 923.98785],
[-11.675994, 160.89919, 484.39148],
[-51.550297, 220.14624, 35.834396],
[-132.34781, 215.73018, 1128.8396],
[-97.1674, 202.34435, 1383.1466],
[-112.97073, 127.96946, 1477.4457],
[-120.03289, 190.96477, 1573.4],
[25.895456, 192.35947, 1296.1571],
[107.10581, 116.050285, 1040.5062],
[129.8381, -48.024918, 850.94806],
[-230.36955, 203.17923, 1311.9639],
[-315.40536, 164.55284, 1049.1747],
[-350.77136, 43.442127, 831.3473],
[-102.237045, 197.76935, 1304.0605]]
联合_世界=np.asarray(联合_世界)
# 关节点连接线
kps_lines=((0,7),(7,8),(8,9),(9,10),(8,11),(11,12),(12,13),(8,14),(14,15),
(15, 16), (0, 1), (1, 2), (2, 3), (0, 4), (4, 5), (5, 6))
#显示在世界坐标系
vis.vis_3d(joint_world,kps_lines,coordinate=WC ,title=WC ,set_lim=True,isshow=True)
kp_vis=CameraTools()
#显示在相机坐标系
joint _ cam=KP _ vis。转换_ WC _到_ cc(联合_世界)
vis.vis_3d(joint_cam,kps_lines,coordinate=CC ,title=CC ,set_lim=True,isshow=True)
joint _ img=KP _ vis。转换_ cc _ to _ IC(关节_凸轮)
联合_世界1=KP _ vis。将_ cc _转换成_ WC(关节_凸轮)
vis.vis_3d(joint_world1,kps_lines,coordinate=WC ,title=WC ,set_lim=True,isshow=True)
#显示在像素坐标系
kpt_2d=joint_img[:0:2]
image_path= ./data/s _ 01 _ act _ 02 _ subact _ 01 _ ca _ 02 _ 000001。 jpg
图像=图像_处理。读取图像(图像路径)
图像=图像_处理。draw _ key _ point _ in _ image(image,key_points=[kpt_2d],pointline=kps_lines)
图像处理。cv _ show _ image( image _ dict ,image)
if __name__==__main__ :
demo_for_human36m()
效果:
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。