Skip to content

Commit f4574c3

Browse files
committed
Fixed a freezing issue caused by MyIntermediateResultReceiver
1 parent f6b2388 commit f4574c3

File tree

1 file changed

+111
-5
lines changed

1 file changed

+111
-5
lines changed

examples/official/dcv/main.py

Lines changed: 111 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,7 +1003,6 @@ def run(self):
10031003

10041004
# Get the appropriate template for the detection mode
10051005
template = DETECTION_MODES[mode_name]["template"]
1006-
10071006
results = self.cvr_instance.capture_multi_pages(self.file_path, template)
10081007

10091008
self.finished.emit(results)
@@ -1496,6 +1495,7 @@ def __init__(self):
14961495
# Initialize variables
14971496
self.cvr_instance = None
14981497
self.custom_receiver = None
1498+
self.receiver_active = False # Track if intermediate receiver is currently active
14991499
self.current_file_path = None
15001500
self.current_pages = {} # Store page data {page_index: cv_image}
15011501
self.page_hash_mapping = {} # Map page_index to hash_id
@@ -2057,8 +2057,10 @@ def initialize_license(self):
20572057
if initialize_license_once():
20582058
self.cvr_instance = CaptureVisionRouter()
20592059
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
20602062
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
20622064

20632065
self.log_message("✅ License initialized successfully!")
20642066

@@ -2077,6 +2079,36 @@ def delayed_camera_init(self):
20772079
if hasattr(self, 'camera_widget'):
20782080
self.camera_widget.initialize_dynamsoft_camera(self.cvr_instance)
20792081

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+
20802112
def on_detection_mode_changed(self, mode_text):
20812113
"""Handle detection mode change in camera."""
20822114
mode_name = mode_text.split(" - ")[0] # Extract mode name from combo text
@@ -2646,6 +2678,13 @@ def process_current_file(self):
26462678
current_mode_text = self.picture_detection_mode_combo.currentText()
26472679
mode_name = current_mode_text.split(" - ")[0]
26482680

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+
26492688
self.is_processing = True
26502689
self.process_button.setEnabled(False)
26512690
self.process_button.setText(f"🔄 Processing {mode_name}...")
@@ -2724,9 +2763,18 @@ def on_processing_finished(self, results):
27242763
else:
27252764
self.log_message(f"⚠️ Error on page {i+1}: {result.get_error_string()}")
27262765

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
27282768
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()
27302778

27312779
# Setup navigation for multi-page PDFs
27322780
if len(self.current_pages) > 1:
@@ -2812,6 +2860,62 @@ def extract_pdf_pages_from_receiver(self):
28122860
else:
28132861
self.log_message("⚠️ No pages extracted from PDF")
28142862

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+
28152919
def display_current_page(self):
28162920
"""Display the current page with annotations."""
28172921
if self.current_page_index not in self.current_pages:
@@ -3653,8 +3757,10 @@ def enter_license_key(self):
36533757

36543758
self.cvr_instance = CaptureVisionRouter()
36553759
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
36563762
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
36583764

36593765
# Update camera widget if it exists
36603766
if hasattr(self, 'camera_widget'):

0 commit comments

Comments
 (0)