Skip to content

Commit 7669431

Browse files
committed
fighting with Cores_dtype, whether to make it a list of array
1 parent 7cc2740 commit 7669431

5 files changed

Lines changed: 101 additions & 131 deletions

File tree

openptv_python/correspondences.py

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55

66
from .calibration import Calibration
77
from .constants import COORD_UNUSED, CORRES_NONE, MAX_TARGETS, MAXCAND, NMAX, PT_UNUSED
8-
from .epi import Coord2d, epi_mm
8+
from .epi import epi_mm
99
from .find_candidate import find_candidate
1010
from .parameters import ControlPar, VolumePar
11-
from .tracking_frame_buf import Frame, Target, n_tupel
11+
from .tracking_frame_buf import Frame, Target, n_tupel_dtype
1212
from .trafo import dist_to_flat, pixel_to_metric
1313

1414

@@ -99,15 +99,13 @@ def __del__(self):
9999
del self.buf
100100

101101

102-
class Correspond:
103-
"""Correspondence between two points in two cameras."""
104-
105-
def __init__(self):
106-
self.p1 = PT_UNUSED
107-
self.n = 0
108-
self.p2 = np.array([0] * MAXCAND)
109-
self.corr = np.array([0.0] * MAXCAND)
110-
self.dist = np.array([0.0] * MAXCAND)
102+
Correspond_dtype = np.dtype([
103+
('p1', np.int32), # PT_UNUSED
104+
('n', np.int32), # 0
105+
('p2', (np.float64, MAXCAND)), # np.zeros
106+
('corr', (np.float64, MAXCAND)), # np.zeros
107+
('dist', (np.float64, MAXCAND)) # np.zeros
108+
])
111109

112110
def safely_allocate_target_usage_marks(
113111
num_cams: int, nmax: int = NMAX
@@ -138,21 +136,26 @@ def safely_allocate_target_usage_marks(
138136

139137
def safely_allocate_adjacency_lists(
140138
num_cams: int, target_counts: List[int]
141-
) -> List[List[List[Correspond]]]:
139+
) -> List[List[List[np.recarray]]]:
142140
"""Allocate space for the adjacency lists."""
141+
one_element = np.array(
142+
[(PT_UNUSED, 0, np.zeros(MAXCAND), np.zeros(MAXCAND), np.zeros(MAXCAND))],
143+
dtype=Correspond_dtype).view(np.recarray)
144+
143145
try:
144146
lists = [
145-
[[Correspond() for _ in range(target_counts[c1])] for _ in range(num_cams)]
147+
[[one_element for _ in range(target_counts[c1])] for _ in range(num_cams)]
146148
for c1 in range(num_cams)
147149
]
150+
148151
except MemoryError:
149152
print("Memory allocation failed.")
150-
lists = []
153+
lists = [[[one_element]]]
151154

152155
return lists
153156

154157
def four_camera_matching(
155-
corr_list: List[List[List[Correspond]]],
158+
corr_list: List[List[List[np.recarray]]],
156159
base_target_count,
157160
accept_corr,
158161
scratch,
@@ -228,7 +231,7 @@ def four_camera_matching(
228231

229232

230233
def three_camera_matching(
231-
corr_list: List[List[List[Correspond]]],
234+
corr_list: List[List[List[np.recarray]]],
232235
num_cams,
233236
target_counts,
234237
accept_corr,
@@ -307,7 +310,7 @@ def three_camera_matching(
307310

308311

309312
def consistent_pair_matching(
310-
corr_list: List[List[List[Correspond]]],
313+
corr_list: List[List[List[np.recarray]]],
311314
num_cams: int,
312315
target_counts: List[int],
313316
accept_corr: float,
@@ -353,8 +356,8 @@ def consistent_pair_matching(
353356

354357

355358
def match_pairs(
356-
corr_lists: List[List[List[Correspond]]],
357-
corrected: List[List[Coord2d]],
359+
corr_lists: List[List[List[np.recarray]]],
360+
corrected: np.ndarray, # List[List[Coord2d]],
358361
frm: Frame,
359362
vpar: VolumePar,
360363
cpar: ControlPar,
@@ -454,7 +457,7 @@ def match_pairs(
454457

455458

456459
def take_best_candidates(
457-
src: List[n_tupel], dst: List[n_tupel], num_cams: int, tusage: List[List[int]]
460+
src: np.recarray, dst: np.recarray, num_cams: int, tusage: List[List[int]] #List[n_tupel]
458461
):
459462
"""
460463
Take the best candidates from the candidate list based on their correlation measure.
@@ -497,7 +500,8 @@ def take_best_candidates(
497500
taken = 0
498501

499502
# Sort candidates by match quality (.corr)
500-
src.sort(key=lambda x: x.corr, reverse=True)
503+
src.sort(order='corr') # by corr
504+
src = src[::-1] # reverse order
501505

502506
# Take candidates from the top to the bottom of the sorted list
503507
# Only take if none of the corresponding targets have been used
@@ -528,7 +532,7 @@ def take_best_candidates(
528532

529533
def py_correspondences(
530534
img_pts: List[List[Target]], # num_cams * num_targets[cam]
531-
flat_coords: List[List[Coord2d]],
535+
flat_coords: List[List[np.recarray]],
532536
calib: List[Calibration],
533537
vparam: VolumePar,
534538
cparam: ControlPar,
@@ -644,12 +648,12 @@ def py_correspondences(
644648

645649
def correspondences(
646650
frm: Frame,
647-
corrected: List[List[Coord2d]],
651+
corrected: List[List[np.recarray]], # List[List[Coord2d]],
648652
vpar: VolumePar,
649653
cpar: ControlPar,
650654
calib: List[Calibration],
651655
match_counts: List[int],
652-
) -> List[n_tupel]:
656+
) -> List[np.ndarray]: # n_tupel
653657
"""Find correspondences between cameras.
654658
655659
/* correspondences() generates a list of tuple target numbers (one for each
@@ -686,8 +690,9 @@ def correspondences(
686690
nmax = NMAX
687691

688692
# Allocation of scratch buffers for internal tasks and return-value space
689-
con0 = [n_tupel() for _ in range(nmax * cpar.num_cams)]
690-
con = [n_tupel() for _ in range(nmax * cpar.num_cams)]
693+
con0 = np.empty((nmax * cpar.num_cams,), dtype=n_tupel_dtype)
694+
con = np.empty((nmax * cpar.num_cams,), dtype=n_tupel_dtype)
695+
691696
tim = safely_allocate_target_usage_marks(cpar.num_cams, nmax)
692697

693698
# allocate memory for lists of correspondences
@@ -752,7 +757,7 @@ def correspondences(
752757

753758

754759
def single_cam_correspondences(
755-
img_pts: List[Target], corrected: List[Coord2d]
760+
img_pts: List[Target], corrected: np.recarray #List[Coord2d]
756761
) -> Tuple[List[np.ndarray], List[np.ndarray], int]:
757762
"""
758763
Single camera correspondence is not a real correspondence, it will be only a projection.

openptv_python/epi.py

Lines changed: 22 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,44 @@
11
"""Epipolar geometry."""
2-
from typing import List, Tuple
2+
from typing import Tuple
33

44
import numpy as np
5-
from numba import float64, int32, njit
6-
from numba.experimental import jitclass
75

6+
# from numba import float64, int32
87
from .calibration import Calibration
9-
from .constants import PT_UNUSED
108
from .imgcoord import flat_image_coord, img_coord
119
from .multimed import move_along_ray
1210
from .parameters import ControlPar, MultimediaPar, VolumePar
1311
from .ray_tracing import ray_tracing
1412
from .trafo import dist_to_flat, metric_to_pixel, pixel_to_metric
1513

16-
spec = [
17-
('pnr', int32),
18-
('tol', float64),
19-
('corr', float64),
20-
]
14+
Candidate_dtype = np.dtype([
15+
('pnr', np.int32),
16+
('tol', np.float64),
17+
('corr', np.float64),
18+
])
2119

22-
@jitclass(spec)
23-
class Candidate:
24-
"""Candidate point in the second image."""
20+
Coord2d_dtype = np.dtype([
21+
('pnr', np.int32),
22+
('x', np.float64),
23+
('y', np.float64),
24+
])
2525

26-
def __init__(self, pnr=PT_UNUSED, tol=0.0, corr=0.0):
27-
self.pnr = pnr
28-
self.tol = tol
29-
self.corr = corr
26+
Coord3d_dtype = np.dtype([
27+
('pnr', np.int32),
28+
('x', np.float64),
29+
('y', np.float64),
30+
('z', np.float64),
31+
])
3032

31-
# def __repr__(self):
32-
# return f"Candidate(pnr={self.pnr}, tol={self.tol}, corr={self.corr})"
3333

34-
spec = [
35-
('pnr', int32),
36-
('x', float64),
37-
('y', float64),
38-
]
3934

40-
@jitclass(spec)
41-
class Coord2d:
42-
"""2D coordinates in the image space."""
43-
44-
def __init__(self, pnr=PT_UNUSED, x=0.0, y=0.0):
45-
self.pnr = pnr
46-
self.x = x
47-
self.y = y
48-
49-
# def __repr__(self):
50-
# return f"Coord2d(pnr={self.pnr}, x={self.x}, y={self.y})"
51-
52-
@njit
53-
def sort_coord2d_x(crd: List[Coord2d]) -> List[Coord2d]:
35+
def sort_coord2d_x(crd: np.ndarray) -> np.ndarray:
5436
"""Quicksort for coordinates by x ."""
55-
return sorted(crd, key=lambda p: p.x)
37+
return np.sort(crd, order='x')
5638

57-
@njit
58-
def sort_coord2d_y(crd: List[Coord2d]) -> List[Coord2d]:
39+
def sort_coord2d_y(crd: np.ndarray) -> np.ndarray:
5940
"""Sort coordinates by y."""
60-
return sorted(crd, key=lambda p: p.y)
61-
62-
spec = [
63-
('pnr', int32),
64-
('x', float64),
65-
('y', float64),
66-
('z', float64),
67-
]
68-
69-
@jitclass(spec)
70-
class Coord3d:
71-
"""2D coordinates in the image space."""
72-
73-
def __init__(self, pnr=PT_UNUSED, x=0.0, y=0.0, z=0.0):
74-
self.pnr = pnr
75-
self.x = x
76-
self.y = y
77-
self.z = z
41+
return np.sort(crd, order='y')
7842

7943

8044
def epi_mm(xl, yl, cal1, cal2, mmp, vpar) -> Tuple[float, float, float, float]:

openptv_python/sortgrid.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from .calibration import Calibration
66
from .constants import POS_INF, PT_UNUSED, SORTGRID_EPS
7-
from .epi import Coord3d
7+
from .epi import Coord3d_dtype
88
from .imgcoord import img_coord
99
from .parameters import ControlPar
1010
from .tracking_frame_buf import Target
@@ -119,7 +119,7 @@ def read_sortgrid_par(filename) -> int:
119119
return eps
120120

121121

122-
def read_calblock(filename: str) -> List[Coord3d]:
122+
def read_calblock(filename: str) -> np.recarray: #List[Coord3d]:
123123
"""
124124
Read the calibration block file into the structure of 3D positions and pointers.
125125
@@ -142,13 +142,14 @@ def read_calblock(filename: str) -> List[Coord3d]:
142142
x = float(values[1])
143143
y = float(values[2])
144144
z = float(values[3])
145-
coord = Coord3d(pnr, x, y, z)
145+
# coord = Coord3d(pnr, x, y, z)
146+
coord = np.array([(pnr, x, y, z)], dtype=Coord3d_dtype)
146147
coords.append(coord)
147148
except FileNotFoundError:
148149
print(f"Can't open calibration block file: {filename}")
149-
return []
150+
return np.recarray(0, dtype=Coord3d_dtype)
150151
except ValueError:
151152
print(f"Empty or badly formatted file: {filename}")
152-
return []
153+
return np.recarray(0, dtype = Coord3d_dtype)
153154

154-
return coords
155+
return np.array(coords).view(np.recarray)

openptv_python/track.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from .imgcoord import img_coord
2424
from .orientation import point_position
2525
from .parameters import ControlPar, SequencePar, TrackPar, VolumePar
26-
from .tracking_frame_buf import Corres, Frame, Pathinfo, Target
26+
from .tracking_frame_buf import Corres_dtype, Frame, Pathinfo, Target
2727
from .tracking_run import TrackingRun
2828
from .trafo import dist_to_flat, metric_to_pixel, pixel_to_metric
2929
from .vec_utils import vec_copy, vec_diff_norm, vec_subt
@@ -761,8 +761,7 @@ def add_particle(frm: Frame, pos: np.ndarray, cand_inds: np.ndarray) -> None:
761761
ref_path_inf = Pathinfo()
762762
frm.path_info.append(ref_path_inf)
763763

764-
ref_corres = Corres()
765-
frm.correspond.append(ref_corres)
764+
frm.correspond.append(np.recarray((1,), dtype=Corres_dtype))
766765

767766
ref_path_inf.x = vec_copy(pos)
768767
ref_path_inf.reset_links()

0 commit comments

Comments
 (0)