飞道的博客

世界坐标系,相机坐标系和图像坐标系的转换(Python)

1188人阅读  评论(0)

世界坐标系,相机坐标系和图像坐标系的转换(Python)


相机内参外参说明:https://panjinquan.blog.csdn.net/article/details/102502213

计算机视觉:相机成像原理:世界坐标系、相机坐标系、图像坐标系、像素坐标系之间的转换:https://blog.csdn.net/chentravelling/article/details/53558096


1.世界坐标->相机坐标


2.相机坐标系->图像坐标系

此时投影点p的单位还是mm,并不是pixel,需要进一步转换到像素坐标系。

3.图像坐标系与像素坐标系

像素坐标系和图像坐标系都在成像平面上,只是各自的原点和度量单位不一样。图像坐标系的原点为相机光轴与成像平面的交点,通常情况下是成像平面的中点或者叫principal point。图像坐标系的单位是mm,属于物理单位,而像素坐标系的单位是pixel,我们平常描述一个像素点都是几行几列。所以这二者之间的转换如下:其中dx和dy表示每一列和每一行分别代表多少mm,即1pixel=dx mm 


那么通过上面四个坐标系的转换就可以得到一个点从世界坐标系如何转换到像素坐标系的。 

 


python代码shi实现:


  
  1. # -*- coding: utf-8 -*-
  2. """
  3. # --------------------------------------------------------
  4. # @Project: prpject
  5. # @Author : panjq
  6. # @E-mail : pan_jinquan@163.com
  7. # @Date : 2020-02-04 16:03:01
  8. # @url : https://www.jianshu.com/p/c5627ad019df
  9. # --------------------------------------------------------
  10. """
  11. import sys
  12. import os
  13. from tools import image_processing
  14. sys.path.append(os.getcwd())
  15. import numpy as np
  16. from modules.utils_3d import vis
  17. camera_intrinsic = {
  18. # R,旋转矩阵
  19. "R": [[ -0.91536173, 0.40180837, 0.02574754],
  20. [ 0.05154812, 0.18037357, -0.98224649],
  21. [ -0.39931903, -0.89778361, -0.18581953]],
  22. # t,平移向量
  23. "T": [ 1841.10702775, 4955.28462345, 1563.4453959],
  24. # 焦距,f/dx, f/dy
  25. "f": [ 1145.04940459, 1143.78109572],
  26. # principal point,主点,主轴与像平面的交点
  27. "c": [ 512.54150496, 515.45148698]
  28. }
  29. class Human36M(object):
  30. @staticmethod
  31. def convert_wc_to_cc(joint_world):
  32. """
  33. 世界坐标系 -> 相机坐标系: R * (pt - T)
  34. :return:
  35. """
  36. joint_world = np.asarray(joint_world)
  37. R = np.asarray(camera_intrinsic[ "R"])
  38. T = np.asarray(camera_intrinsic[ "T"])
  39. joint_num = len(joint_world)
  40. # 世界坐标系 -> 相机坐标系
  41. # [R|t] world coords -> camera coords
  42. joint_cam = np.zeros((joint_num, 3)) # joint camera
  43. for i in range(joint_num): # joint i
  44. joint_cam[i] = np.dot(R, joint_world[i] - T) # R * (pt - T)
  45. return joint_cam
  46. @staticmethod
  47. def __cam2pixel(cam_coord, f, c):
  48. """
  49. 相机坐标系 -> 像素坐标系: (f / dx) * (X / Z) = f * (X / Z) / dx
  50. cx,ppx=260.166; cy,ppy=205.197; fx=367.535; fy=367.535
  51. 将从3D(X,Y,Z)映射到2D像素坐标P(u,v)计算公式为:
  52. u = X * fx / Z + cx
  53. v = Y * fy / Z + cy
  54. D(v,u) = Z / Alpha
  55. =====================================================
  56. camera_matrix = [[428.30114, 0., 316.41648],
  57. [ 0., 427.00564, 218.34591],
  58. [ 0., 0., 1.]])
  59. fx = camera_intrinsic[0, 0]
  60. fy = camera_intrinsic[1, 1]
  61. cx = camera_intrinsic[0, 2]
  62. cy = camera_intrinsic[1, 2]
  63. =====================================================
  64. :param cam_coord:
  65. :param f: [fx,fy]
  66. :param c: [cx,cy]
  67. :return:
  68. """
  69. # 等价于:(f / dx) * (X / Z) = f * (X / Z) / dx
  70. # 三角变换, / dx, + center_x
  71. u = cam_coord[..., 0] / cam_coord[..., 2] * f[ 0] + c[ 0]
  72. v = cam_coord[..., 1] / cam_coord[..., 2] * f[ 1] + c[ 1]
  73. d = cam_coord[..., 2]
  74. return u, v, d
  75. @staticmethod
  76. def convert_cc_to_ic(joint_cam):
  77. """
  78. 相机坐标系 -> 像素坐标系
  79. :param joint_cam:
  80. :return:
  81. """
  82. # 相机坐标系 -> 像素坐标系,并 get relative depth
  83. # Subtract center depth
  84. # 选择 Pelvis骨盆 所在位置作为相机中心,后面用之求relative depth
  85. root_idx = 0
  86. center_cam = joint_cam[root_idx] # (x,y,z) mm
  87. joint_num = len(joint_cam)
  88. f = camera_intrinsic[ "f"]
  89. c = camera_intrinsic[ "c"]
  90. # joint image,像素坐标系,Depth 为相对深度 mm
  91. joint_img = np.zeros((joint_num, 3))
  92. joint_img[:, 0], joint_img[:, 1], joint_img[:, 2] = Human36M.__cam2pixel(joint_cam, f, c) # x,y
  93. joint_img[:, 2] = joint_img[:, 2] - center_cam[ 2] # z
  94. return joint_img
  95. if __name__ == "__main__":
  96. joint_world = [[ -91.679, 154.404, 907.261],
  97. [ -223.23566, 163.80551, 890.5342],
  98. [ -188.4703, 14.077106, 475.1688],
  99. [ -261.84055, 186.55286, 61.438915],
  100. [ 39.877888, 145.00247, 923.98785],
  101. [ -11.675994, 160.89919, 484.39148],
  102. [ -51.550297, 220.14624, 35.834396],
  103. [ -132.34781, 215.73018, 1128.8396],
  104. [ -97.1674, 202.34435, 1383.1466],
  105. [ -112.97073, 127.96946, 1477.4457],
  106. [ -120.03289, 190.96477, 1573.4],
  107. [ 25.895456, 192.35947, 1296.1571],
  108. [ 107.10581, 116.050285, 1040.5062],
  109. [ 129.8381, -48.024918, 850.94806],
  110. [ -230.36955, 203.17923, 1311.9639],
  111. [ -315.40536, 164.55284, 1049.1747],
  112. [ -350.77136, 43.442127, 831.3473],
  113. [ -102.237045, 197.76935, 1304.0605]]
  114. joint_world = np.asarray(joint_world)
  115. kps_lines = (( 0, 7), ( 7, 8), ( 8, 9), ( 9, 10), ( 8, 11), ( 11, 12), ( 12, 13), ( 8, 14), ( 14, 15),
  116. ( 15, 16), ( 0, 1), ( 1, 2), ( 2, 3), ( 0, 4), ( 4, 5), ( 5, 6))
  117. # show in 世界坐标系
  118. vis.vis_3d(joint_world, kps_lines, coordinate= "WC", title= "WC")
  119. human36m = Human36M()
  120. # show in 相机坐标系
  121. joint_cam = human36m.convert_wc_to_cc(joint_world)
  122. vis.vis_3d(joint_cam, kps_lines, coordinate= "CC", title= "CC")
  123. joint_img = human36m.convert_cc_to_ic(joint_cam)
  124. # show in 像素坐标系
  125. kpt_2d = joint_img[:, 0: 2]
  126. image_path = "/media/dm/dm1/git/python-learning-notes/modules/utils_3d/s_01_act_02_subact_01_ca_02_000001.jpg"
  127. image = image_processing.read_image(image_path)
  128. image = image_processing.draw_key_point_in_image(image, key_points=[kpt_2d], pointline=kps_lines)
  129. image_processing.cv_show_image( "image", image)

 


转载:https://blog.csdn.net/guyuealian/article/details/104184551
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场