3d坐标变换为2d坐标,3d坐标转换成屏幕坐标

  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()

  效果:

3d坐标变换为2d坐标,3d坐标转换成屏幕坐标