Skip to content

Commit 27fbcaf

Browse files
committed
removed classes and set calibration as numpy arrays
1 parent 9146a0b commit 27fbcaf

19 files changed

Lines changed: 374 additions & 162 deletions

openptv_python/calibration.py

Lines changed: 35 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ 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
6261
Exterior = np.array((0, 0, 0, 0, 0, 0, np.eye(3)), dtype = exterior_dtype).view(np.recarray)
6362
rotation_matrix(Exterior) # rotation should be a unit matrix
6463
assert np.allclose(np.eye(3), Exterior['dm'])
@@ -70,13 +69,6 @@ def rotation_matrix(ext: np.ndarray) -> None:
7069
])
7170
Interior = np.array( (0, 0, 0), dtype = interior_dtype).view(np.recarray)
7271

73-
# def set_primary_point(point: np.ndarray) -> None:
74-
# """Set the primary point of the camera."""
75-
# self.xh, self.yh, self.cc = point
76-
77-
# def set_back_focal_distance(self, cc: float) -> None:
78-
# """Set the back focal distance of the camera."""
79-
# self.cc = cc
8072

8173
ap52_dtype = np.dtype([
8274
('k1', np.float64),
@@ -89,60 +81,27 @@ def rotation_matrix(ext: np.ndarray) -> None:
8981
])
9082
ap_52 = np.array((0, 0, 0, 0, 0, 1, 0), dtype = ap52_dtype).view(np.recarray)
9183

92-
93-
# class ap_52:
94-
# """Additional parameters for distortion correction."""
95-
96-
# def __init__(self, k1=0.0, k2=0.0, k3=0.0, p1=0.0, p2=0.0, scx=1.0, she=0.0):
97-
# self.k1 = k1
98-
# self.k2 = k2
99-
# self.k3 = k3
100-
# self.p1 = p1
101-
# self.p2 = p2
102-
# self.scx = scx
103-
# self.she = she
104-
105-
# def set_radial_distortion(self, dist_array: np.ndarray) -> None:
106-
# """Set the radial distortion parameters k1, k2, k3."""
107-
# self.k1, self.k2, self.k3 = dist_array
108-
109-
# def set_decentering(self, decent: np.ndarray) -> None:
110-
# """Set the decentring parameters p1 and p2."""
111-
# self.p1, self.p2 = decent
112-
113-
# def set_affine_distortion(self, affine: np.ndarray) -> None:
114-
# """Set the affine distortion parameters scx and she."""
115-
# self.scx, self.she = affine
116-
11784
mmlut_dtype = np.dtype([
11885
('origin', np.float64, 3),
11986
('nr', np.int32),
12087
('nz', np.int32),
12188
('rw', np.int32),
122-
('data', np.float64, (3, 3))
12389
])
12490

125-
mm_lut = np.array((np.zeros(3), 0, 0, 0, np.zeros((3, 3))), dtype = mmlut_dtype).view(np.recarray)
126-
127-
# class mm_lut:
128-
# """Multimedia lookup table data structure."""
129-
130-
# def __init__(self, origin=None, nr=3, nz=3, rw=0, data=None):
131-
# if origin is None:
132-
# origin = np.zeros(3, dtype=np.float32)
133-
# # if data is None:
134-
# # data = np.zeros((nr, nz), dtype=np.float32) # Assuming data is a 2D array, adjust as needed
135-
# self.origin = origin
136-
# self.nr = nr
137-
# self.nz = nz
138-
# self.rw = rw
139-
# self.data = data
91+
mm_lut = np.array((np.zeros(3), 0, 0, 0), dtype = mmlut_dtype).view(np.recarray)
92+
mm_lut_data = np.empty((mm_lut['nr'], mm_lut['nz']), dtype=np.float64)
14093

14194

14295
class Calibration:
14396
"""Calibration data structure."""
14497

145-
def __init__(self, ext_par=None, int_par=None, glass_par=None, added_par=None, mmlut=None):
98+
def __init__(self,
99+
ext_par=None,
100+
int_par=None,
101+
glass_par=None,
102+
added_par=None,
103+
mmlut=None,
104+
mmlut_data=None):
146105
if ext_par is None:
147106
ext_par = Exterior.copy()
148107
if int_par is None:
@@ -152,13 +111,17 @@ def __init__(self, ext_par=None, int_par=None, glass_par=None, added_par=None, m
152111
if added_par is None:
153112
added_par = ap_52.copy()
154113
if mmlut is None:
155-
mmlut = mm_lut.copy() # (np.zeros(3), 0, 0, 0, None)
114+
mmlut = mm_lut.copy() # (np.zeros(3), 0, 0, 0)
115+
if mmlut_data is None:
116+
mmlut_data = np.zeros((mmlut.nr, mmlut.nz), dtype=np.float64)
117+
156118

157119
self.ext_par = ext_par
158120
self.int_par = int_par
159121
self.glass_par = glass_par
160122
self.added_par = added_par
161123
self.mmlut = mmlut
124+
self.mmlut_data = mmlut_data
162125

163126

164127
@classmethod
@@ -205,7 +168,7 @@ def from_file(cls, ori_file: str, add_file: str):
205168

206169
tmp = [float(x) for x in fp.readline().split()] # xh,yh
207170
tmp += [float(x) for x in fp.readline().split()] # cc
208-
ret.int_par.set_primary_point(np.array(tmp))
171+
ret.set_primary_point(np.array(tmp))
209172
# self.int_par.set_back_focal_distance(float(fp.readline()))
210173

211174
# Glass
@@ -224,9 +187,9 @@ def from_file(cls, ori_file: str, add_file: str):
224187
with open(add_file, "r", encoding="utf-8") as fp:
225188
tmp = list(map(float, fp.readline().split()))
226189

227-
ret.added_par.set_radial_distortion(np.array(tmp[:3]))
228-
ret.added_par.set_decentering(np.array(tmp[3:5]))
229-
ret.added_par.set_affine_distortion(np.array(tmp[5:]))
190+
ret.set_radial_distortion(np.array(tmp[:3]))
191+
ret.set_decentering(np.array(tmp[3:5]))
192+
ret.set_affine_distortion(np.array(tmp[5:]))
230193

231194
except FileNotFoundError:
232195
print("no addpar fallback used") # Waits for proper logging.
@@ -324,10 +287,11 @@ def set_primary_point(self, prim_point_pos: np.ndarray) -> None:
324287
of point from sensor middle and sensor-point distance, int_par this
325288
order.
326289
"""
327-
if len(prim_point_pos) != 3:
328-
raise ValueError("Expected a 3-element list")
290+
if prim_point_pos.shape != (3,):
291+
raise ValueError("Expected a 3-element array")
329292

330-
self.int_par.set_primary_point(prim_point_pos)
293+
self.int_par.xh, self.int_par.yh, self.int_par.cc = prim_point_pos
294+
# self.int_par.set_primary_point(prim_point_pos)
331295

332296
def get_primary_point(self):
333297
"""
@@ -349,10 +313,11 @@ def set_radial_distortion(self, dist_coeffs: np.ndarray) -> None:
349313
---------
350314
dist_coeffs - length-3 array, holding k_i.
351315
"""
352-
if len(dist_coeffs) != 3:
316+
if dist_coeffs.shape != (3,):
353317
raise ValueError("Expected a 3-element array")
354318

355-
self.added_par.set_radial_distortion(dist_coeffs)
319+
self.added_par.k1, self.added_par.k2, self.added_par.k3 = dist_coeffs
320+
356321

357322
def get_radial_distortion(self):
358323
"""
@@ -370,29 +335,27 @@ def set_decentering(self, decent: np.ndarray) -> None:
370335
---------
371336
decent - array, holding p_i
372337
"""
373-
if len(decent) != 2:
338+
if decent.shape != (2,):
374339
raise ValueError("Expected a 2-element list")
375340

376-
self.added_par.set_decentering(decent)
341+
self.added_par.p1, self.added_par.p2 = decent
377342

378343
def get_decentering(self):
379344
"""Return the decentering parameters [1] as a 2 element array, (p_1, p_2)."""
380-
ret = np.empty(2)
381-
ret[0] = self.added_par.p1
382-
ret[1] = self.added_par.p2
383-
return ret
345+
return np.r_[self.added_par.p1, self.added_par.p2]
384346

385-
def set_affine_trans(self, affine: np.ndarray) -> None:
347+
def set_affine_distortion(self, affine: np.ndarray) -> None:
386348
"""
387349
Set the affine transform parameters (x-scale, shear) of the image.
388350
389351
Arguments:
390352
---------
391353
affine - array, holding (x-scale, shear) int_par order.
392354
"""
393-
if len(affine) != 2:
355+
if affine.shape != (2,):
394356
raise ValueError("Expected a 2-element list")
395-
self.added_par.set_affine_distortion(affine)
357+
358+
self.added_par.scx, self.added_par.she = affine
396359

397360
def get_affine(self):
398361
"""Return the affine transform parameters [1] as a 2 element array, (scx, she)."""
@@ -419,9 +382,9 @@ def get_glass_vec(self) -> np.ndarray:
419382
"""Return the glass vector, a 3-element array of float."""
420383
return self.glass_par
421384

422-
def set_added_par(self, listpar: np.ndarray | list):
385+
def set_added_par(self, ap52_array: np.ndarray):
423386
"""Set added par from an numpy array of parameters."""
424-
self.added_par = np.array(listpar, dtype=ap52_dtype).view(np.recarray)
387+
self.added_par = np.array(tuple(ap52_array.tolist()), dtype = ap52_dtype).view(np.recarray)
425388

426389
def copy(self, new_copy):
427390
"""Copy the calibration data to a new object."""
@@ -486,7 +449,7 @@ def read_ori(ori_file: str, add_file: str) -> Calibration:
486449
return ret
487450

488451

489-
def compare_exterior(e1: np.ndarray, e2: np.ndarray) -> bool:
452+
def compare_exterior(e1: np.recarray, e2: np.recarray) -> bool:
490453
"""Compare exterior orientation parameters."""
491454
return (
492455
np.allclose(e1['dm'], e2['dm'], atol=1e-6)

openptv_python/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,4 @@
2929

3030
NUM_ITER = 80
3131
POS_INF = 1e20
32-
CONVERGENCE = 0.00001
32+
CONVERGENCE = 0.0001

openptv_python/multimed.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def multimed_r_nlay(cal: Calibration, mm: MultimediaPar, pos: np.ndarray) -> flo
3434
return 1.0
3535

3636
# interpolation using the existing mmlut
37-
if cal.mmlut.data is not None:
37+
if cal.mmlut_data.shape != (0, 0):
3838
# print("going into get_mmf_from_mmlut\n")
3939
mmf = get_mmf_from_mmlut(cal, pos)
4040
if mmf > 0:
@@ -273,7 +273,7 @@ def init_mmlut(vpar: VolumePar, cpar: ControlPar, cal: Calibration) -> Calibrati
273273
z_max_t = z_max
274274

275275
# intersect with image vertices rays
276-
cal_t = Calibration(mmlut=cal.mmlut)
276+
cal_t = Calibration(mmlut = cal.mmlut.copy())
277277

278278
for i in range(2):
279279
for j in range(2):
@@ -330,19 +330,19 @@ def init_mmlut(vpar: VolumePar, cpar: ControlPar, cal: Calibration) -> Calibrati
330330
cal.mmlut.nz = nz
331331
cal.mmlut.rw = rw
332332

333-
if cal.mmlut.data is None:
334-
data = np.empty((nr, nz), dtype=np.float64)
333+
if cal.mmlut_data.shape == (0, 0):
334+
cal.mmlut_data = np.empty((nr, nz), dtype=np.float64)
335335
Ri = np.arange(nr) * rw
336336
Zi = np.arange(nz) * rw + z_min_t
337337

338338
for i in range(nr):
339339
for j in range(nz):
340340
xyz = np.r_[Ri[i] + cal_t.ext_par.x0,
341341
cal_t.ext_par.y0, Zi[j]]
342-
data.flat[i * nz + j] = multimed_r_nlay(cal_t, cpar.mm, xyz)
342+
cal.mmlut_data.flat[i * nz + j] = multimed_r_nlay(cal_t, cpar.mm, xyz)
343343

344344
# print(f"filled mmlut data with {data}")
345-
cal.mmlut.data = data
345+
# cal.mmlut_data = data
346346

347347
return cal
348348

@@ -351,15 +351,13 @@ def get_mmf_from_mmlut(cal: Calibration, pos: np.ndarray) -> float:
351351
"""Get the refractive index of the medium at a given position."""
352352
rw = cal.mmlut.rw
353353
origin = cal.mmlut.origin
354-
data = cal.mmlut.data.flatten() # type: ignore
354+
data = cal.mmlut_data.flatten() # type: ignore
355355
nz = cal.mmlut.nz
356356
nr = cal.mmlut.nr
357357

358358
return fast_get_mmf_from_mmlut(rw, origin, data, nz, nr, pos)
359359

360360
# @njit
361-
362-
363361
def fast_get_mmf_from_mmlut(
364362
rw: int,
365363
origin: np.ndarray,

openptv_python/orientation.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -489,13 +489,13 @@ def orient(
489489
)
490490

491491
# Interpret the results
492-
print(
493-
f"Coefficients (beta): {beta} \n \
494-
Residuals: {residuals} \n \
495-
singular_values: {singular_values} \n \
496-
rank: {rank} \n \
497-
"
498-
)
492+
# print(
493+
# f"Coefficients (beta): {beta} \n \
494+
# Residuals: {residuals} \n \
495+
# singular_values: {singular_values} \n \
496+
# rank: {rank} \n \
497+
# "
498+
# )
499499

500500
# stopflag
501501
stopflag = True

openptv_python/parameters.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -714,9 +714,10 @@ class OrientPar(Parameters):
714714
@classmethod
715715
def from_file(cls, filename: str):
716716
"""Read orientation parameters from file and returns orient_par object."""
717+
ret = cls()
717718
try:
718719
with open(filename, "r", encoding="utf-8") as file:
719-
ret = cls()
720+
720721
ret.useflag = int(file.readline().strip()) # /* use every point or every other pt */
721722
ret.ccflag = int(file.readline().strip()) # /* change back focal distance */
722723
ret.xhflag = int(file.readline().strip()) # /* change xh point, 1-yes, 0-no */
@@ -729,10 +730,11 @@ def from_file(cls, filename: str):
729730
ret.scxflag = int(file.readline().strip()) # /* scx - scaling */
730731
ret.sheflag = int(file.readline().strip()) # /* she - shearing */
731732
ret.interfflag = int(file.readline().strip()) # /* interface glass vector */
732-
return ret
733+
733734
except IOError:
734735
print(f"Could not open orientation parameters file {filename}.")
735-
return None
736+
737+
return ret
736738

737739

738740

openptv_python/trafo.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from numba import float64, int32, njit
66
from numpy import cos, sin, sqrt
77

8-
from .calibration import Calibration, ap_52
8+
from .calibration import Calibration
99
from .parameters import ControlPar
1010

1111

@@ -147,7 +147,7 @@ def fast_arr_metric_to_pixel(
147147

148148
def distort_brown_affine(x: float,
149149
y: float,
150-
ap: ap_52
150+
ap: np.recarray,
151151
) -> Tuple[float, float]:
152152
"""Distort a point using the Brown affine model."""
153153
if x == 0 and y == 0:
@@ -160,7 +160,9 @@ def distort_brown_affine(x: float,
160160
# print(f"x {x}, y {y}")
161161

162162

163-
@njit(float64[:](float64,float64,float64,float64,float64,float64,float64,float64,float64))
163+
# @njit(float64[:]
164+
# (float64,float64,float64,float64,float64,
165+
# float64,float64,float64,float64))
164166
def fast_distort_brown_affine(
165167
x: float,
166168
y: float,
@@ -198,7 +200,7 @@ def fast_distort_brown_affine(
198200

199201

200202
def correct_brown_affine(
201-
x: float, y: float, ap: ap_52, tol: float = 1e-5
203+
x: float, y: float, ap: np.recarray, tol: float = 1e-5
202204
) -> Tuple[float, float]:
203205
"""Correct a distorted point using the Brown affine model."""
204206
return fast_correct_brown_affine(x, y, ap.k1, ap.k2, ap.k3, ap.p1, ap.p2, ap.she, ap.scx, tol)

0 commit comments

Comments
 (0)