Skip to content

Commit 74cf92e

Browse files
authored
Add files via upload
1 parent d80e686 commit 74cf92e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+3232
-0
lines changed

Camera/constant.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import numpy as np
2+
import Camera.orientation as orientation
3+
4+
device_frame_from_view_frame = np.array([
5+
[0., 0., 1.],
6+
[1., 0., 0.],
7+
[0., 1., 0.]
8+
])
9+
view_frame_from_device_frame = device_frame_from_view_frame.T
10+
11+
12+
def get_view_frame_from_calib_frame(roll, pitch, yaw, height):
13+
device_from_calib = orientation.rot_from_euler([roll, pitch, yaw])
14+
view_from_calib = view_frame_from_device_frame.dot(device_from_calib)
15+
return np.hstack((view_from_calib, [[0], [height], [0]]))
16+
17+
18+
def get_view_frame_from_road_frame(roll, pitch, yaw, height):
19+
device_from_road = orientation.rot_from_euler([roll, pitch, yaw]).dot(np.diag([1, -1, -1]))
20+
view_from_road = view_frame_from_device_frame.dot(device_from_road)
21+
return np.hstack((view_from_road, [[0], [height], [0]]))
22+
23+
24+
plot_img_width = 1360
25+
plot_img_height = 768
26+
27+
FULL_FRAME_SIZE = (1360, 768)
28+
W, H = FULL_FRAME_SIZE[0], FULL_FRAME_SIZE[1]
29+
eon_focal_length = FOCAL = 900
30+
31+
zoom = FULL_FRAME_SIZE[0] / plot_img_width
32+
CALIB_BB_TO_FULL = np.asarray([
33+
[zoom, 0., 0.],
34+
[0., zoom, 0.],
35+
[0., 0., 1.]])
36+
37+
# MED model
38+
MEDMODEL_INPUT_SIZE = (512, 256)
39+
MEDMODEL_YUV_SIZE = (MEDMODEL_INPUT_SIZE[0], MEDMODEL_INPUT_SIZE[1] * 3 // 2)
40+
MEDMODEL_CY = 47.6
41+
42+
medmodel_fl = 910.0
43+
medmodel_intrinsics = np.array([
44+
[medmodel_fl, 0.0, 0.5 * MEDMODEL_INPUT_SIZE[0]],
45+
[0.0, medmodel_fl, MEDMODEL_CY],
46+
[0.0, 0.0, 1.0]])
47+
48+
# BIG model
49+
BIGMODEL_INPUT_SIZE = (1024, 512)
50+
BIGMODEL_YUV_SIZE = (BIGMODEL_INPUT_SIZE[0], BIGMODEL_INPUT_SIZE[1] * 3 // 2)
51+
52+
bigmodel_fl = 910.0
53+
bigmodel_intrinsics = np.array([
54+
[bigmodel_fl, 0.0, 0.5 * BIGMODEL_INPUT_SIZE[0]],
55+
[0.0, bigmodel_fl, 256 + MEDMODEL_CY],
56+
[0.0, 0.0, 1.0]])
57+
58+
# SBIG model (big model with the size of small model)
59+
SBIGMODEL_INPUT_SIZE = (512, 256)
60+
SBIGMODEL_YUV_SIZE = (SBIGMODEL_INPUT_SIZE[0], SBIGMODEL_INPUT_SIZE[1] * 3 // 2)
61+
62+
sbigmodel_fl = 455.0
63+
sbigmodel_intrinsics = np.array([
64+
[sbigmodel_fl, 0.0, 0.5 * SBIGMODEL_INPUT_SIZE[0]],
65+
[0.0, sbigmodel_fl, 0.5 * (256 + MEDMODEL_CY)],
66+
[0.0, 0.0, 1.0]])
67+
68+
bigmodel_frame_from_calib_frame = np.dot(bigmodel_intrinsics,
69+
get_view_frame_from_calib_frame(0, 0, 0, 0))
70+
71+
sbigmodel_frame_from_calib_frame = np.dot(sbigmodel_intrinsics,
72+
get_view_frame_from_calib_frame(0, 0, 0, 0))
73+
74+
medmodel_frame_from_calib_frame = np.dot(medmodel_intrinsics,
75+
get_view_frame_from_calib_frame(0, 0, 0, 0))
76+
77+
medmodel_frame_from_bigmodel_frame = np.dot(medmodel_intrinsics, np.linalg.inv(bigmodel_intrinsics))
78+
79+
# aka 'K' aka camera_frame_from_view_frame
80+
eon_intrinsics = np.array([
81+
[1000, 0., W / 2.],
82+
[0., 350, H / 2. + 20],
83+
[0., 0., 1.]])

Camera/coordinates.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import numpy as np
2+
3+
"""
4+
Coordinate transformation module. All methods accept arrays as input
5+
with each row as a position.
6+
"""
7+
8+
a = 6378137
9+
b = 6356752.3142
10+
esq = 6.69437999014 * 0.001
11+
e1sq = 6.73949674228 * 0.001
12+
13+
14+
def geodetic2ecef(geodetic, radians=False):
15+
geodetic = np.array(geodetic)
16+
input_shape = geodetic.shape
17+
geodetic = np.atleast_2d(geodetic)
18+
19+
ratio = 1.0 if radians else (np.pi / 180.0)
20+
lat = ratio * geodetic[:, 0]
21+
lon = ratio * geodetic[:, 1]
22+
alt = geodetic[:, 2]
23+
24+
xi = np.sqrt(1 - esq * np.sin(lat) ** 2)
25+
x = (a / xi + alt) * np.cos(lat) * np.cos(lon)
26+
y = (a / xi + alt) * np.cos(lat) * np.sin(lon)
27+
z = (a / xi * (1 - esq) + alt) * np.sin(lat)
28+
ecef = np.array([x, y, z]).T
29+
return ecef.reshape(input_shape)
30+
31+
32+
def ecef2geodetic(ecef, radians=False):
33+
"""
34+
Convert ECEF coordinates to geodetic using ferrari's method
35+
"""
36+
# Save shape and export column
37+
ecef = np.atleast_1d(ecef)
38+
input_shape = ecef.shape
39+
ecef = np.atleast_2d(ecef)
40+
x, y, z = ecef[:, 0], ecef[:, 1], ecef[:, 2]
41+
42+
ratio = 1.0 if radians else (180.0 / np.pi)
43+
44+
# Conver from ECEF to geodetic using Ferrari's methods
45+
# https://en.wikipedia.org/wiki/Geographic_coordinate_conversion#Ferrari.27s_solution
46+
r = np.sqrt(x * x + y * y)
47+
Esq = a * a - b * b
48+
F = 54 * b * b * z * z
49+
G = r * r + (1 - esq) * z * z - esq * Esq
50+
C = (esq * esq * F * r * r) / (pow(G, 3))
51+
S = np.cbrt(1 + C + np.sqrt(C * C + 2 * C))
52+
P = F / (3 * pow((S + 1 / S + 1), 2) * G * G)
53+
Q = np.sqrt(1 + 2 * esq * esq * P)
54+
r_0 = -(P * esq * r) / (1 + Q) + np.sqrt(0.5 * a * a * (1 + 1.0 / Q) -
55+
P * (1 - esq) * z * z / (Q * (1 + Q)) - 0.5 * P * r * r)
56+
U = np.sqrt(pow((r - esq * r_0), 2) + z * z)
57+
V = np.sqrt(pow((r - esq * r_0), 2) + (1 - esq) * z * z)
58+
Z_0 = b * b * z / (a * V)
59+
h = U * (1 - b * b / (a * V))
60+
lat = ratio * np.arctan((z + e1sq * Z_0) / r)
61+
lon = ratio * np.arctan2(y, x)
62+
63+
# stack the new columns and return to the original shape
64+
geodetic = np.column_stack((lat, lon, h))
65+
return geodetic.reshape(input_shape)
66+
67+
68+
class LocalCoord:
69+
"""
70+
Allows conversions to local frames. In this case NED.
71+
That is: North East Down from the start position in
72+
meters.
73+
"""
74+
75+
def __init__(self, init_geodetic, init_ecef):
76+
self.init_ecef = init_ecef
77+
lat, lon, _ = (np.pi / 180) * np.array(init_geodetic)
78+
self.ned2ecef_matrix = np.array([[-np.sin(lat) * np.cos(lon), -np.sin(lon), -np.cos(lat) * np.cos(lon)],
79+
[-np.sin(lat) * np.sin(lon), np.cos(lon), -np.cos(lat) * np.sin(lon)],
80+
[np.cos(lat), 0, -np.sin(lat)]])
81+
self.ecef2ned_matrix = self.ned2ecef_matrix.T
82+
83+
@classmethod
84+
def from_geodetic(cls, init_geodetic):
85+
init_ecef = geodetic2ecef(init_geodetic)
86+
return LocalCoord(init_geodetic, init_ecef)
87+
88+
@classmethod
89+
def from_ecef(cls, init_ecef):
90+
init_geodetic = ecef2geodetic(init_ecef)
91+
return LocalCoord(init_geodetic, init_ecef)
92+
93+
def ecef2ned(self, ecef):
94+
ecef = np.array(ecef)
95+
return np.dot(self.ecef2ned_matrix, (ecef - self.init_ecef).T).T
96+
97+
def ned2ecef(self, ned):
98+
ned = np.array(ned)
99+
# Transpose so that init_ecef will broadcast correctly for 1d or 2d ned.
100+
return np.dot(self.ned2ecef_matrix, ned.T).T + self.init_ecef
101+
102+
def geodetic2ned(self, geodetic):
103+
ecef = geodetic2ecef(geodetic)
104+
return self.ecef2ned(ecef)
105+
106+
def ned2geodetic(self, ned):
107+
ecef = self.ned2ecef(ned)
108+
return ecef2geodetic(ecef)

0 commit comments

Comments
 (0)