camera_position.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. ''' Camera position estimation from center marker '''
  2. import cv2
  3. from cv2 import aruco
  4. import numpy as np
  5. import math
  6. import sys
  7. import os
  8. sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
  9. from default_config import *
  10. calib_data_path = f"camera_calibration/calib_data/{set_resolution}/MultiMatrix.npz"
  11. calib_data = np.load(calib_data_path)
  12. print('resolution:', set_resolution)
  13. cam_mat = calib_data["camMatrix"]
  14. dist_coef = calib_data["distCoef"]
  15. marker_dict = aruco.getPredefinedDictionary(aruco.DICT_7X7_50)
  16. param_markers = aruco.DetectorParameters()
  17. cap = cv2.VideoCapture(0)
  18. # Thay đổi độ phân giải phù hợp với yêu cầu ban đầu
  19. new_height = RESOLUTION_STANDARDS[set_resolution]
  20. new_width, new_height = change_resolution(cap,new_height)
  21. print(f'Resolution camera {new_width}x{new_height}')
  22. fps = cap.get(cv2.CAP_PROP_FPS)
  23. print(f"Frames per second: {fps}")
  24. # convert rotation matrix to euler angles (degrees)
  25. def rotationMatrixEulerAngles(rotMatrix):
  26. assert rotMatrix.shape == (3, 3), "Ma trận quay phải có kích thước 3x3"
  27. sy = math.sqrt(rotMatrix[0, 0]* rotMatrix[0, 0] + rotMatrix[1, 0]*rotMatrix[1, 0])
  28. singular = sy < 1e-6
  29. if not singular:
  30. x = math.atan2(rotMatrix[2, 1], rotMatrix[2, 2])
  31. x = np.round(np.degrees(x))
  32. y = math.atan2(-rotMatrix[2, 0], sy)
  33. y = np.round(np.degrees(y))
  34. z = math.atan2(rotMatrix[1, 0], rotMatrix[0, 0])
  35. z = np.round(np.degrees(z))
  36. else:
  37. x = math.atan2(rotMatrix[1, 0], rotMatrix[0, 0])
  38. x = np.round(np.degrees(x))
  39. y = math.atan2(-rotMatrix[2, 0], sy)
  40. y = np.round(np.degrees(y))
  41. z = 0
  42. return np.array([x, y, z])
  43. while True:
  44. ret, frame = cap.read()
  45. if not ret:
  46. break
  47. gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
  48. marker_corners, marker_IDs, reject = aruco.detectMarkers(
  49. gray_frame, marker_dict, parameters=param_markers
  50. )
  51. if marker_corners:
  52. rVec, tVec, _ = aruco.estimatePoseSingleMarkers(
  53. marker_corners, MARKER_SIZE, cam_mat, dist_coef
  54. )
  55. total_markers = range(0, marker_IDs.size)
  56. markers = {}
  57. for ids, corners, i in zip(marker_IDs, marker_corners, total_markers):
  58. corners = corners.reshape(4, 2)
  59. corners = corners.astype(int)
  60. top_right = corners[0].ravel()
  61. top_left = corners[1].ravel()
  62. bottom_right = corners[2].ravel()
  63. bottom_left = corners[3].ravel()
  64. # Chuyển đổi rVec thành ma trận quay R
  65. R, _ = cv2.Rodrigues(rVec[i])
  66. # Tính toán tọa độ các điểm của marker so với camera
  67. object_points = np.array([
  68. [-MARKER_SIZE / 2, MARKER_SIZE / 2, 0],
  69. [MARKER_SIZE / 2, MARKER_SIZE / 2, 0],
  70. [MARKER_SIZE / 2, -MARKER_SIZE / 2, 0],
  71. [-MARKER_SIZE / 2, -MARKER_SIZE / 2, 0]
  72. ])
  73. marker_points_camera = R @ object_points.T + tVec[i].reshape(3, 1)
  74. marker_points_camera = marker_points_camera.T
  75. distance = np.sqrt(
  76. tVec[i][0][2] ** 2 + tVec[i][0][0] ** 2 + tVec[i][0][1] ** 2
  77. )
  78. # Draw the pose of the marker
  79. # point = cv2.drawFrameAxes(frame, cam_mat, dist_coef, rVec[i], tVec[i], 4, 4)
  80. x = -tVec[i][0][0]
  81. y = tVec[i][0][1]
  82. z = tVec[i][0][2]
  83. pos = np.array([x, y, z])
  84. angles = rotationMatrixEulerAngles(R.T)
  85. if ids == 2:
  86. markers['marker 2'] = np.hstack((pos,angles))
  87. if ids == 0:
  88. pos += np.array([-12.3, 9.1, 0])
  89. markers['marker 0'] = np.hstack((pos,angles))
  90. if ids == 1:
  91. pos += np.array([12.3, 9.1, 0.])
  92. markers['marker 1'] = np.hstack((pos,angles))
  93. if ids == 3:
  94. pos += np.array([-7.2, -9.1, 0.])
  95. markers['marker 3'] = np.hstack((pos,angles))
  96. if ids == 4:
  97. pos += np.array([12.3, -5., 0.])
  98. markers['marker 4'] = np.hstack((pos,angles))
  99. if 'marker 2' in markers.keys():
  100. x, y, z, roll, pitch, yaw = np.round(markers['marker 2'], 1)
  101. else:
  102. cam_position = np.array([0., 0., 0., 0., 0., 0.])
  103. for v in markers.values():
  104. cam_position += v
  105. cam_position /= len(markers)
  106. x, y, z, roll, pitch, yaw = np.round(cam_position, 1)
  107. print(x, y, z, roll, pitch, yaw)
  108. # cv2.imshow("frame", frame)
  109. key = cv2.waitKey(1)
  110. if key == ord("q"):
  111. break
  112. cap.release()
  113. cv2.destroyAllWindows()