-
Notifications
You must be signed in to change notification settings - Fork 302
/
Copy pathpose_estimation_chessboard.py
60 lines (50 loc) · 2.33 KB
/
pose_estimation_chessboard.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import numpy as np
import cv2 as cv
# The given video and calibration data
video_file = '../data/chessboard.avi'
K = np.array([[432.7390364738057, 0, 476.0614994349778],
[0, 431.2395555913084, 288.7602152621297],
[0, 0, 1]])
dist_coeff = np.array([-0.2852754904152874, 0.1016466459919075, -0.0004420196146339175, 0.0001149909868437517, -0.01803978785585194])
board_pattern = (10, 7)
board_cellsize = 0.025
board_criteria = cv.CALIB_CB_ADAPTIVE_THRESH + cv.CALIB_CB_NORMALIZE_IMAGE + cv.CALIB_CB_FAST_CHECK
# Open a video
video = cv.VideoCapture(video_file)
assert video.isOpened(), 'Cannot read the given input, ' + video_file
# Prepare a 3D box for simple AR
box_lower = board_cellsize * np.array([[4, 2, 0], [5, 2, 0], [5, 4, 0], [4, 4, 0]])
box_upper = board_cellsize * np.array([[4, 2, -1], [5, 2, -1], [5, 4, -1], [4, 4, -1]])
# Prepare 3D points on a chessboard
obj_points = board_cellsize * np.array([[c, r, 0] for r in range(board_pattern[1]) for c in range(board_pattern[0])])
# Run pose estimation
while True:
# Read an image from the video
valid, img = video.read()
if not valid:
break
# Estimate the camera pose
success, img_points = cv.findChessboardCorners(img, board_pattern, board_criteria)
if success:
ret, rvec, tvec = cv.solvePnP(obj_points, img_points, K, dist_coeff)
# Draw the box on the image
line_lower, _ = cv.projectPoints(box_lower, rvec, tvec, K, dist_coeff)
line_upper, _ = cv.projectPoints(box_upper, rvec, tvec, K, dist_coeff)
cv.polylines(img, [np.int32(line_lower)], True, (255, 0, 0), 2)
cv.polylines(img, [np.int32(line_upper)], True, (0, 0, 255), 2)
for b, t in zip(line_lower, line_upper):
cv.line(img, np.int32(b.flatten()), np.int32(t.flatten()), (0, 255, 0), 2)
# Print the camera position
R, _ = cv.Rodrigues(rvec) # Alternative) `scipy.spatial.transform.Rotation`
p = (-R.T @ tvec).flatten()
info = f'XYZ: [{p[0]:.3f} {p[1]:.3f} {p[2]:.3f}]'
cv.putText(img, info, (10, 25), cv.FONT_HERSHEY_DUPLEX, 0.6, (0, 255, 0))
# Show the image and process the key event
cv.imshow('Pose Estimation (Chessboard)', img)
key = cv.waitKey(10)
if key == ord(' '):
key = cv.waitKey()
if key == 27: # ESC
break
video.release()
cv.destroyAllWindows()