diff --git a/README.md b/README.md index a0add0d2..669daf9b 100644 --- a/README.md +++ b/README.md @@ -186,7 +186,7 @@ from the camera can be used. - [save\_load\_transformation\_matrix](https://github.com/zivid/zivid-python-samples/tree/master/modules/zividsamples/save_load_transformation_matrix.py) - assert\_affine\_matrix\_and\_save(transformation\_matrix.as\_matrix(), yaml\_path) - - [settings\_utils](https://github.com/zivid/zivid-python-samples/tree/master/modules/zividsamples/settings_utils.py) - categories = zivid.presets.categories2d(camera.info.model) + - [save\_residuals](https://github.com/zivid/zivid-python-samples/tree/master/modules/zividsamples/save_residuals.py) - per\_pose\_residuals = \[ - [settings\_utils](https://github.com/zivid/zivid-python-samples/tree/master/modules/zividsamples/settings_utils.py) - categories = zivid.presets.categories2d(camera.info.model) - [transformation\_matrix](https://github.com/zivid/zivid-python-samples/tree/master/modules/zividsamples/transformation_matrix.py) - Convenience functions and a class for 4x4 transformation matrices. - [white\_balance\_calibration](https://github.com/zivid/zivid-python-samples/tree/master/modules/zividsamples/white_balance_calibration.py) - Balance color for 2D capture using white surface as diff --git a/modules/zividsamples/gui/hand_eye_calibration_gui.py b/modules/zividsamples/gui/hand_eye_calibration_gui.py index 23f908d4..19846f57 100644 --- a/modules/zividsamples/gui/hand_eye_calibration_gui.py +++ b/modules/zividsamples/gui/hand_eye_calibration_gui.py @@ -31,6 +31,7 @@ from zividsamples.gui.show_yaml_dialog import show_yaml_dialog from zividsamples.gui.tab_with_robot_support import TabWidgetWithRobotSupport from zividsamples.save_load_transformation_matrix import load_transformation_matrix, save_transformation_matrix +from zividsamples.save_residuals import save_residuals from zividsamples.transformation_matrix import TransformationMatrix @@ -325,6 +326,10 @@ def on_calibrate_button_clicked(self): hand_eye_transformation_matrix = TransformationMatrix.from_matrix(calibration_result.transform()) hand_eye_transform_path = self.data_directory / "hand_eye_transform.yaml" save_transformation_matrix(hand_eye_transformation_matrix, hand_eye_transform_path) + + hand_eye_residuals_path = self.data_directory / "hand_eye_residuals.yaml" + save_residuals(calibration_result.residuals(), hand_eye_residuals_path) + self.pose_pair_selection_widget.set_residuals(calibration_result.residuals()) show_yaml_dialog(hand_eye_transform_path, "Hand Eye Calibration Transform") self.update_instructions( diff --git a/modules/zividsamples/save_residuals.py b/modules/zividsamples/save_residuals.py new file mode 100644 index 00000000..a0df9e32 --- /dev/null +++ b/modules/zividsamples/save_residuals.py @@ -0,0 +1,26 @@ +from pathlib import Path +from typing import Iterable + +import yaml + + +def save_residuals(residuals: Iterable, yaml_path: Path) -> None: + """Save per-pose hand-eye residuals to a YAML file. + + Args: + residuals: Iterable of residual objects with `rotation()` and `translation()` methods. + yaml_path: Destination YAML file path. + + """ + per_pose_residuals = [ + { + "rotation_deg": float(r.rotation()), + "translation_mm": float(r.translation()), + } + for r in residuals + ] + + data = {"per_pose_residuals": per_pose_residuals} + + with open(yaml_path, "w", encoding="utf-8") as file: + yaml.safe_dump(data, file, sort_keys=False)