Skip to content

Commit 8c2b4aa

Browse files
committed
exterior is a numpy array. works well with recarray view
1 parent 0d6b6fb commit 8c2b4aa

13 files changed

Lines changed: 161 additions & 162 deletions

openptv_python/calibration.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def rotation_matrix(ext: np.ndarray) -> None:
2020
https://doi.org/10.1007/BF00190953
2121
2222
"""
23-
omega, phi, kappa = ext[0]['omega'], ext[0]['phi'], ext[0]['kappa']
23+
omega, phi, kappa = ext['omega'], ext['phi'], ext['kappa']
2424

2525

2626
co = np.cos(omega)
@@ -33,7 +33,7 @@ def rotation_matrix(ext: np.ndarray) -> None:
3333
sk = np.sin(kappa)
3434

3535
# dm = np.zeros((3, 3), dtype=np.float64)
36-
dm = ext[0]['dm'] # shortcut to the dm field of the first element of the array
36+
dm = ext['dm'] # shortcut to the dm field of the first element of the array
3737

3838
dm[0, 0] = cp * ck
3939
dm[0, 1] = -cp * sk
@@ -58,9 +58,10 @@ def rotation_matrix(ext: np.ndarray) -> None:
5858
('kappa', np.float64),
5959
('dm', np.float64, (3, 3))
6060
])
61-
Exterior = np.zeros(1, dtype=exterior_dtype).view(np.recarray) # initialize memory
61+
# Exterior = np.zeros(1, dtype=exterior_dtype).view(np.recarray) # initialize memory
62+
Exterior = np.array((0, 0, 0, 0, 0, 0, np.eye(3)), dtype = exterior_dtype).view(np.recarray)
6263
rotation_matrix(Exterior) # rotation should be a unit matrix
63-
assert np.allclose(np.eye(3), Exterior[0]['dm'])
64+
assert np.allclose(np.eye(3), Exterior['dm'])
6465

6566

6667
# rotation_matrix(exterior) # inplace update of the rotation matrix
@@ -249,9 +250,12 @@ def write(self, ori_file: str, addpar_file: str):
249250

250251
def increment_attribute(self, attr_name, increment_value):
251252
"""Update the value of an attribute by increment_value."""
252-
if hasattr(self, attr_name):
253-
setattr(self, attr_name, getattr(
254-
self, attr_name) + increment_value)
253+
if hasattr(self.ext_par, attr_name):
254+
setattr(self.ext_par, attr_name, getattr(
255+
self.ext_par, attr_name) + increment_value)
256+
if hasattr(self.int_par, attr_name):
257+
setattr(self.int_par, attr_name, getattr(
258+
self.int_par, attr_name) + increment_value)
255259

256260
def update_rotation_matrix(self) -> None:
257261
"""Update the rotation matrix of the exterior orientation."""
@@ -441,9 +445,9 @@ def write_ori(
441445
success = False
442446

443447
with open(filename, "w", encoding="utf-8") as fp:
444-
fp.write(f"{ext_par[0]['x0']:.8f} {ext_par[0]['y0']:.8f} {ext_par[0]['z0']:.8f}\n")
445-
fp.write(f"{ext_par[0]['omega']:.8f} {ext_par[0]['phi']:.8f} {ext_par[0]['kappa']:.8f}\n\n")
446-
for row in ext_par[0]['dm']:
448+
fp.write(f"{ext_par['x0']:.8f} {ext_par['y0']:.8f} {ext_par['z0']:.8f}\n")
449+
fp.write(f"{ext_par['omega']:.8f} {ext_par['phi']:.8f} {ext_par['kappa']:.8f}\n\n")
450+
for row in ext_par['dm']:
447451
fp.write(f"{row[0]:.7f} {row[1]:.7f} {row[2]:.7f}\n")
448452
fp.write(f"\n{int_par.xh:.4f} {int_par.yh:.4f}\n{int_par.cc:.4f}\n")
449453
fp.write(

openptv_python/imgcoord.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def flat_image_coord(
4848
pos_t = np.r_[x_t, y_t, pos_t[2]]
4949
pos = back_trans_point(pos_t, mm, cal.glass_par, cross_p, cross_c)
5050

51-
dm = cal.ext_par[0].dm
51+
dm = cal.ext_par.dm
5252
origin = np.r_[cal.ext_par.x0, cal.ext_par.y0, cal.ext_par.z0]
5353

5454
deno = np.dot(dm[:,2], (pos - origin))

openptv_python/multimed.py

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import math
21
from typing import List, Tuple
32

43
import numpy as np
@@ -12,7 +11,7 @@
1211
)
1312
from .ray_tracing import ray_tracing
1413
from .trafo import correct_brown_affine, pixel_to_metric
15-
from .vec_utils import norm, vec_set
14+
from .vec_utils import vec_norm
1615

1716

1817
def multimed_nlay(
@@ -64,9 +63,9 @@ def fast_multimed_r_nlay(
6463
n2: np.ndarray,
6564
n3: float,
6665
d: np.ndarray,
67-
x0,
68-
y0,
69-
z0,
66+
x0: float,
67+
y0: float,
68+
z0: float,
7069
pos: np.ndarray
7170
) -> float:
7271
"""Calculate the radial shift for the multimedia model.
@@ -87,22 +86,23 @@ def fast_multimed_r_nlay(
8786
for i in range(1, nlay):
8887
zout += d[i]
8988

90-
r = norm(X-x0, Y-y0, 0)
89+
90+
r = vec_norm(np.array([X-x0, Y-y0, 0]))
9191
rq = r
9292

9393
it = 0
9494
while (rdiff > 0.001 or rdiff < -0.001) and it < n_iter:
9595
zdiff = z0 - Z
9696
if zdiff == 0:
9797
zdiff = 1.0
98-
beta1 = math.atan(rq / zdiff)
98+
beta1 = np.arctan(rq / zdiff)
9999
for i in range(nlay):
100-
beta2[i] = math.asin(math.sin(beta1) * n1 / n2[i])
101-
beta3 = math.asin(math.sin(beta1) * n1 / n3)
100+
beta2[i] = np.arcsin(np.sin(beta1) * n1 / n2[i])
101+
beta3 = np.arcsin(np.sin(beta1) * n1 / n3)
102102

103-
rbeta = (z0 - d[0]) * math.tan(beta1) - zout * math.tan(beta3)
103+
rbeta = (z0 - d[0]) * np.tan(beta1) - zout * np.tan(beta3)
104104
for i in range(nlay):
105-
rbeta += d[i] * math.tan(beta2[i])
105+
rbeta += d[i] * np.tan(beta2[i])
106106

107107
rdiff = r - rbeta
108108
rq += rdiff
@@ -127,14 +127,14 @@ def trans_cam_point(
127127
128128
pos_t, cross_p, cross_c = trans_cam_point(ex, mm, glass, pos, ex_t)
129129
"""
130-
origin = np.r_[ex.x0, ex.y0, ex.z0]
130+
origin = np.r_[ex.x0, ex.y0, ex.z0] # type: ignore
131131
pos = pos.astype(np.float64)
132132

133133
return fast_trans_cam_point(
134134
origin, mm.d[0], glass_dir, pos)
135135

136136

137-
# @njit(fastmath=True)
137+
@njit(fastmath=True)
138138
def fast_trans_cam_point(
139139
primary_point: np.ndarray,
140140
d: float,
@@ -266,8 +266,8 @@ def init_mmlut(vpar: VolumePar, cpar: ControlPar, cal: Calibration) -> Calibrati
266266
z_min = min(vpar.z_min_lay)
267267
z_max = max(vpar.z_max_lay)
268268

269-
z_min -= math.fmod(z_min, rw)
270-
z_max += rw - math.fmod(z_max, rw)
269+
z_min -= np.fmod(z_min, rw)
270+
z_max += rw - np.fmod(z_max, rw)
271271

272272
z_min_t = z_min
273273
z_max_t = z_max
@@ -292,8 +292,11 @@ def init_mmlut(vpar: VolumePar, cpar: ControlPar, cal: Calibration) -> Calibrati
292292
if xyz_t[2] > z_max_t:
293293
z_max_t = xyz_t[2]
294294

295-
R = norm(xyz_t[0] - cal_t.ext_par.x0,
296-
xyz_t[1] - cal_t.ext_par.y0, 0)
295+
R = vec_norm(
296+
np.r_[xyz_t[0] - cal_t.ext_par.x0,
297+
xyz_t[1] - cal_t.ext_par.y0,
298+
0]
299+
)
297300

298301
if R > Rmax:
299302
Rmax = R
@@ -308,14 +311,14 @@ def init_mmlut(vpar: VolumePar, cpar: ControlPar, cal: Calibration) -> Calibrati
308311
if xyz_t[2] > z_max_t:
309312
z_max_t = xyz_t[2]
310313

311-
R = norm(xyz_t[0] - cal_t.ext_par.x0,
312-
xyz_t[1] - cal_t.ext_par.y0, 0)
314+
R = vec_norm(np.r_[xyz_t[0] - cal_t.ext_par.x0,
315+
xyz_t[1] - cal_t.ext_par.y0, 0])
313316

314317
if R > Rmax:
315318
Rmax = R
316319

317320
# round values (-> enlarge)
318-
Rmax += rw - math.fmod(Rmax, rw)
321+
Rmax += rw - np.fmod(Rmax, rw)
319322

320323
# get # of rasterlines in r, z
321324
nr = int(Rmax / rw + 1)
@@ -334,11 +337,11 @@ def init_mmlut(vpar: VolumePar, cpar: ControlPar, cal: Calibration) -> Calibrati
334337

335338
for i in range(nr):
336339
for j in range(nz):
337-
xyz = vec_set(Ri[i] + cal_t.ext_par.x0,
338-
cal_t.ext_par.y0, Zi[j])
340+
xyz = np.r_[Ri[i] + cal_t.ext_par.x0,
341+
cal_t.ext_par.y0, Zi[j]]
339342
data.flat[i * nz + j] = multimed_r_nlay(cal_t, cpar.mm, xyz)
340343

341-
print("filled mmlut data with {data}")
344+
# print(f"filled mmlut data with {data}")
342345
cal.mmlut.data = data
343346

344347
return cal

openptv_python/orientation.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -162,15 +162,15 @@ def num_deriv_exterior(
162162
steps = [dpos, dpos, dpos, dang, dang, dang]
163163

164164
# print(f"exterior = {cal.ext_par}")
165-
cal.ext_par.update_rotation_matrix()
165+
cal.update_rotation_matrix()
166166
xs, ys = img_coord(pos, cal, cpar.mm)
167167
# print(f" xs = {xs}, ys = {ys}")
168168

169169
for pd in range(6):
170-
cal.ext_par.increment_attribute(var[pd], steps[pd])
170+
cal.increment_attribute(var[pd], steps[pd])
171171
# print(f"exterior = {cal.ext_par}")
172172
if pd > 2:
173-
cal.ext_par.update_rotation_matrix()
173+
cal.update_rotation_matrix()
174174

175175
xpd, ypd = img_coord(pos, cal, cpar.mm)
176176
# print(f" xpd = {xpd}, ypd = {ypd}")
@@ -179,10 +179,10 @@ def num_deriv_exterior(
179179

180180
# print(f" x_ders[{pd}] = {x_ders[pd]}, y_ders[{pd}] = {y_ders[pd]}")
181181

182-
cal.ext_par.increment_attribute(var[pd], -steps[pd])
182+
cal.increment_attribute(var[pd], -steps[pd])
183183
# print(f"exterior = {cal.ext_par}")
184184

185-
cal.ext_par.update_rotation_matrix()
185+
cal.update_rotation_matrix()
186186

187187
return (x_ders, y_ders)
188188

@@ -335,7 +335,7 @@ def orient(
335335
xc, yc = correct_brown_affine(xc, yc, cal.added_par)
336336

337337
# Projected 2D position on sensor of corresponding known point
338-
cal.ext_par.update_rotation_matrix()
338+
cal.update_rotation_matrix()
339339
xp, yp = img_coord(fix[i], cal, cpar.mm)
340340

341341
# derivatives of distortion parameters
@@ -382,7 +382,7 @@ def orient(
382382

383383
# Num. deriv. of projection coords over sensor distance from PP
384384
cal.int_par.cc += dm
385-
cal.ext_par.update_rotation_matrix()
385+
cal.update_rotation_matrix()
386386
xpd, ypd = img_coord(fix[i], cal, cpar.mm)
387387
X[n][6] = (xpd - xp) / dm
388388
X[n + 1][6] = ypd - yp
@@ -571,7 +571,7 @@ def orient(
571571
sigmabeta[i] = sigmabeta[NPAR] * np.sqrt(XPX[i][i])
572572

573573
if stopflag:
574-
cal.ext_par.update_rotation_matrix()
574+
cal.update_rotation_matrix()
575575
return resi
576576
else:
577577
return None
@@ -611,7 +611,7 @@ def raw_orient(
611611
for i in range(nfix):
612612
xc, yc = pixel_to_metric(pix[i].x, pix[i].y, cpar)
613613
pos = fix[i]
614-
cal.ext_par.update_rotation_matrix()
614+
cal.update_rotation_matrix()
615615
xp, yp = img_coord(pos, cal, cpar.mm)
616616
X[n], X[n + 1] = num_deriv_exterior(cal, cpar, dm, drad, pos)
617617
y[n] = xc - xp
@@ -651,7 +651,7 @@ def raw_orient(
651651
cal.ext_par.kappa += beta[5]
652652

653653
if stopflag:
654-
cal.ext_par.update_rotation_matrix()
654+
cal.update_rotation_matrix()
655655

656656
return stopflag
657657

tests/test_corresp.py

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -468,40 +468,3 @@ def test_four_camera_matching(self):
468468

469469
# Assert that 16 triplets were matched.
470470
self.assertEqual(matched, 16)
471-
472-
473-
class TestSafelyAllocateAdjacencyLists(unittest.TestCase):
474-
"""Test the safely_allocate_adjacency_lists function."""
475-
476-
def test_correct_list_size(self):
477-
"""Test that the adjacency lists are correctly sized."""
478-
num_cams = 5
479-
target_counts = [3, 5, 2, 4, 1]
480-
lists = safely_allocate_adjacency_lists(num_cams, target_counts)
481-
self.assertEqual(len(lists), num_cams)
482-
for i in range(num_cams):
483-
self.assertEqual(len(lists[i]), num_cams)
484-
for j in range(num_cams):
485-
if i < j:
486-
self.assertTrue(len(lists[i][j]) >= target_counts[i]) # recarray is one length
487-
488-
def test_memory_error(self):
489-
"""Memory stress test."""
490-
# available_memory = 8GB = 8 * 1024 * 1024 * 1024 bytes
491-
# overhead = 200MB = 200 * 1024 * 1024 bytes
492-
# item_size = 4 bytes (for integers)
493-
494-
# max_items = (8 * 1024 * 1024 * 1024 - 200 * 1024 * 1024) // 4 = 1,995,116,800
495-
496-
num_cams = 4
497-
target_counts = [1000, 1000, 1000, 1000]
498-
# with self.assertRaises(MemoryError):
499-
_ = safely_allocate_adjacency_lists(num_cams, target_counts)
500-
501-
# target_counts = [int(1e3), int(1e3), int(1e3), int(1e10)]
502-
# with self.assertRaises(MemoryError):
503-
# safely_allocate_adjacency_lists(num_cams, target_counts)
504-
505-
506-
if __name__ == "__main__":
507-
unittest.main()

tests/test_epipolar.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,10 @@ def test_two_cameras(self):
8686

8787
def test_epi_mm_2D(self):
8888
"""Test the epi_mm_2D function."""
89-
test_Ex = Exterior(0.0, 0.0, 100.0, 0.0, 0.0, 0.0)
89+
test_Ex = Exterior.copy()
90+
test_Ex.z0 = 100.0
91+
92+
9093
test_I = Interior(0.0, 0.0, 100.0)
9194
test_G = np.array((0.0, 0.0, 50.0))
9295
test_addp = ap_52(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
@@ -124,13 +127,20 @@ def test_epi_mm_2D(self):
124127

125128
def test_epi_mm(self):
126129
"""Test the epi_mm function."""
127-
test_Ex = Exterior(10.0, 0.0, 100.0, 0.0, -0.01, 0.0)
130+
test_Ex = Exterior.copy()
131+
test_Ex.x0 = 10.0
132+
test_Ex.z0 = 100.0
133+
test_Ex.phi = -.01
134+
128135
test_I = Interior(0.0, 0.0, 100.0)
129136
test_G = np.array((0.0, 0.0, 50.0))
130137
test_addp = ap_52(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
131138
test_cal_1 = Calibration(test_Ex, test_I, test_G, test_addp)
132139

133-
test_Ex_2 = Exterior(-10.0, 0.0, 100.0, 0.0, 0.01, 0.0)
140+
test_Ex_2 = Exterior.copy()
141+
test_Ex_2.x0 = -10.0
142+
test_Ex_2.z0 = 100.0
143+
test_Ex_2.phi = .01
134144
test_cal_2 = Calibration(test_Ex_2, test_I, test_G, test_addp)
135145

136146
test_mm = MultimediaPar(1, 1.0, [1.49, 0.0, 0.0], [
@@ -155,13 +165,16 @@ def test_epi_mm(self):
155165

156166
def test_epi_mm_perpendicular(self):
157167
"""Test the epi_mm function."""
158-
test_Ex = Exterior(0.0, 0.0, 100.0, 0.0, 0.0, 0.0)
168+
test_Ex = Exterior.copy()
169+
test_Ex.z0 = 100.0
159170
test_I = Interior(0.0, 0.0, 100.0)
160171
test_G = np.array((0.0, 0.0, 50.0))
161172
test_addp = ap_52(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
162173
test_cal_1 = Calibration(test_Ex, test_I, test_G, test_addp)
163174

164-
test_Ex_2 = Exterior(100.0, 0.0, 0.0, 0.0, 1.57, 0.0)
175+
test_Ex_2 = Exterior.copy()
176+
test_Ex_2.x0 = 100.0
177+
test_Ex_2.phi = 1.57
165178
test_cal_2 = Calibration(test_Ex_2, test_I, test_G, test_addp)
166179

167180
test_mm = MultimediaPar(1, 1.0, [1.0, 0.0, 0.0], [1.0, 0.0, 0.0], 1.0)
@@ -232,7 +245,9 @@ def test_find_candidate(self):
232245
ny = 3
233246
sumg = 100
234247

235-
test_Ex = Exterior(0.0, 0.0, 100.0, 0.0, 0.0, 0.0)
248+
test_Ex = Exterior.copy()
249+
test_Ex.z0 = 100.
250+
236251
test_I = Interior(0.0, 0.0, 100.0)
237252
test_G = np.array((0.0, 0.0, 50.0))
238253
test_addp = ap_52(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)

tests/test_imgcoord.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ def test_flat_centered_cam(self):
2020
# gleaned from simple geometry.
2121
pos = vec_set(10, 5, -20)
2222
cal = Calibration(
23-
ext_par=Exterior(0, 0, 40, 0, 0, 0, [[1, 0, 0], [0, 1, 0], [0, 0, 1]]),
23+
ext_par = np.array((0, 0, 40, 0, 0, 0,
24+
[[1, 0, 0], [0, 1, 0], [0, 0, 1]]),
25+
dtype = Exterior.dtype).view(np.recarray),
2426
int_par=Interior(0, 0, 10),
2527
glass_par=np.array((0., 0., 20.)),
2628
added_par=ap_52(0, 0, 0, 0, 0, 1, 0),

0 commit comments

Comments
 (0)