-
Notifications
You must be signed in to change notification settings - Fork 8
/
snapshot.py
74 lines (58 loc) · 2.18 KB
/
snapshot.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
70
71
72
73
74
import cv2.aruco as aruco
from collections import namedtuple
import numpy as np
# Convenience class that allows indexing as well as x and y attribute access
XYPoint = namedtuple("XYPoint", ["x", "y"])
class Marker:
"""Base class for any detected physical objects.
Args:
x (int): x coordinate of center point
y (int): y coordinate of center point
Attribiutes:
center (XYPoint): center point of marker
"""
def __init__(self, x, y):
self.center = XYPoint(x, y)
class ArucoMarker(Marker):
def __init__(self, id, tl, tr, br, bl):
[center_x, center_y] = np.median([np.array(tl), np.array(br)], axis=0)
super().__init__(center_x, center_y)
self.id = id
self.tl = XYPoint(*tl)
self.tr = XYPoint(*tr)
self.bl = XYPoint(*bl)
self.br = XYPoint(*br)
self.rotation = np.degrees(np.arctan((self.tl.y - self.bl.y) /
(self.tl.x - self.bl.x)))
class Snapshot:
"""Current state of physical markers on the landscape.
Processes an image array and pulls out marker information for the user.
Args:
image (numpy.ndarray): A W x H x 3 matrix representing the image
to process.
Attributes:
markers (dict<int, list<ArucoMarker>>): maps marker id to list of marker
objects that match that id.
"""
def __init__(self, image):
self.image = image
self.markers = self.detect_aruco()
def detect_aruco(self):
# Aruco - Find markers
aruco_markers = aruco.detectMarkers(self.image, aruco.Dictionary_get(
aruco.DICT_ARUCO_ORIGINAL))
corners = aruco_markers[0]
ids = aruco_markers[1]
m = {}
if ids is None:
return m
for aruco_id, corner in zip(ids, corners):
id_key = int(aruco_id[0])
[tl, tr, br, bl] = corner[0]
m[id_key] = m.get(id_key, [])
m[id_key].append(ArucoMarker(id_key, tl, tr, br, bl))
return m
class FakeSnapshot:
def __init__(self, fake_markers):
self.image = None
self.markers = {x[0]: [Marker(x[1], x[2])] for x in fake_markers}