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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#!/usr/bin/env python
from dataclasses import dataclass, field
import math
import re
from argaze import DataStructures
from argaze.AreaOfInterest import AOIFeatures, AOI2DScene
import numpy
import cv2 as cv
@dataclass
class AOI3DScene(AOIFeatures.AOIScene):
"""Define AOI 3D scene."""
rotation: list = field(init=False, default=numpy.asarray([0., 0., 0.]))
translation: list = field(init=False, default=numpy.asarray([0., 0., 0.]))
def __post_init__(self, **aois):
# set dimension member
self.dimension = 3
def load(self, obj_filepath: str):
"""Load AOI3D scene from .obj file."""
# regex rules for .obj file parsing
OBJ_RX_DICT = {
'comment': re.compile(r'#(.*)\n'),
'name': re.compile(r'o (\w+)(.*)\n'),
'vertice': re.compile(r'v ([+-]?[0-9]*[.]?[0-9]+) ([+-]?[0-9]*[.]?[0-9]+) ([+-]?[0-9]*[.]?[0-9]+)\n'),
'face': re.compile(r'f (.*)\n')
}
# regex .obj line parser
def __parse_obj_line(line):
for key, rx in OBJ_RX_DICT.items():
match = rx.search(line)
if match:
return key, match
# if there are no matches
return None, None
# start parsing
try:
name = None
vertices = []
faces = {}
# open the file and read through it line by line
with open(obj_filepath, 'r') as file:
line = file.readline()
while line:
# at each line check for a match with a regex
key, match = __parse_obj_line(line)
# extract comment
if key == 'comment':
pass
# extract aoi3D name
elif key == 'name':
name = str(match.group(1))
# fill vertices array
elif key == 'vertice':
vertices.append(tuple([float(match.group(1)), float(match.group(2)), float(match.group(3))]))
# extract aoi3D vertice id
elif key == 'face':
faces[name] = [int(i) for i in match.group(1).split()]
# go to next line
line = file.readline()
file.close()
# retreive all aoi3D vertices
for name, face in faces.items():
aoi3D = numpy.array([ vertices[i-1] for i in face ]).astype('float32').view(AOIFeatures.AreaOfInterest)
self.append(name, aoi3D)
except IOError:
raise IOError(f'File not found: {obj_filepath}')
def project(self, K, D):
"""Project 3D scene onto 2D scene according optical parameters.
**Returns:** AOI2DScene"""
aoi2D_scene = AOI2DScene.AOI2DScene()
for name, aoi3D in self.areas.items():
vertices_2D, J = cv.projectPoints(aoi3D, self.rotation, self.translation, K, D)
vertices_2D = vertices_2D.astype('int').reshape((len(vertices_2D), 2)).tolist()
aoi2D = numpy.array(vertices_2D).view(AOIFeatures.AreaOfInterest)
aoi2D_scene.append(name, aoi2D)
return aoi2D_scene
|