Skip to content

Commit 86ca130

Browse files
committed
Fixed overlay drawing issue in camera mode
1 parent 8df8e33 commit 86ca130

File tree

1 file changed

+30
-60
lines changed

1 file changed

+30
-60
lines changed

examples/official/dcv/main.py

Lines changed: 30 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -170,12 +170,7 @@ def __init__(self):
170170
self.current_frame = None
171171
self.annotated_frame = None
172172
self.frame_mutex = QMutex()
173-
self.detection_enabled = True
174-
self._current_barcode_items = [] # Store current detection results for live overlay
175-
176-
import time
177-
self._last_detection_time = time.time() # Initialize with current time to prevent issues
178-
173+
self.detection_enabled = True
179174
# Detection mode
180175
self.current_detection_mode = "Barcode" # Default to barcode detection
181176

@@ -186,9 +181,6 @@ def __init__(self):
186181
self.frame_timer = QTimer()
187182
self.frame_timer.timeout.connect(self.update_frame)
188183

189-
# Timer for processing results
190-
self.result_timer = QTimer()
191-
self.result_timer.timeout.connect(self.process_detection_results)
192184

193185
# Initialize available cameras
194186
self.update_camera_list()
@@ -356,7 +348,6 @@ def _start_camera_background(self, camera_index):
356348

357349
# Start timers
358350
self.frame_timer.start(33) # ~30 FPS
359-
self.result_timer.start(100) # Check results every 100ms
360351

361352
except Exception as e:
362353
self.error_occurred.emit(f"Error in camera background startup: {e}")
@@ -375,15 +366,13 @@ def stop_camera(self):
375366
try:
376367
self.camera_running = False
377368
self.frame_timer.stop()
378-
self.result_timer.stop()
379369

380370
if self.opencv_capture:
381371
self.opencv_capture.release()
382372
self.opencv_capture = None
383373

384374
# Clear all annotation data to prevent overlay issues
385375
self.annotated_frame = None
386-
self._current_barcode_items = []
387376

388377
self.start_stop_btn.setText("📷 Start Camera")
389378
self.capture_btn.setEnabled(False)
@@ -432,11 +421,15 @@ def toggle_detection(self, enabled):
432421
"""Toggle real-time barcode detection."""
433422
self.detection_enabled = enabled
434423
if not enabled:
435-
# Clear annotations immediately when detection is disabled
436-
self._current_barcode_items = []
424+
# Clear the result queue when detection is disabled to prevent stale overlays
425+
try:
426+
while not self.result_queue.empty():
427+
self.result_queue.get_nowait()
428+
except:
429+
pass
437430

438431
def update_frame(self):
439-
"""Update camera frame display with proper synchronization."""
432+
"""Update camera frame display with real-time results fetching."""
440433
if not self.camera_running or not self.opencv_capture:
441434
return
442435

@@ -460,24 +453,16 @@ def update_frame(self):
460453
# Always start with a fresh frame copy
461454
display_frame = frame.copy()
462455

463-
# Only add annotations if we have VERY recent detections to prevent ghosting
464-
if (self.detection_enabled and
465-
hasattr(self, '_current_barcode_items') and
466-
self._current_barcode_items and
467-
hasattr(self, '_last_detection_time')):
468-
469-
import time
470-
current_time = time.time()
471-
472-
# Only show annotations if they're very recent (less than 0.3 seconds old)
473-
if current_time - self._last_detection_time < 0.3:
456+
# Fetch latest results directly from queue for overlay drawing
457+
if self.detection_enabled:
458+
latest_items = self._get_latest_detection_results()
459+
if latest_items:
474460
try:
475-
display_frame = self.draw_detection_annotations(display_frame, self._current_barcode_items)
461+
display_frame = self.draw_detection_annotations(display_frame, latest_items)
462+
# Emit signal with detected items for results panel
463+
self.barcodes_detected.emit(latest_items)
476464
except Exception as e:
477465
pass # Fall back to clean frame if annotation fails
478-
else:
479-
# Clear old annotations if they're stale
480-
self._current_barcode_items = []
481466

482467
# Convert to Qt format and display
483468
rgb_frame = cv2.cvtColor(display_frame, cv2.COLOR_BGR2RGB)
@@ -499,24 +484,26 @@ def update_frame(self):
499484
except Exception as e:
500485
pass # Silently ignore frame update errors
501486

502-
def process_detection_results(self):
503-
"""Process detection results and update live annotations."""
504-
import time
487+
def _get_latest_detection_results(self):
488+
"""Get the latest detection results directly from the queue.
505489
506-
if not self.detection_enabled:
507-
# Clear current results when detection is disabled
508-
self._current_barcode_items = []
509-
return
490+
Returns:
491+
list: Latest detection items, or empty list if no results available.
492+
"""
493+
import time
494+
import queue
510495

511-
current_time = time.time()
512496
detected_items = []
513497

514-
# Process all available results
498+
# Process all available results to get the most recent ones
515499
while not self.result_queue.empty():
516500
try:
517501
captured_result = self.result_queue.get_nowait()
518502

519-
# Get all items from the captured result (like reference files)
503+
# Clear previous items and use only the latest result
504+
detected_items.clear()
505+
506+
# Get all items from the captured result
520507
items = captured_result.get_items()
521508

522509
for item in items:
@@ -527,12 +514,12 @@ def process_detection_results(self):
527514
detected_items.append(item)
528515

529516
elif self.current_detection_mode == "Document":
530-
# Document detection looks for deskewed images (like document_camera.py)
517+
# Document detection looks for deskewed images
531518
if item_type == EnumCapturedResultItemType.CRIT_DESKEWED_IMAGE:
532519
detected_items.append(item)
533520

534521
elif self.current_detection_mode == "MRZ":
535-
# MRZ detection looks for text lines and parsed results (like mrz_camera.py)
522+
# MRZ detection looks for text lines and parsed results
536523
if item_type in [EnumCapturedResultItemType.CRIT_TEXT_LINE,
537524
EnumCapturedResultItemType.CRIT_PARSED_RESULT]:
538525
detected_items.append(item)
@@ -542,8 +529,7 @@ def process_detection_results(self):
542529
except Exception as e:
543530
continue
544531

545-
# Finalize detection results
546-
self._finalize_detection_results(detected_items, current_time)
532+
return detected_items
547533

548534
def _is_mrz_like_text(self, text):
549535
"""Check if text looks like MRZ data."""
@@ -560,22 +546,6 @@ def _is_mrz_like_text(self, text):
560546
uppercase_and_symbols = sum(1 for c in text if c.isupper() or c.isdigit() or c == '<')
561547
return uppercase_and_symbols / len(text) > 0.8
562548

563-
def _finalize_detection_results(self, detected_items, current_time):
564-
"""Finalize detection results and update display."""
565-
# ALWAYS clear previous annotations first to prevent ghosting
566-
self._current_barcode_items = []
567-
568-
# Update with new detections if any
569-
if detected_items:
570-
self._current_barcode_items = detected_items
571-
self._last_detection_time = current_time
572-
# Emit signal with detected items for results panel
573-
self.barcodes_detected.emit(detected_items)
574-
else:
575-
# Clear old annotations more aggressively (0.5 seconds instead of 1)
576-
if current_time - self._last_detection_time > 0.5:
577-
self._current_barcode_items = []
578-
579549
def draw_detection_annotations(self, frame, detection_items):
580550
"""Draw detection annotations on the frame with consistent colors."""
581551
if not detection_items:

0 commit comments

Comments
 (0)