Skip to content

Commit 8df8e33

Browse files
committed
Save normalize images in file mode
1 parent 66da5ed commit 8df8e33

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

examples/official/dcv/main.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,6 +1370,9 @@ def __init__(self):
13701370
self.process_start_time = None
13711371
self.current_detection_mode = "Barcode" # Default detection mode
13721372

1373+
# Document mode variables
1374+
self.current_normalized_documents = {} # Store normalized documents {page_index: cv_image}
1375+
13731376
# Camera mode variables
13741377
self.camera_results = [] # Store recent camera detection results
13751378
self.camera_history = [] # Store detection history
@@ -1668,6 +1671,7 @@ def create_control_panel(self):
16681671
for mode, config in DETECTION_MODES.items():
16691672
self.picture_detection_mode_combo.addItem(f"{mode} - {config['description']}")
16701673
self.picture_detection_mode_combo.setCurrentIndex(0) # Default to Barcode
1674+
self.picture_detection_mode_combo.currentTextChanged.connect(self.on_picture_detection_mode_changed)
16711675
mode_layout.addWidget(self.picture_detection_mode_combo)
16721676
process_layout.addLayout(mode_layout)
16731677

@@ -1715,6 +1719,14 @@ def create_control_panel(self):
17151719
self.copy_button.clicked.connect(self.copy_to_clipboard)
17161720
actions_layout.addWidget(self.copy_button)
17171721

1722+
# Save normalized document button (only for document mode)
1723+
self.save_document_button = QPushButton("💾 Save Normalized Document")
1724+
self.save_document_button.setEnabled(False)
1725+
self.save_document_button.setVisible(False) # Hidden by default (only show in Document mode)
1726+
self.save_document_button.clicked.connect(self.save_normalized_document)
1727+
self.save_document_button.setToolTip("Save the normalized document image to file")
1728+
actions_layout.addWidget(self.save_document_button)
1729+
17181730
clear_button = QPushButton("🗑️ Clear All")
17191731
clear_button.clicked.connect(self.clear_all)
17201732
actions_layout.addWidget(clear_button)
@@ -1916,6 +1928,24 @@ def on_detection_mode_changed(self, mode_text):
19161928
self.setWindowTitle(f"Dynamsoft Capture Vision - {current_mode} Scanner")
19171929
self.log_message(f"🔄 Switched to {current_mode} detection mode")
19181930

1931+
def on_picture_detection_mode_changed(self, mode_text):
1932+
"""Handle detection mode change in picture mode."""
1933+
mode_name = mode_text.split(" - ")[0] # Extract mode name from combo text
1934+
1935+
# Show/hide save document button based on mode
1936+
if hasattr(self, 'save_document_button'):
1937+
if mode_name == "Document":
1938+
self.save_document_button.setVisible(True)
1939+
# Enable button only if we have a normalized document for current page
1940+
has_normalized = (hasattr(self, 'current_normalized_documents') and
1941+
self.current_page_index in self.current_normalized_documents)
1942+
self.save_document_button.setEnabled(has_normalized)
1943+
else:
1944+
self.save_document_button.setVisible(False)
1945+
self.save_document_button.setEnabled(False)
1946+
1947+
self.log_message(f"🔄 Picture mode switched to {mode_name} detection")
1948+
19191949
def on_tab_changed(self, index):
19201950
"""Handle tab change events."""
19211951
if index == 0: # Picture mode
@@ -2616,6 +2646,10 @@ def display_document_results(self, original_image, document_items):
26162646
try:
26172647
if not document_items:
26182648
self.image_widget.set_image(original_image, [])
2649+
# Clear stored normalized document
2650+
if self.current_page_index in self.current_normalized_documents:
2651+
del self.current_normalized_documents[self.current_page_index]
2652+
self.save_document_button.setEnabled(False)
26192653
return
26202654

26212655
# Create annotated original image
@@ -2649,6 +2683,10 @@ def display_document_results(self, original_image, document_items):
26492683
if normalized_image_data:
26502684
normalized_image = convertImageData2Mat(normalized_image_data)
26512685

2686+
# Store normalized document for saving
2687+
self.current_normalized_documents[self.current_page_index] = normalized_image
2688+
self.save_document_button.setEnabled(True)
2689+
26522690
# Create side-by-side display
26532691
combined_image = self.create_side_by_side_display(annotated_original, normalized_image)
26542692
self.image_widget.set_image(combined_image, []) # No additional annotations needed
@@ -2658,6 +2696,10 @@ def display_document_results(self, original_image, document_items):
26582696

26592697
# Fallback: just show original with boundaries if normalized image extraction fails
26602698
self.image_widget.set_image(annotated_original, [])
2699+
# Clear stored normalized document and disable save button
2700+
if self.current_page_index in self.current_normalized_documents:
2701+
del self.current_normalized_documents[self.current_page_index]
2702+
self.save_document_button.setEnabled(False)
26612703

26622704
except Exception as e:
26632705
print(f"Error in document display: {e}")
@@ -2715,6 +2757,47 @@ def create_side_by_side_display(self, original_image, normalized_image):
27152757
print(f"Error creating side-by-side display: {e}")
27162758
return original_image
27172759

2760+
def save_normalized_document(self):
2761+
"""Save the current normalized document image to file."""
2762+
if self.current_page_index not in self.current_normalized_documents:
2763+
QMessageBox.warning(self, "No Document", "No normalized document available to save.")
2764+
return
2765+
2766+
try:
2767+
normalized_image = self.current_normalized_documents[self.current_page_index]
2768+
2769+
# Generate default filename
2770+
if self.current_file_path:
2771+
base_name = os.path.splitext(os.path.basename(self.current_file_path))[0]
2772+
if len(self.current_pages) > 1:
2773+
default_name = f"{base_name}_page{self.current_page_index + 1}_normalized.jpg"
2774+
else:
2775+
default_name = f"{base_name}_normalized.jpg"
2776+
else:
2777+
default_name = f"normalized_document_page{self.current_page_index + 1}.jpg"
2778+
2779+
# Show save dialog
2780+
file_path, _ = QFileDialog.getSaveFileName(
2781+
self,
2782+
"Save Normalized Document",
2783+
default_name,
2784+
"JPEG files (*.jpg);;PNG files (*.png);;BMP files (*.bmp);;TIFF files (*.tiff);;All files (*.*)"
2785+
)
2786+
2787+
if file_path:
2788+
# Save the image
2789+
success = cv2.imwrite(file_path, normalized_image)
2790+
if success:
2791+
self.log_message(f"💾 Normalized document saved: {os.path.basename(file_path)}")
2792+
QMessageBox.information(self, "Save Complete",
2793+
f"Normalized document saved successfully to:\n{file_path}")
2794+
else:
2795+
raise Exception("Failed to write image file")
2796+
2797+
except Exception as e:
2798+
self.log_message(f"❌ Save error: {e}")
2799+
QMessageBox.critical(self, "Save Error", f"Failed to save normalized document: {e}")
2800+
27182801
def display_page_results(self):
27192802
"""Display detection results for the current page."""
27202803
self.results_text.clear()
@@ -3170,6 +3253,10 @@ def clear_all(self):
31703253
self.page_results = {}
31713254
self.current_page_index = 0
31723255

3256+
# Clear normalized documents
3257+
if hasattr(self, 'current_normalized_documents'):
3258+
self.current_normalized_documents.clear()
3259+
31733260
# Clear custom receiver
31743261
if self.custom_receiver:
31753262
self.custom_receiver.images.clear()
@@ -3187,6 +3274,8 @@ def clear_all(self):
31873274
self.process_button.setEnabled(False)
31883275
self.export_button.setEnabled(False)
31893276
self.copy_button.setEnabled(False)
3277+
if hasattr(self, 'save_document_button'):
3278+
self.save_document_button.setEnabled(False)
31903279

31913280
# Hide navigation
31923281
self.nav_group.hide()

0 commit comments

Comments
 (0)