Skip to content

Commit a83f499

Browse files
authored
Merge pull request #5 from OpenPTV/test_optimize_calibration
Test optimize calibration
2 parents 15ae103 + d843745 commit a83f499

7 files changed

Lines changed: 6239 additions & 140 deletions

File tree

openptv_python/calibration.py

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,17 @@ def rotation_matrix(ext: np.ndarray) -> None:
7070
Interior = np.array( (0, 0, 0), dtype = interior_dtype).view(np.recarray)
7171

7272

73-
ap52_dtype = np.dtype([
74-
('k1', np.float64),
75-
('k2', np.float64),
76-
('k3', np.float64),
77-
('p1', np.float64),
78-
('p2', np.float64),
79-
('scx', np.float64),
80-
('she', np.float64)
81-
])
82-
ap_52 = np.array((0, 0, 0, 0, 0, 1, 0), dtype = ap52_dtype).view(np.recarray)
73+
# ap52_dtype = np.dtype([
74+
# ('k1', np.float64),
75+
# ('k2', np.float64),
76+
# ('k3', np.float64),
77+
# ('p1', np.float64),
78+
# ('p2', np.float64),
79+
# ('scx', np.float64),
80+
# ('she', np.float64)
81+
# ])
82+
ap_52 = np.array((0, 0, 0, 0, 0, 1, 0), dtype = np.float64)
83+
# ap_52 = np.array((0, 0, 0, 0, 0, 1, 0), dtype = ap52_dtype).view(np.recarray)
8384

8485
mmlut_dtype = np.dtype([
8586
('origin', np.float64, 3),
@@ -177,9 +178,10 @@ def from_file(cls, ori_file: str, add_file: str | None):
177178
else:
178179
# print("no addpar fallback used") # Waits for proper logging.
179180
print("No addpar file found. Using default values for radial distortion")
180-
ret.added_par.k1 = ret.added_par.k2 = ret.added_par.k3 \
181-
= ret.added_par.p1 = ret.added_par.p2 = ret.added_par.she = 0.0
182-
ret.added_par.scx = 1.0
181+
# ret.added_par.k1 = ret.added_par.k2 = ret.added_par.k3 \
182+
# = ret.added_par.p1 = ret.added_par.p2 = ret.added_par.she = 0.0
183+
# ret.added_par.scx = 1.0
184+
ret.added_par = np.array([0,0,0,0,0,1,0], dtype=np.float64)
183185

184186
return ret
185187
# print(f"Calibration data read from files {ori_file} and {add_file}")
@@ -300,7 +302,9 @@ def set_radial_distortion(self, dist_coeffs: np.ndarray) -> None:
300302
if dist_coeffs.shape != (3,):
301303
raise ValueError("Expected a 3-element array")
302304

303-
self.added_par.k1, self.added_par.k2, self.added_par.k3 = dist_coeffs
305+
self.added_par[:3] = dist_coeffs
306+
307+
# self.added_par.k1, self.added_par.k2, self.added_par.k3 = dist_coeffs
304308

305309

306310
def get_radial_distortion(self):
@@ -309,7 +313,8 @@ def get_radial_distortion(self):
309313
310314
array, from lowest power to highest.
311315
"""
312-
return np.r_[self.added_par.k1, self.added_par.k2, self.added_par.k3]
316+
# return np.r_[self.added_par.k1, self.added_par.k2, self.added_par.k3]
317+
return self.added_par[:3]
313318

314319
def set_decentering(self, decent: np.ndarray) -> None:
315320
"""
@@ -322,11 +327,13 @@ def set_decentering(self, decent: np.ndarray) -> None:
322327
if decent.shape != (2,):
323328
raise ValueError("Expected a 2-element list")
324329

325-
self.added_par.p1, self.added_par.p2 = decent
330+
# self.added_par.p1, self.added_par.p2 = decent
331+
self.added_par[3:5] = decent
326332

327333
def get_decentering(self):
328334
"""Return the decentering parameters [1] as a 2 element array, (p_1, p_2)."""
329-
return np.r_[self.added_par.p1, self.added_par.p2]
335+
# return np.r_[self.added_par.p1, self.added_par.p2]
336+
return self.added_par[3:5]
330337

331338
def set_affine_distortion(self, affine: np.ndarray) -> None:
332339
"""
@@ -339,11 +346,13 @@ def set_affine_distortion(self, affine: np.ndarray) -> None:
339346
if affine.shape != (2,):
340347
raise ValueError("Expected a 2-element list")
341348

342-
self.added_par.scx, self.added_par.she = affine
349+
# self.added_par.scx, self.added_par.she = affine
350+
self.added_par[5:] = affine
343351

344352
def get_affine(self):
345353
"""Return the affine transform parameters [1] as a 2 element array, (scx, she)."""
346-
return np.r_[self.added_par.scx, self.added_par.she]
354+
# return np.r_[self.added_par.scx, self.added_par.she]
355+
return self.added_par[5:]
347356

348357
def set_glass_vec(self, gvec: np.ndarray):
349358
"""
@@ -368,7 +377,8 @@ def get_glass_vec(self) -> np.ndarray:
368377

369378
def set_added_par(self, ap52_array: np.ndarray):
370379
"""Set added par from an numpy array of parameters."""
371-
self.added_par = np.array(tuple(ap52_array.tolist()), dtype = ap52_dtype).view(np.recarray)
380+
# self.added_par = np.array(tuple(ap52_array.tolist()), dtype = ap52_dtype).view(np.recarray)
381+
self.added_par = ap52_array
372382

373383
def copy(self, new_copy):
374384
"""Copy the calibration data to a new object."""

openptv_python/orientation.py

Lines changed: 58 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from .parameters import ControlPar, MultimediaPar, OrientPar, VolumePar
1717
from .ray_tracing import ray_tracing
1818
from .sortgrid import sortgrid
19-
from .tracking_frame_buf import Target, TargetArray
19+
from .tracking_frame_buf import Target
2020
from .trafo import correct_brown_affine, pixel_to_metric
2121
from .vec_utils import unit_vector, vec_norm, vec_set
2222

@@ -301,14 +301,14 @@ def orient(
301301
cal.int_par.cc,
302302
cal.int_par.xh,
303303
cal.int_par.yh,
304-
cal.added_par.k1,
305-
cal.added_par.k2,
306-
cal.added_par.k3,
307-
cal.added_par.p1,
308-
cal.added_par.p2,
309-
cal.added_par.scx,
310-
cal.added_par.she,
311-
]
304+
cal.added_par[0],
305+
cal.added_par[1],
306+
cal.added_par[2],
307+
cal.added_par[3],
308+
cal.added_par[4],
309+
cal.added_par[5],
310+
cal.added_par[6]
311+
]
312312

313313
# backup for changing back and forth
314314
safety_x = cal.glass_par[0]
@@ -343,40 +343,40 @@ def orient(
343343
# derivatives of distortion parameters
344344
r = np.sqrt(xp * xp + yp * yp)
345345

346-
X[n][7] = cal.added_par.scx
347-
X[n + 1][7] = np.sin(cal.added_par.she)
346+
X[n][7] = cal.added_par[5] # cal.added_par[5]
347+
X[n + 1][7] = np.sin(cal.added_par[6]) #np.sin(cal.added_par[6])
348348

349349
X[n][8] = 0
350350
X[n + 1][8] = 1
351351

352-
X[n][9] = cal.added_par.scx * xp * r * r
352+
X[n][9] = cal.added_par[5] * xp * r * r
353353
X[n + 1][9] = yp * r * r
354354

355-
X[n][10] = cal.added_par.scx * xp * pow(r, 4)
355+
X[n][10] = cal.added_par[5] * xp * pow(r, 4)
356356
X[n + 1][10] = yp * pow(r, 4)
357357

358-
X[n][11] = cal.added_par.scx * xp * pow(r, 6)
358+
X[n][11] = cal.added_par[5] * xp * pow(r, 6)
359359
X[n + 1][11] = yp * pow(r, 6)
360360

361-
X[n][12] = cal.added_par.scx * (2 * xp * xp + r * r)
361+
X[n][12] = cal.added_par[5] * (2 * xp * xp + r * r)
362362
X[n + 1][12] = 2 * xp * yp
363363

364-
X[n][13] = 2 * cal.added_par.scx * xp * yp
364+
X[n][13] = 2 * cal.added_par[5] * xp * yp
365365
X[n + 1][13] = 2 * yp * yp + r * r
366366

367-
qq = cal.added_par.k1 * r * r
368-
qq += cal.added_par.k2 * pow(r, 4)
369-
qq += cal.added_par.k3 * pow(r, 6)
367+
qq = cal.added_par[0] * r * r
368+
qq += cal.added_par[1] * pow(r, 4)
369+
qq += cal.added_par[2] * pow(r, 6)
370370
qq += 1
371371
X[n][14] = (
372372
xp * qq
373-
+ cal.added_par.p1 * (r * r + 2 * xp * xp)
374-
+ 2 * cal.added_par.p2 * xp * yp
373+
+ cal.added_par[3] * (r * r + 2 * xp * xp)
374+
+ 2 * cal.added_par[4] * xp * yp
375375
)
376376
X[n + 1][14] = 0
377377

378-
X[n][15] = -np.cos(cal.added_par.she) * yp
379-
X[n + 1][15] = -np.sin(cal.added_par.she) * yp
378+
X[n][15] = -np.cos(cal.added_par[6]) * yp
379+
X[n + 1][15] = -np.sin(cal.added_par[6]) * yp
380380

381381
# numeric derivatives of projection coordinates over external parameters,
382382
# 3D position and the angles
@@ -449,13 +449,13 @@ def orient(
449449
y[n_obs + 0] = ident[0] - cal.int_par.cc
450450
y[n_obs + 1] = ident[1] - cal.int_par.xh
451451
y[n_obs + 2] = ident[2] - cal.int_par.yh
452-
y[n_obs + 3] = ident[3] - cal.added_par.k1
453-
y[n_obs + 4] = ident[4] - cal.added_par.k2
454-
y[n_obs + 5] = ident[5] - cal.added_par.k3
455-
y[n_obs + 6] = ident[6] - cal.added_par.p1
456-
y[n_obs + 7] = ident[7] - cal.added_par.p2
457-
y[n_obs + 8] = ident[8] - cal.added_par.scx
458-
y[n_obs + 9] = ident[9] - cal.added_par.she
452+
y[n_obs + 3] = ident[3] - cal.added_par[0]
453+
y[n_obs + 4] = ident[4] - cal.added_par[1]
454+
y[n_obs + 5] = ident[5] - cal.added_par[2]
455+
y[n_obs + 6] = ident[6] - cal.added_par[3]
456+
y[n_obs + 7] = ident[7] - cal.added_par[4]
457+
y[n_obs + 8] = ident[8] - cal.added_par[5]
458+
y[n_obs + 9] = ident[9] - cal.added_par[6]
459459

460460
# weights
461461
for i in range(n_obs):
@@ -540,13 +540,13 @@ def orient(
540540
cal.int_par.cc += beta[6]
541541
cal.int_par.xh += beta[7]
542542
cal.int_par.yh += beta[8]
543-
cal.added_par.k1 += beta[9]
544-
cal.added_par.k2 += beta[10]
545-
cal.added_par.k3 += beta[11]
546-
cal.added_par.p1 += beta[12]
547-
cal.added_par.p2 += beta[13]
548-
cal.added_par.scx += beta[14]
549-
cal.added_par.she += beta[15]
543+
cal.added_par[0] += beta[9]
544+
cal.added_par[1] += beta[10]
545+
cal.added_par[2] += beta[11]
546+
cal.added_par[3] += beta[12]
547+
cal.added_par[4] += beta[13]
548+
cal.added_par[5] += beta[14]
549+
cal.added_par[6] += beta[15]
550550

551551
if flags.interfflag:
552552
cal.glass_par[0] += e1[0] * nGl * beta[16]
@@ -606,14 +606,14 @@ def raw_orient(
606606
beta = np.zeros(6)
607607
pos = np.zeros(3)
608608

609-
cal.added_par.k1 = 0
610-
cal.added_par.k2 = 0
611-
cal.added_par.k3 = 0
612-
cal.added_par.p1 = 0
613-
cal.added_par.p2 = 0
614-
cal.added_par.scx = 1
615-
cal.added_par.she = 0
616-
609+
# cal.added_par[0] = 0
610+
# cal.added_par[1] = 0
611+
# cal.added_par[2] = 0
612+
# cal.added_par[3] = 0
613+
# cal.added_par[4] = 0
614+
# cal.added_par[5] = 1
615+
# cal.added_par[6] = 0
616+
cal.added_par = np.array([0, 0, 0, 0, 0, 1, 0], dtype=np.float64)
617617
itnum = 0
618618
stopflag = False
619619

@@ -787,7 +787,7 @@ def external_calibration(
787787
def full_calibration(
788788
cal: Calibration,
789789
ref_pts: np.ndarray,
790-
img_pts: TargetArray,
790+
img_pts: np.ndarray,
791791
cparam: ControlPar,
792792
orient_par: OrientPar,
793793
dm: float = 1e-6,
@@ -832,7 +832,16 @@ def full_calibration(
832832
ValueError if iteration did not converge.
833833
"""
834834
err_est = np.empty((NPAR + 1), dtype=np.float64)
835-
residuals = orient(cal, cparam, len(ref_pts), ref_pts, img_pts, orient_par, err_est, dm=dm, drad=drad)
835+
836+
# convert numpy array to list of Target objects
837+
targs = [Target() for _ in img_pts]
838+
839+
for ptx, pt in enumerate(img_pts):
840+
targs[ptx].x = pt[0]
841+
targs[ptx].y = pt[1]
842+
targs[ptx].pnr = ptx
843+
844+
residuals = orient(cal, cparam, len(ref_pts), ref_pts, targs, orient_par, err_est, dm=dm, drad=drad)
836845

837846
# free(orip)
838847

@@ -844,7 +853,7 @@ def full_calibration(
844853
ret = np.empty((len(img_pts), 2))
845854
used = np.empty(len(img_pts), dtype=np.int_)
846855

847-
for ix, img_pt in enumerate(img_pts):
856+
for ix, img_pt in enumerate(targs):
848857
ret[ix] = (residuals[2 * ix], residuals[2 * ix + 1])
849858
used[ix] = img_pt.pnr
850859

@@ -855,7 +864,7 @@ def full_calibration(
855864
def match_detection_to_ref(
856865
cal: Calibration,
857866
ref_pts: np.ndarray,
858-
img_pts: TargetArray,
867+
img_pts: List[Target],
859868
cparam: ControlPar,
860869
eps: int = 25,
861870
) -> List[Target]:

openptv_python/tracking_frame_buf.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -136,31 +136,31 @@ def sort_target_y(targets: List[Target]) -> List[Target]:
136136
"""Sort targets by y coordinate."""
137137
return sorted(targets, key=lambda t: t.y)
138138

139-
class TargetArray(list):
140-
"""Target array class."""
139+
# class TargetArray(list):
140+
# """Target array class."""
141141

142-
def __init__(self, num_targets: int = 0):
143-
super().__init__(Target() for item in range(num_targets))
142+
# def __init__(self, num_targets: int = 0):
143+
# super().__init__(Target() for item in range(num_targets))
144144

145-
def __setitem__(self, index, item):
146-
super().__setitem__(index, item)
145+
# def __setitem__(self, index, item):
146+
# super().__setitem__(index, item)
147147

148-
def insert(self, index, item):
149-
super().insert(index, item)
148+
# def insert(self, index, item):
149+
# super().insert(index, item)
150150

151-
def append(self, item):
152-
super().append(str(item))
151+
# def append(self, item):
152+
# super().append(str(item))
153153

154-
def extend(self, other):
155-
if isinstance(other, type(self)):
156-
super().extend(other)
157-
else:
158-
super().extend(item for item in other)
154+
# def extend(self, other):
155+
# if isinstance(other, type(self)):
156+
# super().extend(other)
157+
# else:
158+
# super().extend(item for item in other)
159159

160-
@property
161-
def num_targs(self):
162-
"""Return the number of targets in the list."""
163-
return len(self)
160+
# @property
161+
# def num_targs(self):
162+
# """Return the number of targets in the list."""
163+
# return len(self)
164164

165165

166166
def read_targets(file_base: str, frame_num: int) -> List[Target]:

0 commit comments

Comments
 (0)