Skip to content

Commit d28ac96

Browse files
committed
working on the numpy.recarray
1 parent 7669431 commit d28ac96

4 files changed

Lines changed: 88 additions & 63 deletions

File tree

openptv_python/correspondences.py

Lines changed: 43 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,14 @@ def __del__(self):
102102
Correspond_dtype = np.dtype([
103103
('p1', np.int32), # PT_UNUSED
104104
('n', np.int32), # 0
105-
('p2', (np.float64, MAXCAND)), # np.zeros
105+
('p2', (np.int32, MAXCAND)), # np.zeros
106106
('corr', (np.float64, MAXCAND)), # np.zeros
107107
('dist', (np.float64, MAXCAND)) # np.zeros
108108
])
109109

110110
def safely_allocate_target_usage_marks(
111111
num_cams: int, nmax: int = NMAX
112-
) -> List[List[int]]:
112+
) -> np.ndarray: # num_cams x nmax instead of List[List[int]]:
113113
"""Allocate space for per-camera arrays marking whether a certain target was used.
114114
115115
If some allocation failed, it cleans up memory and returns NULL. Allocated arrays are zeroed
@@ -123,39 +123,48 @@ def safely_allocate_target_usage_marks(
123123
-------
124124
A list of lists of integers, or `None` if an allocation failed.
125125
"""
126-
tusage = []
127-
for cam in range(num_cams):
128-
tusage.append([0] * nmax) # Initialize the array to all zeros.
126+
# tusage = []
127+
# for cam in range(num_cams):
128+
# tusage.append([0] * nmax) # Initialize the array to all zeros.
129129

130-
# Check if any of the allocations failed.
131-
for cam in range(num_cams):
132-
if tusage[cam] is None:
133-
return [] # was None
130+
# # Check if any of the allocations failed.
131+
# for cam in range(num_cams):
132+
# if tusage[cam] is None:
133+
# return [] # was None
134134

135-
return tusage
135+
return np.zeros((num_cams, nmax), dtype=np.int32)
136136

137137
def safely_allocate_adjacency_lists(
138138
num_cams: int, target_counts: List[int]
139-
) -> List[List[List[np.recarray]]]:
139+
) -> np.recarray:
140140
"""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)
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)
144144

145145
try:
146-
lists = [
147-
[[one_element for _ in range(target_counts[c1])] for _ in range(num_cams)]
148-
for c1 in range(num_cams)
149-
]
146+
# lists = [
147+
# [[one_element for _ in range(target_counts[c1])] for _ in range(num_cams)]
148+
# for c1 in range(num_cams)
149+
# ]
150+
151+
lists = np.recarray((num_cams, num_cams, max(target_counts)),dtype=Correspond_dtype)
152+
153+
except MemoryError as exc:
154+
raise MemoryError("Failed to allocate adjacency lists.") from exc
155+
# lists = [[[one_element]]]
156+
157+
lists.p1 = PT_UNUSED
158+
lists.n = 0
159+
lists.p2 = np.zeros(MAXCAND)
160+
lists.corr = np.zeros(MAXCAND)
161+
lists.dist = np.zeros(MAXCAND)
150162

151-
except MemoryError:
152-
print("Memory allocation failed.")
153-
lists = [[[one_element]]]
154163

155164
return lists
156165

157166
def four_camera_matching(
158-
corr_list: List[List[List[np.recarray]]],
167+
corr_list: np.recarray,
159168
base_target_count,
160169
accept_corr,
161170
scratch,
@@ -231,7 +240,7 @@ def four_camera_matching(
231240

232241

233242
def three_camera_matching(
234-
corr_list: List[List[List[np.recarray]]],
243+
corr_list: np.recarray, # num_cam, num_cam, num_targets
235244
num_cams,
236245
target_counts,
237246
accept_corr,
@@ -310,13 +319,13 @@ def three_camera_matching(
310319

311320

312321
def consistent_pair_matching(
313-
corr_list: List[List[List[np.recarray]]],
322+
corr_list: np.recarray,
314323
num_cams: int,
315324
target_counts: List[int],
316325
accept_corr: float,
317-
scratch,
326+
scratch: np.recarray,
318327
scratch_size: int,
319-
tusage: List[List[int]],
328+
tusage: np.ndarray,
320329
) -> int:
321330
"""Find consistent pairs of correspondences."""
322331
matched = 0
@@ -356,8 +365,8 @@ def consistent_pair_matching(
356365

357366

358367
def match_pairs(
359-
corr_lists: List[List[List[np.recarray]]],
360-
corrected: np.ndarray, # List[List[Coord2d]],
368+
corr_lists: np.recarray, # num_cam, num_cam, num_targets
369+
corrected: np.recarray, # List[List[Coord2d]],
361370
frm: Frame,
362371
vpar: VolumePar,
363372
cpar: ControlPar,
@@ -457,7 +466,7 @@ def match_pairs(
457466

458467

459468
def take_best_candidates(
460-
src: np.recarray, dst: np.recarray, num_cams: int, tusage: List[List[int]] #List[n_tupel]
469+
src: np.recarray, dst: np.recarray, num_cams: int, tusage: np.ndarray #List[n_tupel]
461470
):
462471
"""
463472
Take the best candidates from the candidate list based on their correlation measure.
@@ -532,7 +541,7 @@ def take_best_candidates(
532541

533542
def py_correspondences(
534543
img_pts: List[List[Target]], # num_cams * num_targets[cam]
535-
flat_coords: List[List[np.recarray]],
544+
flat_coords: np.recarray,
536545
calib: List[Calibration],
537546
vparam: VolumePar,
538547
cparam: ControlPar,
@@ -648,12 +657,12 @@ def py_correspondences(
648657

649658
def correspondences(
650659
frm: Frame,
651-
corrected: List[List[np.recarray]], # List[List[Coord2d]],
660+
corrected: np.recarray, # List[List[Coord2d]],
652661
vpar: VolumePar,
653662
cpar: ControlPar,
654663
calib: List[Calibration],
655664
match_counts: List[int],
656-
) -> List[np.ndarray]: # n_tupel
665+
) -> np.recarray: # n_tupel_dtype
657666
"""Find correspondences between cameras.
658667
659668
/* correspondences() generates a list of tuple target numbers (one for each
@@ -690,8 +699,8 @@ def correspondences(
690699
nmax = NMAX
691700

692701
# Allocation of scratch buffers for internal tasks and return-value space
693-
con0 = np.empty((nmax * cpar.num_cams,), dtype=n_tupel_dtype)
694-
con = np.empty((nmax * cpar.num_cams,), dtype=n_tupel_dtype)
702+
con0 = np.recarray((nmax * cpar.num_cams), dtype=n_tupel_dtype)
703+
con = np.recarray((nmax * cpar.num_cams), dtype=n_tupel_dtype)
695704

696705
tim = safely_allocate_target_usage_marks(cpar.num_cams, nmax)
697706

openptv_python/find_candidate.py

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66

77
from .calibration import Calibration
88
from .constants import MAXCAND
9-
from .epi import Candidate, Coord2d
9+
from .epi import Candidate_dtype
1010
from .parameters import ControlPar, VolumePar
1111
from .tracking_frame_buf import Target
1212
from .trafo import correct_brown_affine
1313

1414

1515
def find_candidate(
16-
crd: List[Coord2d],
16+
crd: np.recarray,
1717
pix: List[Target],
1818
num: int,
1919
xa: float,
@@ -27,7 +27,7 @@ def find_candidate(
2727
vpar: VolumePar,
2828
cpar: ControlPar,
2929
cal: Calibration,
30-
) -> List[Candidate]:
30+
) -> np.recarray:
3131
"""Search in the image space of the image all the candidates around the epipolar line.
3232
3333
originating from another camera. It is a binary search in an x-sorted coord-set,
@@ -57,7 +57,8 @@ def find_candidate(
5757
-------
5858
cand: list of candidates, or empty list if nothing is found
5959
"""
60-
cand: List[Candidate] = []
60+
cand: List[np.recarray] = []
61+
# cand: np.recarray = np.recarray((0,), dtype=Candidate_dtype)
6162

6263
# The image space is the image plane of the camera. The image space is
6364
# given in millimeters of sensor size and the origin is in the center of the sensor.
@@ -89,7 +90,8 @@ def find_candidate(
8990

9091
# If epipolar line out of sensor area, give up.
9192
if xb <= xmin or xa >= xmax or yb <= ymin or ya >= ymax:
92-
return cand
93+
# return np.array(cand).view(np.recarray)
94+
return np.recarray((0,), dtype=Candidate_dtype)
9395

9496
j0 = find_start_point(crd, num, xa, vpar)
9597

@@ -99,7 +101,8 @@ def find_candidate(
99101
# Since the list is x-sorted, an out of x-bound candidate is after the
100102
# last possible candidate, so stop.
101103
if crd[j].x > xb + vpar.eps0:
102-
return cand
104+
out = np.array(cand).view(np.recarray).flatten()
105+
return out # type: ignore
103106

104107
# Candidate should at the very least be in the epipolar search window
105108
# to be considered.
@@ -128,8 +131,9 @@ def find_candidate(
128131
if qn < vpar.cn or qnx < vpar.cnx or qny < vpar.cny or qsumg <= vpar.csumg:
129132
continue
130133
if len(cand) >= MAXCAND:
131-
print(f"More candidates than {MAXCAND}: {len(cand)}\n")
132-
return cand
134+
print(f"Increase maximum number of candidates {len(cand)}\n")
135+
out = np.array(cand).view(np.recarray).flatten()
136+
return out # type: ignore
133137

134138
# Empirical correlation coefficient from shape and brightness
135139
# parameters.
@@ -138,11 +142,13 @@ def find_candidate(
138142
# Prefer matches with brighter targets.
139143
corr *= sumg + pix[p2].sumg
140144

141-
cand.append(Candidate(pnr=j, tol=d, corr=corr))
145+
# cand.append(Candidate(pnr=j, tol=d, corr=corr))
146+
cand.append(np.array([(j, d, corr)], dtype=Candidate_dtype)) # type: ignore
142147

148+
out = np.array(cand).view(np.recarray).flatten()
143149
# print(f"appended: {cand[-1]}")
144150

145-
return cand
151+
return out # type: ignore
146152

147153

148154
# def quality_ratio(a, b):
@@ -156,7 +162,7 @@ def quality_ratio(a: float, b: float) -> float:
156162
return 0
157163
return min(a, b) / max(a, b)
158164

159-
def find_start_point(crd: List[Coord2d], num: int, xa: float, vpar: VolumePar) -> int:
165+
def find_start_point(crd: np.recarray, num: int, xa: float, vpar: VolumePar) -> int:
160166
"""Find the start point of the candidate search.
161167
162168
Args:
@@ -171,9 +177,8 @@ def find_start_point(crd: List[Coord2d], num: int, xa: float, vpar: VolumePar) -
171177
-------
172178
The start point of the candidate search.
173179
"""
174-
x = np.array([_.x for _ in crd])
175-
eps0 = vpar.eps0
176-
out = find_start_point_binary(x, num, xa, eps0)
180+
# x = np.array([_.x for _ in crd])
181+
out = find_start_point_binary(crd.x, num, xa, vpar.eps0)
177182
return out
178183

179184
@njit(int32(float64[:], int32, float64, float64))

openptv_python/tracking_frame_buf.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -883,7 +883,7 @@ def match_coords(
883883
cal: Calibration,
884884
tol: float = 1e-5,
885885
reset_numbers: bool = False,
886-
) -> np.ndarray:
886+
) -> np.recarray:
887887
"""Match coordinates from all cameras into a single block.
888888
889889
replaces MatchedCoords class in Cython
@@ -898,7 +898,7 @@ def match_coords(
898898
is a low priority.
899899
900900
"""
901-
matched_coords = np.empty(len(targs), dtype=Coord2d_dtype)
901+
matched_coords = np.recarray(len(targs), dtype=Coord2d_dtype)
902902

903903
for tnum, targ in enumerate(targs):
904904
# targ = targs[tnum]
@@ -915,7 +915,7 @@ def match_coords(
915915

916916

917917
def matched_coords_as_arrays(
918-
matched_coords: List[np.recarray], #Coord2d
918+
matched_coords: np.recarray, #Coord2d
919919
) -> Tuple[np.ndarray, np.ndarray]:
920920
"""
921921
Return the data associated with the object (the matched coordinates.
@@ -927,7 +927,7 @@ def matched_coords_as_arrays(
927927
pos - (n,2) array, the (x,y) flat-coordinates position of n targets.
928928
pnr - n-length array, the corresponding target number for each point.
929929
"""
930-
num_pts = len(matched_coords)
930+
num_pts = matched_coords.shape[0]
931931
pos = np.empty((num_pts, 2))
932932
pnr = np.empty(num_pts, dtype=np.int_)
933933

0 commit comments

Comments
 (0)