Use separate kernels for peak-finding and scoring

pull/416/head
nyanpasu64 2022-03-11 06:40:57 -08:00
rodzic 942577dd39
commit b985d3e187
1 zmienionych plików z 19 dodań i 8 usunięć

Wyświetl plik

@ -484,17 +484,25 @@ class CorrelationTrigger(MainTrigger):
else: else:
edge_score = None edge_score = None
corr_enabled = bool(cfg.buffer_strength) and bool(cfg.responsiveness)
# array[A+B] Amplitude # array[A+B] Amplitude
corr_kernel: np.ndarray = self._corr_buffer * cfg.buffer_strength corr_kernel: np.ndarray = self._corr_buffer * cfg.buffer_strength
if slope_finder is not None: if slope_finder is not None:
corr_kernel += slope_finder corr_kernel += slope_finder
peak_kernel = self._corr_buffer
# `corr[x]` = correlation of kernel placed at position `x` in data. # `corr[x]` = correlation of kernel placed at position `x` in data.
# `corr_kernel` is not allowed to move past the boundaries of `data`. # `corr_kernel` is not allowed to move past the boundaries of `data`.
corr = signal.correlate_valid(data, corr_kernel) corr = signal.correlate_valid(data, corr_kernel)
peaks = (
signal.correlate_valid(data, peak_kernel)
if corr_enabled
else np.zeros_like(corr)
)
if edge_score is not None: if edge_score is not None:
corr += edge_score peaks += edge_score
# Don't pick peaks more than `period * trigger_radius_periods` away from the # Don't pick peaks more than `period * trigger_radius_periods` away from the
# center. # center.
@ -503,10 +511,13 @@ class CorrelationTrigger(MainTrigger):
else: else:
trigger_radius = None trigger_radius = None
def find_peak(corr: np.ndarray, radius: Optional[int]) -> int: def find_peak(
corr: np.ndarray, peaks: np.ndarray, radius: Optional[int]
) -> int:
"""If radius is set, the returned offset is limited to ±radius from the """If radius is set, the returned offset is limited to ±radius from the
center of correlation. center of correlation.
""" """
assert len(corr) == len(peaks) == self._trigger_diameter + 1
# returns double, not single/f32 # returns double, not single/f32
begin_offset = 0 begin_offset = 0
@ -518,24 +529,24 @@ class CorrelationTrigger(MainTrigger):
right = min(mid + radius + 1, Ncorr) right = min(mid + radius + 1, Ncorr)
corr = corr[left:right] corr = corr[left:right]
peaks = peaks[left:right]
begin_offset = left begin_offset = left
min_val = np.min(corr) min_corr = np.min(corr)
# Only permit local maxima. This fixes triggering errors where the edge # Only permit local maxima. This fixes triggering errors where the edge
# of the allowed range has higher correlation than edges in-bounds, # of the allowed range has higher correlation than edges in-bounds,
# but isn't a rising edge itself (a local maximum of alignment). # but isn't a rising edge itself (a local maximum of alignment).
orig = corr.copy() corr[:-1][peaks[:-1] < peaks[1:]] = min_corr
corr[:-1][orig[:-1] < orig[1:]] = min_val corr[1:][peaks[1:] < peaks[:-1]] = min_corr
corr[1:][orig[1:] < orig[:-1]] = min_val corr[0] = corr[-1] = min_corr
corr[0] = corr[-1] = min_val
# Find optimal offset # Find optimal offset
peak_offset = np.argmax(corr) + begin_offset # type: int peak_offset = np.argmax(corr) + begin_offset # type: int
return peak_offset return peak_offset
# Find correlation peak. # Find correlation peak.
peak_offset = find_peak(corr, trigger_radius) peak_offset = find_peak(corr, peaks, trigger_radius)
trigger = trigger_begin + stride * (peak_offset) trigger = trigger_begin + stride * (peak_offset)
del data del data