forked from dsutanto/zenai-kpc-python
fix counter bug
This commit is contained in:
1 parent
cb0b8ac1d9
commit
41c4a558b1
2 files changed
+33
-9
No files matched your search
+13
-6
@@ -1215,8 +1215,9 @@ def run():
|
||||
frames_since_infer = 0
|
||||
video_writer = None
|
||||
crossing_times = deque()
|
||||
counter_in = 0
|
||||
counter_out = 0
|
||||
# Overlay shows daily store totals (resume-safe, resets on counting-day change).
|
||||
counter_in = store.current_count_in
|
||||
counter_out = store.current_count_out
|
||||
last_snapshot_cleanup = 0.0
|
||||
|
||||
counting_active = True
|
||||
@@ -1495,13 +1496,17 @@ def run():
|
||||
|
||||
recent.append((frame_idx, cx))
|
||||
st["counted"] = True
|
||||
_, _, counted = store.record_object_crossing(tid, direction)
|
||||
counter_in = store.current_count_in
|
||||
counter_out = store.current_count_out
|
||||
if not counted:
|
||||
# Dedup in the store rejected this event; skip overlay/CSV.
|
||||
object_tracked[tid] = (cx, cy, mono)
|
||||
continue
|
||||
if direction == "in":
|
||||
counter_in += 1
|
||||
count_in_pulse = COUNT_PULSE_FRAMES
|
||||
else:
|
||||
counter_out += 1
|
||||
count_out_pulse = COUNT_PULSE_FRAMES
|
||||
store.record_object_crossing(tid, direction)
|
||||
if cross_logger:
|
||||
cross_logger.write_row(
|
||||
[
|
||||
@@ -1550,7 +1555,9 @@ def run():
|
||||
if object_crossed_frame:
|
||||
line_pulse = LINE_PULSE_FRAMES
|
||||
|
||||
display_total = store.display_total()
|
||||
# Keep overlay aligned with daily store (also resets after cutoff).
|
||||
counter_in = store.current_count_in
|
||||
counter_out = store.current_count_out
|
||||
while crossing_times and mono - crossing_times[0] > RATE_WINDOW_SEC:
|
||||
crossing_times.popleft()
|
||||
rate = (len(crossing_times) / RATE_WINDOW_SEC * 60) if crossing_times else 0.0
|
||||
|
||||
+20
-3
@@ -88,11 +88,23 @@ class CounterStore:
|
||||
state.setdefault('count_in', 0)
|
||||
state.setdefault('count_out', 0)
|
||||
state.setdefault('count', state['count_in'] + state['count_out'])
|
||||
state.setdefault('counted_event_ids', [])
|
||||
# Track IDs are process-local and restart from 1 after every process
|
||||
# start. Persisted dedup keys like "5_in" would silently block new
|
||||
# counts that reuse those IDs, so clear them on resume while keeping
|
||||
# the day's totals.
|
||||
stale_ids = state.get('counted_event_ids') or []
|
||||
if stale_ids:
|
||||
self.log(
|
||||
f"Cleared {len(stale_ids)} persisted track dedup keys "
|
||||
f"(track IDs reset on restart)"
|
||||
)
|
||||
state['counted_event_ids'] = []
|
||||
self.log(
|
||||
f"Resumed {current_date} with total={state['count']} "
|
||||
f"(in={state['count_in']} out={state['count_out']})"
|
||||
)
|
||||
with open(self.state_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(state, f, indent=2, ensure_ascii=False)
|
||||
return state
|
||||
except Exception as exc:
|
||||
self.log(f'Failed to load state file: {exc}')
|
||||
@@ -126,7 +138,10 @@ class CounterStore:
|
||||
self.log(f'Started counting day {counting_date} ({self.object_label})')
|
||||
|
||||
def record_object_crossing(self, track_id, direction):
|
||||
"""Record an object crossing a counting line. direction: 'in' | 'out'."""
|
||||
"""Record an object crossing a counting line. direction: 'in' | 'out'.
|
||||
|
||||
Returns (total_count, day_started, counted).
|
||||
"""
|
||||
with self.state_lock:
|
||||
counting_date = self.get_counting_date()
|
||||
day_started = False
|
||||
@@ -134,6 +149,7 @@ class CounterStore:
|
||||
self._start_new_day(counting_date)
|
||||
day_started = True
|
||||
|
||||
counted = False
|
||||
event_key = f"{track_id}_{direction}"
|
||||
if event_key not in self.current_state['counted_event_ids']:
|
||||
self.current_state['count'] += 1
|
||||
@@ -142,6 +158,7 @@ class CounterStore:
|
||||
else:
|
||||
self.current_state['count_out'] += 1
|
||||
self.current_state['counted_event_ids'].append(event_key)
|
||||
counted = True
|
||||
self.log(
|
||||
f'Counted {direction} (track {track_id}) | {counting_date} '
|
||||
f'total: {self.current_state["count"]} '
|
||||
@@ -151,7 +168,7 @@ class CounterStore:
|
||||
|
||||
self.current_state['last_detection_time'] = datetime.now().isoformat()
|
||||
self.save_state()
|
||||
return self.current_state['count'], day_started
|
||||
return self.current_state['count'], day_started, counted
|
||||
|
||||
def _persist_day(self):
|
||||
state = self.current_state
|
||||
|
||||
Reference in new issue
Block a user