当前位置:   article > 正文

非常详细的相机标定(六)(2维坐标点转为3维坐标点)_python/opencv利用相机位姿估计实现2d图像像素坐标到3d世界坐标的转换

python/opencv利用相机位姿估计实现2d图像像素坐标到3d世界坐标的转换

根据提取的相机的参数,2维坐标点转为3维坐标点,代码如下:

  1. import argparse
  2. from argparse import RawTextHelpFormatter
  3. import numpy as np
  4. import cv2
  5. # 寻找焦点
  6. def cam_calib_find_corners(img, rlt_dir, col, row):
  7. # 灰度化图片,减少参数的运算
  8. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  9. # 寻找角点
  10. ret, corners = cv2.findChessboardCorners(gray, (col, row), None)
  11. # 为了得到稍微精确一点的角点坐标,进一步对角点进行亚像素寻找
  12. corners2 = cv2.cornerSubPix(
  13. gray, corners, (7, 7), (-1, -1), (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_COUNT, 10, 0.001))
  14. if ret == True:
  15. # 保存角点图像
  16. sav_path = rlt_dir + "/1_corner.jpg"
  17. # 绘制角点
  18. cv2.drawChessboardCorners(img, (col, row), corners2, ret)
  19. cv2.imwrite(sav_path, img)
  20. return (ret, corners2)
  21. # 相机标定
  22. def cam_calib_calibrate(img_dir, rlt_dir, col, row, img_num):
  23. w = 0
  24. h = 0
  25. all_corners = []
  26. patterns = []
  27. x, y = np.meshgrid(range(col), range(row))
  28. prod = row * col
  29. pattern_points = np.hstack(
  30. (x.reshape(prod, 1), y.reshape(prod, 1), np.zeros((prod, 1)))).astype(np.float32)
  31. img_path = r"C:\Users\17930\Desktop\1.jpg"
  32. img = cv2.imread(img_path)
  33. if img is None:
  34. print(f"Error reading image at {img_path}")
  35. pass
  36. else:
  37. (h, w) = img.shape[:2]
  38. ret, corners = cam_calib_find_corners(img, rlt_dir, col, row)
  39. all_corners.append(corners)
  40. patterns.append(pattern_points)
  41. rms, cameraMatrix, distCoeffs, rvecs, tvecs = cv2.calibrateCamera(
  42. patterns, all_corners, (w, h), None, None)
  43. print('相机内参', cameraMatrix)
  44. print('相机外参旋转向量', rvecs)
  45. print('相机外参平移向量', tvecs)
  46. return cameraMatrix, distCoeffs, rvecs, tvecs
  47. if __name__ == "__main__":
  48. parser = argparse.ArgumentParser(
  49. description="读取标定的图片并保存结果", formatter_class=RawTextHelpFormatter)
  50. parser.add_argument("--img_dir", help="标定图片路径", type=str,
  51. metavar='', default=r'D:\螺丝数据集与相机标定代码\camera\calib_img')
  52. parser.add_argument("--rlt_dir", help="保存路径", type=str,
  53. metavar='', default="rlt_dir")
  54. parser.add_argument("--crct_img_dir", help="待矫正图像路径",
  55. type=str, metavar='', default="crct_img")
  56. parser.add_argument("--row_num", help="每一行有多少个角点,边缘处的不算",
  57. type=int, metavar='', default="7")
  58. parser.add_argument("--col_num", help="每一列有多少个角点,边缘处的不算",
  59. type=int, metavar='', default="6")
  60. parser.add_argument("--img_num", help="多少幅图像",
  61. type=int, metavar='', default="4")
  62. args = parser.parse_args()
  63. cameraMatrix, distCoeffs, rvecs, tvecs = cam_calib_calibrate(
  64. args.img_dir, args.rlt_dir, args.row_num, args.col_num, args.img_num)
  65. image_points = np.array([[55, 66], [77, 88]], dtype=np.float32)
  66. world_z = 0
  67. world_points = []
  68. for i in range(len(rvecs)):
  69. rotation_matrix, _ = cv2.Rodrigues(rvecs[i])
  70. projection_matrix = np.dot(cameraMatrix, np.hstack(
  71. (rotation_matrix, tvecs[i])))
  72. inv_projection_matrix = np.linalg.pinv(projection_matrix)
  73. for pt in image_points:
  74. img_pt = np.array([pt[0], pt[1], 1])
  75. ray_dir = np.dot(inv_projection_matrix, img_pt)
  76. scale = (world_z - tvecs[i][2]) / ray_dir[2]
  77. world_pt = tvecs[i].reshape(3) + scale * ray_dir[:3]
  78. world_points.append(world_pt)
  79. world_points = np.array(world_points)
  80. print(world_points)

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/90290
推荐阅读
相关标签
  

闽ICP备14008679号