@@ -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