@@ -1003,7 +1003,6 @@ def run(self):
1003
1003
1004
1004
# Get the appropriate template for the detection mode
1005
1005
template = DETECTION_MODES [mode_name ]["template" ]
1006
-
1007
1006
results = self .cvr_instance .capture_multi_pages (self .file_path , template )
1008
1007
1009
1008
self .finished .emit (results )
@@ -1496,6 +1495,7 @@ def __init__(self):
1496
1495
# Initialize variables
1497
1496
self .cvr_instance = None
1498
1497
self .custom_receiver = None
1498
+ self .receiver_active = False # Track if intermediate receiver is currently active
1499
1499
self .current_file_path = None
1500
1500
self .current_pages = {} # Store page data {page_index: cv_image}
1501
1501
self .page_hash_mapping = {} # Map page_index to hash_id
@@ -2057,8 +2057,10 @@ def initialize_license(self):
2057
2057
if initialize_license_once ():
2058
2058
self .cvr_instance = CaptureVisionRouter ()
2059
2059
intermediate_result_manager = self .cvr_instance .get_intermediate_result_manager ()
2060
+
2061
+ # Create receiver but don't add it yet - only add for barcode detection
2060
2062
self .custom_receiver = MyIntermediateResultReceiver (intermediate_result_manager )
2061
- intermediate_result_manager . add_result_receiver ( self .custom_receiver )
2063
+ self .receiver_active = False # Track if receiver is currently active
2062
2064
2063
2065
self .log_message ("✅ License initialized successfully!" )
2064
2066
@@ -2077,6 +2079,36 @@ def delayed_camera_init(self):
2077
2079
if hasattr (self , 'camera_widget' ):
2078
2080
self .camera_widget .initialize_dynamsoft_camera (self .cvr_instance )
2079
2081
2082
+ def manage_intermediate_receiver (self , detection_mode , action = 'add' ):
2083
+ """
2084
+ Conditionally manage the intermediate result receiver based on detection mode.
2085
+ Only add the receiver for barcode detection to avoid deadlocks in document/MRZ modes.
2086
+
2087
+ Args:
2088
+ detection_mode (str): The detection mode ('Barcode', 'Document', 'MRZ')
2089
+ action (str): 'add' to add receiver, 'remove' to remove receiver
2090
+ """
2091
+ if not self .cvr_instance or not self .custom_receiver :
2092
+ return
2093
+
2094
+ try :
2095
+ intermediate_result_manager = self .cvr_instance .get_intermediate_result_manager ()
2096
+
2097
+ if action == 'add' and detection_mode == "Barcode" and not self .receiver_active :
2098
+ # Only add receiver for barcode detection
2099
+ intermediate_result_manager .add_result_receiver (self .custom_receiver )
2100
+ self .receiver_active = True
2101
+ print ("🔧 Added intermediate receiver for barcode detection" )
2102
+
2103
+ elif action == 'remove' and self .receiver_active :
2104
+ # Remove receiver for non-barcode modes or when explicitly requested
2105
+ intermediate_result_manager .remove_result_receiver (self .custom_receiver )
2106
+ self .receiver_active = False
2107
+ print ("🔧 Removed intermediate receiver to avoid deadlock" )
2108
+
2109
+ except Exception as e :
2110
+ print (f"⚠️ Warning: Error managing intermediate receiver: { e } " )
2111
+
2080
2112
def on_detection_mode_changed (self , mode_text ):
2081
2113
"""Handle detection mode change in camera."""
2082
2114
mode_name = mode_text .split (" - " )[0 ] # Extract mode name from combo text
@@ -2646,6 +2678,13 @@ def process_current_file(self):
2646
2678
current_mode_text = self .picture_detection_mode_combo .currentText ()
2647
2679
mode_name = current_mode_text .split (" - " )[0 ]
2648
2680
2681
+ # Manage intermediate receiver based on detection mode to avoid deadlocks
2682
+ # Only use receiver for barcode detection - remove for document/MRZ modes
2683
+ if mode_name == "Barcode" :
2684
+ self .manage_intermediate_receiver (mode_name , 'add' )
2685
+ else :
2686
+ self .manage_intermediate_receiver (mode_name , 'remove' )
2687
+
2649
2688
self .is_processing = True
2650
2689
self .process_button .setEnabled (False )
2651
2690
self .process_button .setText (f"🔄 Processing { mode_name } ..." )
@@ -2724,9 +2763,18 @@ def on_processing_finished(self, results):
2724
2763
else :
2725
2764
self .log_message (f"⚠️ Error on page { i + 1 } : { result .get_error_string ()} " )
2726
2765
2727
- # Extract pages from intermediate receiver for PDF files
2766
+ # Extract pages from intermediate receiver for PDF files (only for Barcode mode)
2767
+ # For Document/MRZ modes, we extract pages directly from results to avoid deadlock
2728
2768
if self .current_file_path and self .current_file_path .lower ().endswith ('.pdf' ):
2729
- self .extract_pdf_pages_from_receiver ()
2769
+ if mode_name == "Barcode" and self .receiver_active :
2770
+ self .extract_pdf_pages_from_receiver ()
2771
+ else :
2772
+ # For Document/MRZ modes, extract pages directly from results
2773
+ self .extract_pdf_pages_from_results (results )
2774
+ elif self .current_file_path and not self .current_file_path .lower ().endswith ('.pdf' ):
2775
+ # For single images, ensure we have the image in current_pages
2776
+ if 0 not in self .current_pages and hasattr (self , 'image_widget' ) and self .image_widget .original_image is not None :
2777
+ self .current_pages [0 ] = self .image_widget .original_image .copy ()
2730
2778
2731
2779
# Setup navigation for multi-page PDFs
2732
2780
if len (self .current_pages ) > 1 :
@@ -2812,6 +2860,62 @@ def extract_pdf_pages_from_receiver(self):
2812
2860
else :
2813
2861
self .log_message ("⚠️ No pages extracted from PDF" )
2814
2862
2863
+ def extract_pdf_pages_from_results (self , captured_results ):
2864
+ """
2865
+ Extract PDF pages directly from capture results without intermediate receiver.
2866
+ This method is used for Document/MRZ modes to avoid deadlock issues.
2867
+ """
2868
+ try :
2869
+ self .current_pages = {}
2870
+
2871
+ # Get the original image data from each result
2872
+ result_list = captured_results .get_results ()
2873
+
2874
+ for page_index , result in enumerate (result_list ):
2875
+ if result .get_error_code () == EnumErrorCode .EC_OK :
2876
+ try :
2877
+ # Try to get the original image directly from the result
2878
+ original_image = result .get_original_image ()
2879
+ if original_image is not None :
2880
+ # Convert Dynamsoft image to OpenCV format
2881
+ from dynamsoft_capture_vision_bundle import ImageIO
2882
+ image_io = ImageIO ()
2883
+ saved = image_io .save_to_numpy (original_image )
2884
+
2885
+ if saved is not None :
2886
+ # Handle different return formats
2887
+ if isinstance (saved , tuple ) and len (saved ) == 3 :
2888
+ error_code , error_message , numpy_array = saved
2889
+ if error_code == 0 and numpy_array is not None :
2890
+ self .current_pages [page_index ] = numpy_array
2891
+ elif isinstance (saved , tuple ) and len (saved ) == 2 :
2892
+ success , numpy_array = saved
2893
+ if success and numpy_array is not None :
2894
+ self .current_pages [page_index ] = numpy_array
2895
+ else :
2896
+ # Direct numpy array return
2897
+ self .current_pages [page_index ] = saved
2898
+
2899
+ self .log_message (f"📄 Extracted page { page_index + 1 } directly from results" )
2900
+ else :
2901
+ self .log_message (f"⚠️ No image data for page { page_index + 1 } " )
2902
+
2903
+ except Exception as e :
2904
+ self .log_message (f"⚠️ Error extracting page { page_index + 1 } : { e } " )
2905
+ continue
2906
+ else :
2907
+ self .log_message (f"⚠️ Error on page { page_index + 1 } : { result .get_error_string ()} " )
2908
+
2909
+ # Set the first page as current
2910
+ if self .current_pages :
2911
+ self .current_page_index = 0
2912
+ self .log_message (f"✅ Extracted { len (self .current_pages )} page(s) from PDF results (no receiver)" )
2913
+ else :
2914
+ self .log_message ("⚠️ No pages extracted from PDF results" )
2915
+
2916
+ except Exception as e :
2917
+ self .log_message (f"❌ Error in direct PDF page extraction: { e } " )
2918
+
2815
2919
def display_current_page (self ):
2816
2920
"""Display the current page with annotations."""
2817
2921
if self .current_page_index not in self .current_pages :
@@ -3653,8 +3757,10 @@ def enter_license_key(self):
3653
3757
3654
3758
self .cvr_instance = CaptureVisionRouter ()
3655
3759
intermediate_result_manager = self .cvr_instance .get_intermediate_result_manager ()
3760
+
3761
+ # Create receiver but don't add it yet - only add for barcode detection
3656
3762
self .custom_receiver = MyIntermediateResultReceiver (intermediate_result_manager )
3657
- intermediate_result_manager . add_result_receiver ( self .custom_receiver )
3763
+ self .receiver_active = False # Track if receiver is currently active
3658
3764
3659
3765
# Update camera widget if it exists
3660
3766
if hasattr (self , 'camera_widget' ):
0 commit comments