前回やったマーカー検出を発展させて今回はマーカーの姿勢を求めます。

  1. import numpy as np
  2. import cv2
  3. from cv2 import aruco

  4. def main():
  5.     cap = cv2.VideoCapture(0)
  6.     marker_length = 0.060
  7.     dictionary = aruco.getPredefinedDictionary(aruco.DICT_4X4_50)

  8.     camera_matrix = np.load("mtx.npy")
  9.     distortion_coeff = np.load("dist.npy")

  10.     while True:
  11.         ret, img = cap.read()
  12.         corners, ids, rejectedImgPoints = aruco.detectMarkers(img, dictionary)
  13.         aruco.drawDetectedMarkers(img, corners, ids, (0,255,255))

  14.         if len(corners) > 0:
  15.             for i, corner in enumerate(corners):
  16.                 rvec, tvec, _ = aruco.estimatePoseSingleMarkers(corner, marker_length, camera_matrix, distortion_coeff)
  17.                 
  18.                 tvec = np.squeeze(tvec)
  19.                 rvec = np.squeeze(rvec)
  20.                 rvec_matrix = cv2.Rodrigues(rvec)
  21.                 rvec_matrix = rvec_matrix[0]
  22.                 transpose_tvec = tvec[np.newaxis, :].T
  23.                 proj_matrix = np.hstack((rvec_matrix, transpose_tvec))
  24.                 euler_angle = cv2.decomposeProjectionMatrix(proj_matrix)[6]

  25.                 print("x : " + str(tvec[0]))
  26.                 print("y : " + str(tvec[1]))
  27.                 print("z : " + str(tvec[2]))
  28.                 print("roll : " + str(euler_angle[0]))
  29.                 print("pitch: " + str(euler_angle[1]))
  30.                 print("yaw  : " + str(euler_angle[2]))

  31.                 draw_pole_length = marker_length/2
  32.                 aruco.drawAxis(img, camera_matrix, distortion_coeff, rvec, tvec, draw_pole_length)

  33.         cv2.imshow('drawDetectedMarkers', img)
  34.         if cv2.waitKey(10) & 0xFF == ord('q'):
  35.             break

  36.     cv2.destroyAllWindows()

  37. if __name__ == '__main__':
  38.     main()

7行目でマーカーの一片の長さを[m]表記で指定します。
10,11行目でカメラのキャリブレーション結果をインポートします。
20行目でマーカーの情報を読み取っています。
22~28行目で読み取ったデータの調整をしています。

 詳しい動作についてはこのサイト(https://docs.opencv.org/master/d9/d6a/group__aruco.html):を見て解析して下さい。私も理解していない部分があります。

 実際に動作させると↓のようになります。

スクリーンショット 2020-10-19 212308