前回やったマーカー検出を発展させて今回はマーカーの姿勢を求めます。
7行目でマーカーの一片の長さを[m]表記で指定します。
10,11行目でカメラのキャリブレーション結果をインポートします。
20行目でマーカーの情報を読み取っています。
22~28行目で読み取ったデータの調整をしています。
詳しい動作についてはこのサイト(https://docs.opencv.org/master/d9/d6a/group__aruco.html):を見て解析して下さい。私も理解していない部分があります。
実際に動作させると↓のようになります。
- import numpy as np
- import cv2
- from cv2 import aruco
- def main():
- cap = cv2.VideoCapture(0)
- marker_length = 0.060
- dictionary = aruco.getPredefinedDictionary(aruco.DICT_4X4_50)
- camera_matrix = np.load("mtx.npy")
- distortion_coeff = np.load("dist.npy")
- while True:
- ret, img = cap.read()
- corners, ids, rejectedImgPoints = aruco.detectMarkers(img, dictionary)
- aruco.drawDetectedMarkers(img, corners, ids, (0,255,255))
- if len(corners) > 0:
- for i, corner in enumerate(corners):
- rvec, tvec, _ = aruco.estimatePoseSingleMarkers(corner, marker_length, camera_matrix, distortion_coeff)
- tvec = np.squeeze(tvec)
- rvec = np.squeeze(rvec)
- rvec_matrix = cv2.Rodrigues(rvec)
- rvec_matrix = rvec_matrix[0]
- transpose_tvec = tvec[np.newaxis, :].T
- proj_matrix = np.hstack((rvec_matrix, transpose_tvec))
- euler_angle = cv2.decomposeProjectionMatrix(proj_matrix)[6]
- print("x : " + str(tvec[0]))
- print("y : " + str(tvec[1]))
- print("z : " + str(tvec[2]))
- print("roll : " + str(euler_angle[0]))
- print("pitch: " + str(euler_angle[1]))
- print("yaw : " + str(euler_angle[2]))
- draw_pole_length = marker_length/2
- aruco.drawAxis(img, camera_matrix, distortion_coeff, rvec, tvec, draw_pole_length)
- cv2.imshow('drawDetectedMarkers', img)
- if cv2.waitKey(10) & 0xFF == ord('q'):
- break
- cv2.destroyAllWindows()
- if __name__ == '__main__':
- main()
7行目でマーカーの一片の長さを[m]表記で指定します。
10,11行目でカメラのキャリブレーション結果をインポートします。
20行目でマーカーの情報を読み取っています。
22~28行目で読み取ったデータの調整をしています。
詳しい動作についてはこのサイト(https://docs.opencv.org/master/d9/d6a/group__aruco.html):を見て解析して下さい。私も理解していない部分があります。
実際に動作させると↓のようになります。
ちさと@chisao_62AruCoでマーカーの姿勢推定 https://t.co/IJM4AhRExp
2020/10/19 18:53:09