diff --git a/dev/demo/demo_playback_widget.py b/dev/demo/demo_playback_widget.py index ab0dd1019..e8a9c4e61 100644 --- a/dev/demo/demo_playback_widget.py +++ b/dev/demo/demo_playback_widget.py @@ -16,9 +16,6 @@ original_workspace_dir = Path( __root__, "tests", "sessions", "prerecorded_calibration" ) -# workspace_dir = Path( -# __root__, "tests", "sessions_copy_delete", "prerecorded_calibration" -# ) # copy_contents(original_workspace_dir, workspace_dir) workspace_dir = Path(r"C:\Users\Mac Prible\OneDrive\pyxy3d\prerecorded_workflow") diff --git a/pyxy3d/gui/frame_emitters/playback_frame_emitter.py b/pyxy3d/gui/frame_emitters/playback_frame_emitter.py index 23d1634bc..74fe8241d 100644 --- a/pyxy3d/gui/frame_emitters/playback_frame_emitter.py +++ b/pyxy3d/gui/frame_emitters/playback_frame_emitter.py @@ -26,6 +26,10 @@ def __init__(self, recorded_stream: RecordedStream, pixmap_edge_length=500): super(PlaybackFrameEmitter, self).__init__() self.stream = recorded_stream self.port = self.stream.port + + # Apply a safety margin to the scaling factors (e.g., 5%) + # used only when applying the undistortion + self.scaling_factor = 1 self.frame_packet_q = Queue() self.stream.subscribe(self.frame_packet_q) @@ -87,17 +91,25 @@ def run(self): def stop(self): self.keep_collecting = False self.quit() + + def set_scale_factor(self, scaling_factor): + self.scaling_factor = scaling_factor - def update_distortion_params(self, undistort, matrix, distortions): + if hasattr(self, "matrix") and hasattr(self, "distortions"): + self.update_distortion_params(self.undistort,self.matrix, self.distortions) + + def update_distortion_params(self, undistort=None, matrix=None, distortions=None): if matrix is None: logger.info(f"No camera matrix calculated yet at port {self.port}") else: logger.info( f"Updating camera matrix and distortion parameters for frame emitter at port {self.port}" ) + self.undistort = undistort self.matrix = matrix self.distortions = distortions + h, w = self.stream.size # h, w = original_image_size initial_new_matrix, valid_roi = cv2.getOptimalNewCameraMatrix( @@ -133,8 +145,6 @@ def update_distortion_params(self, undistort, matrix, distortions): scale_x = (max_x - min_x) / w scale_y = (max_y - min_y) / h - # Apply a safety margin to the scaling factors (e.g., 5%) - self.scaling_factor = 0.95 scale_x *= self.scaling_factor scale_y *= self.scaling_factor diff --git a/pyxy3d/gui/prerecorded_intrinsic_calibration/playback_widget.py b/pyxy3d/gui/prerecorded_intrinsic_calibration/playback_widget.py index f6a63c369..d8d55c2df 100644 --- a/pyxy3d/gui/prerecorded_intrinsic_calibration/playback_widget.py +++ b/pyxy3d/gui/prerecorded_intrinsic_calibration/playback_widget.py @@ -4,6 +4,7 @@ from pathlib import Path from PySide6.QtWidgets import ( QApplication, + QSpinBox, QMainWindow, QCheckBox, QWidget, @@ -98,7 +99,13 @@ def __init__(self, controller: Controller, port: int, parent=None): self.ccw_rotation_btn = QPushButton(QIcon(str(CAM_ROTATE_LEFT_PATH)), "") self.ccw_rotation_btn.setMaximumSize(35, 35) - # self.ccw_rotation_btn.setMaximumSize(35, 35) + + # Create the spinbox + self.spin_box_label = QLabel("Undistorted Image Scale") + self.scaling_spinBox = QSpinBox(self) + self.scaling_spinBox.setRange(50, 150) + self.scaling_spinBox.setValue(100) + self.scaling_spinBox.setSingleStep(5) self.is_playing = False @@ -120,16 +127,23 @@ def place_widgets(self): self.right_panel.addLayout(self.rotate_span) self.play_span = QHBoxLayout() - self.play_span.addWidget(self.play_button, stretch=1) - self.play_span.addWidget(self.slider, stretch=4) + self.play_span.addWidget(self.play_button) + self.play_button.setMaximumWidth(35) + self.play_span.addWidget(self.slider) self.right_panel.addLayout(self.play_span) - # self.right_panel.addWidget(self.play_button) - # self.right_panel.addWidget(self.slider) - self.right_panel.addWidget(self.add_grid_btn) - self.right_panel.addWidget(self.calibrate_btn) - self.right_panel.addWidget(self.clear_calibration_data_btn) - self.right_panel.addWidget(self.frame_index_label) - self.right_panel.addWidget(self.toggle_distortion) + + self.calibration_control_span = QHBoxLayout() + self.calibration_control_span.addWidget(self.add_grid_btn) + self.calibration_control_span.addWidget(self.calibrate_btn) + self.calibration_control_span.addWidget(self.clear_calibration_data_btn) + self.right_panel.addLayout(self.calibration_control_span) + + self.distortion_control_span = QHBoxLayout() + self.distortion_control_span.addWidget(self.frame_index_label) + self.distortion_control_span.addWidget(self.toggle_distortion) + self.distortion_control_span.addWidget(self.scaling_spinBox) + self.distortion_control_span.addWidget(self.spin_box_label) + self.right_panel.addLayout(self.distortion_control_span) self.layout.addLayout(self.right_panel) def connect_widgets(self): @@ -142,7 +156,8 @@ def connect_widgets(self): self.toggle_distortion.stateChanged.connect(self.toggle_distortion_changed) self.ccw_rotation_btn.clicked.connect(self.rotate_ccw) self.cw_rotation_btn.clicked.connect(self.rotate_cw) - + + self.scaling_spinBox.valueChanged.connect(self.on_scale_change) # self.controller.connect_frame_emitter(self.port, self.update_image,self.update_index) self.controller.IntrinsicImageUpdate.connect(self.update_image) self.controller.IndexUpdate.connect(self.update_index) @@ -206,6 +221,15 @@ def add_grid(self): self.controller.add_calibration_grid(self.port, self.index) self.controller.stream_jump_to(self.port, self.index) + def on_scale_change(self, value): + """ + Way too much starting to happen here, but there we are... + """ + new_scale = value/100 + logger.info(f"Changing frame_emitter scale factor to {new_scale}") + self.controller.frame_emitters[self.port].set_scale_factor(new_scale) + self.controller.stream_jump_to(self.port, self.index) + def calibrate(self): self.controller.calibrate_camera(self.port) self.toggle_distortion_changed(2)