-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathfeedback.py
69 lines (52 loc) · 2.95 KB
/
feedback.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
61
62
63
64
65
66
67
68
69
import cv2
from cv2 import aruco
import math
class MarkerDetector:
def __init__(self, aruco_dict, mtx, dist):
self.aruco_dict = aruco_dict
self.parameters = aruco.DetectorParameters_create()
self.mtx = mtx
self.dist = dist
def detect(self, frame, target):
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
corners, ids, rejectedImgPoints = aruco.detectMarkers(gray, self.aruco_dict, parameters=self.parameters)
# SUB PIXEL DETECTION
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.0001)
for corner in corners:
cv2.cornerSubPix(gray, corner, winSize=(3, 3), zeroZone=(-1, -1), criteria=criteria)
size_of_marker = 0.15 # side lenght of the marker in meters
rvecs, tvecs, _objPoints = aruco.estimatePoseSingleMarkers(corners, size_of_marker, self.mtx, self.dist)
length_of_axis = 0.1
imaxis = aruco.drawDetectedMarkers(frame.copy(), corners, ids)
#print(ids, corners)
if tvecs is not None:
target_id = None
for i in range(len(ids)):
if ids[i] == target:
target_id = i
if target_id is not None:
imaxis = aruco.drawAxis(imaxis, self.mtx, self.dist, rvecs[target_id], tvecs[target_id], length_of_axis)
x = (corners[target_id][0][0][0] + corners[target_id][0][2][0]) / 2
y = (corners[target_id][0][0][1] + corners[target_id][0][2][1]) / 2
square_side_dimension_px = math.sqrt(math.pow(corners[target_id][0][3][1] - corners[target_id][0][0][1], 2) + math.pow(corners[target_id][0][3][0] - corners[target_id][0][0][0], 2))
return imaxis, x, y, square_side_dimension_px
else:
return frame, None, None, None
else:
return frame, None, None, None
def detect_and_compute_error_values(self, frame, set_point_x, set_point_y, set_point_z, target):
imaxis, x, y, square_side_dimension_px = self.detect(frame, target)
if x is not None:
horizontal_error, vertical_error, frontal_error = compute_error_values(x, y, square_side_dimension_px, set_point_x, set_point_y, set_point_z)
return imaxis, horizontal_error, vertical_error, frontal_error
else:
return imaxis, None, None, None
def distance_estimator(square_side_dimension_px):
return 1.129e+04 * math.pow(square_side_dimension_px, -0.9631) + (-11.26)
def compute_error_values(x, y, square_side_dimension_px, set_point_x, set_point_y, set_point_z):
frontal_distance_cm = int(distance_estimator(square_side_dimension_px))
cm_pix_ratio = 15 / square_side_dimension_px # 15 [cm] / marker dimension [pixel]
horizontal_error = int((set_point_x - x) * cm_pix_ratio)
vertical_error = int((set_point_y - y) * cm_pix_ratio)
frontal_error = frontal_distance_cm - set_point_z
return horizontal_error, vertical_error, frontal_error