| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- ''' Camera position estimation from center marker '''
- import cv2
- from cv2 import aruco
- import numpy as np
- import math
- import sys
- import os
- sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
- from default_config import *
- calib_data_path = f"camera_calibration/calib_data/{set_resolution}/MultiMatrix.npz"
- calib_data = np.load(calib_data_path)
- print('resolution:', set_resolution)
- cam_mat = calib_data["camMatrix"]
- dist_coef = calib_data["distCoef"]
- marker_dict = aruco.getPredefinedDictionary(aruco.DICT_7X7_50)
- param_markers = aruco.DetectorParameters()
- cap = cv2.VideoCapture(0)
- # Thay đổi độ phân giải phù hợp với yêu cầu ban đầu
- new_height = RESOLUTION_STANDARDS[set_resolution]
- new_width, new_height = change_resolution(cap,new_height)
- print(f'Resolution camera {new_width}x{new_height}')
- fps = cap.get(cv2.CAP_PROP_FPS)
- print(f"Frames per second: {fps}")
- # convert rotation matrix to euler angles (degrees)
- def rotationMatrixEulerAngles(rotMatrix):
- assert rotMatrix.shape == (3, 3), "Ma trận quay phải có kích thước 3x3"
- sy = math.sqrt(rotMatrix[0, 0]* rotMatrix[0, 0] + rotMatrix[1, 0]*rotMatrix[1, 0])
- singular = sy < 1e-6
- if not singular:
- x = math.atan2(rotMatrix[2, 1], rotMatrix[2, 2])
- x = np.round(np.degrees(x))
- y = math.atan2(-rotMatrix[2, 0], sy)
- y = np.round(np.degrees(y))
- z = math.atan2(rotMatrix[1, 0], rotMatrix[0, 0])
- z = np.round(np.degrees(z))
- else:
- x = math.atan2(rotMatrix[1, 0], rotMatrix[0, 0])
- x = np.round(np.degrees(x))
- y = math.atan2(-rotMatrix[2, 0], sy)
- y = np.round(np.degrees(y))
- z = 0
- return np.array([x, y, z])
- while True:
- ret, frame = cap.read()
- if not ret:
- break
- gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
- marker_corners, marker_IDs, reject = aruco.detectMarkers(
- gray_frame, marker_dict, parameters=param_markers
- )
- if marker_corners:
- rVec, tVec, _ = aruco.estimatePoseSingleMarkers(
- marker_corners, MARKER_SIZE, cam_mat, dist_coef
- )
- total_markers = range(0, marker_IDs.size)
- markers = {}
- for ids, corners, i in zip(marker_IDs, marker_corners, total_markers):
- corners = corners.reshape(4, 2)
- corners = corners.astype(int)
- top_right = corners[0].ravel()
- top_left = corners[1].ravel()
- bottom_right = corners[2].ravel()
- bottom_left = corners[3].ravel()
-
- # Chuyển đổi rVec thành ma trận quay R
- R, _ = cv2.Rodrigues(rVec[i])
-
- # Tính toán tọa độ các điểm của marker so với camera
- object_points = np.array([
- [-MARKER_SIZE / 2, MARKER_SIZE / 2, 0],
- [MARKER_SIZE / 2, MARKER_SIZE / 2, 0],
- [MARKER_SIZE / 2, -MARKER_SIZE / 2, 0],
- [-MARKER_SIZE / 2, -MARKER_SIZE / 2, 0]
- ])
- marker_points_camera = R @ object_points.T + tVec[i].reshape(3, 1)
- marker_points_camera = marker_points_camera.T
- distance = np.sqrt(
- tVec[i][0][2] ** 2 + tVec[i][0][0] ** 2 + tVec[i][0][1] ** 2
- )
- # Draw the pose of the marker
- # point = cv2.drawFrameAxes(frame, cam_mat, dist_coef, rVec[i], tVec[i], 4, 4)
- x = -tVec[i][0][0]
- y = tVec[i][0][1]
- z = tVec[i][0][2]
- pos = np.array([x, y, z])
- angles = rotationMatrixEulerAngles(R.T)
- if ids == 2:
- markers['marker 2'] = np.hstack((pos,angles))
- if ids == 0:
- pos += np.array([-12.3, 9.1, 0])
- markers['marker 0'] = np.hstack((pos,angles))
- if ids == 1:
- pos += np.array([12.3, 9.1, 0.])
- markers['marker 1'] = np.hstack((pos,angles))
- if ids == 3:
- pos += np.array([-7.2, -9.1, 0.])
- markers['marker 3'] = np.hstack((pos,angles))
- if ids == 4:
- pos += np.array([12.3, -5., 0.])
- markers['marker 4'] = np.hstack((pos,angles))
- if 'marker 2' in markers.keys():
- x, y, z, roll, pitch, yaw = np.round(markers['marker 2'], 1)
- else:
- cam_position = np.array([0., 0., 0., 0., 0., 0.])
- for v in markers.values():
- cam_position += v
- cam_position /= len(markers)
- x, y, z, roll, pitch, yaw = np.round(cam_position, 1)
- print(x, y, z, roll, pitch, yaw)
- # cv2.imshow("frame", frame)
- key = cv2.waitKey(1)
- if key == ord("q"):
- break
- cap.release()
- cv2.destroyAllWindows()
|