Skip to content

Commit c6bfa27

Browse files
authored
Merge pull request #203 from zivid/2025-06-13-update-python-samples
Samples: Automatic updates to public repository
2 parents ce2064a + 4760ea4 commit c6bfa27

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+933
-870
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ from the camera can be used.
6363
- [camera\_user\_data](https://github.com/zivid/zivid-python-samples/tree/master/source/camera/info_util_other/camera_user_data.py) - Store user data on the Zivid camera.
6464
- [capture\_with\_diagnostics](https://github.com/zivid/zivid-python-samples/tree/master/source/camera/info_util_other/capture_with_diagnostics.py) - Capture point clouds, with color, from the Zivid camera,
6565
with settings from YML file and diagnostics enabled.
66+
- [context\_manager\_with\_zivid](https://github.com/zivid/zivid-python-samples/tree/master/source/camera/info_util_other/context_manager_with_zivid.py) - Sample showing how to use a context manager with Zivid
67+
Application and safely return processed data.
6668
- [firmware\_updater](https://github.com/zivid/zivid-python-samples/tree/master/source/camera/info_util_other/firmware_updater.py) - Update firmware on the Zivid camera.
6769
- [frame\_info](https://github.com/zivid/zivid-python-samples/tree/master/source/camera/info_util_other/frame_info.py) - Read frame info from the Zivid camera.
6870
- [get\_camera\_intrinsics](https://github.com/zivid/zivid-python-samples/tree/master/source/camera/info_util_other/get_camera_intrinsics.py) - Read intrinsic parameters from the Zivid camera (OpenCV

modules/pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ dependencies = [
1818
"matplotlib",
1919
"nptyping",
2020
"numpy",
21-
"open3d; python_version <= '3.11'",
21+
"open3d",
2222
"opencv-python",
23+
"pandas",
2324
"pyyaml",
2425
"pyqt5-sip==12.15.0",
2526
"pyqt5",

modules/zividsamples/gui/stitch_gui.py

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,37 +8,29 @@
88
99
"""
1010

11-
import sys
1211
from pathlib import Path
1312
from typing import Dict, List, Optional
1413

1514
import numpy as np
1615
import zivid
1716
from PyQt5.QtCore import pyqtSignal
1817
from PyQt5.QtGui import QImage
19-
from PyQt5.QtWidgets import QHBoxLayout, QMessageBox, QPushButton, QVBoxLayout, QWidget
18+
from PyQt5.QtWidgets import QHBoxLayout, QPushButton, QVBoxLayout, QWidget
2019
from zividsamples.gui.capture_at_pose_selection_widget import CaptureAtPose, CaptureAtPoseSelectionWidget
2120
from zividsamples.gui.hand_eye_configuration import HandEyeConfiguration
21+
from zividsamples.gui.pointcloud_visualizer import Open3DVisualizerWidget
2222
from zividsamples.gui.pose_widget import PoseWidget, PoseWidgetDisplayMode
2323
from zividsamples.gui.robot_control import RobotTarget
2424
from zividsamples.gui.rotation_format_configuration import RotationInformation
2525
from zividsamples.transformation_matrix import TransformationMatrix
2626

27-
if sys.version_info < (3, 12):
28-
from zividsamples.gui.pointcloud_visualizer import Open3DVisualizerWidget
29-
3027

3128
class StitchGUI(QWidget):
3229
data_directory: Path
3330
use_robot: bool
3431
qimage_rgba: Optional[QImage] = None
3532
hand_eye_configuration: HandEyeConfiguration
36-
if sys.version_info < (3, 12):
37-
point_cloud_widget: Optional[Open3DVisualizerWidget] = None
38-
show_warning_once: bool = False
39-
else:
40-
point_cloud_widget = None
41-
show_warning_once: bool = True
33+
point_cloud_widget: Optional[Open3DVisualizerWidget] = None
4234
has_detection_result: bool = False
4335
has_confirmed_robot_pose: bool = False
4436
instructions_updated: pyqtSignal = pyqtSignal()
@@ -141,21 +133,7 @@ def stop_3d_visualizer(self):
141133

142134
def start_3d_visualizer(self):
143135
self.stop_3d_visualizer()
144-
if sys.version_info < (3, 12):
145-
self.point_cloud_widget = Open3DVisualizerWidget()
146-
elif self.show_warning_once:
147-
folder_path = self.capture_at_pose_selection_widget.directory
148-
QMessageBox.warning(
149-
self,
150-
"Visualization",
151-
f"""\
152-
Visualizing the point cloud requires Python 3.11 or earlier.
153-
154-
All transformed captures will be saved as .ply files in the folder:
155-
156-
{folder_path.as_posix()}""",
157-
)
158-
self.show_warning_once = False
136+
self.point_cloud_widget = Open3DVisualizerWidget()
159137
self.update_stitched_view()
160138

161139
def hand_eye_configuration_update(self, hand_eye_configuration: HandEyeConfiguration):

source/applications/advanced/auto_2d_settings.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,11 @@ def _find_white_mask_and_distance_to_checkerboard(camera: zivid.Camera) -> Tuple
132132
"""
133133
try:
134134
frame = zivid.calibration.capture_calibration_board(camera)
135-
136135
checkerboard_pose = zivid.calibration.detect_calibration_board(frame).pose().to_matrix()
137136
distance_to_checkerboard = checkerboard_pose[2, 3]
138-
139-
rgb = frame.point_cloud().copy_data("rgba_srgb")[:, :, :3]
137+
rgb = frame.point_cloud().copy_data("rgba_sgrb")[:, :, :3]
140138
white_squares_mask = find_white_mask_from_checkerboard(rgb)
139+
141140
except RuntimeError as exc:
142141
raise RuntimeError("Unable to find checkerboard, make sure it is in view of the camera.") from exc
143142

source/applications/advanced/create_depth_map.py

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -64,25 +64,28 @@ def _visualize_and_save_image(image: np.ndarray, image_file: str, title: str) ->
6464

6565

6666
def _main() -> None:
67-
with zivid.Application():
68-
data_file = get_sample_data_path() / "Zivid3D.zdf"
69-
print(f"Reading ZDF frame from file: {data_file}")
70-
frame = zivid.Frame(data_file)
71-
point_cloud = frame.point_cloud()
67+
# Application class must be initialized before using other Zivid classes.
68+
app = zivid.Application() # noqa: F841 # pylint: disable=unused-variable
7269

73-
print("Converting to BGR image in OpenCV format")
74-
bgr = _point_cloud_to_cv_bgr(point_cloud)
70+
data_file = get_sample_data_path() / "Zivid3D.zdf"
71+
print(f"Reading ZDF frame from file: {data_file}")
7572

76-
bgr_image_file = "ImageRGB.png"
77-
print(f"Visualizing and saving BGR image to file: {bgr_image_file}")
78-
_visualize_and_save_image(bgr, bgr_image_file, "BGR image")
73+
frame = zivid.Frame(data_file)
74+
point_cloud = frame.point_cloud()
7975

80-
print("Converting to Depth map in OpenCV format")
81-
z_color_map = _point_cloud_to_cv_z(point_cloud)
76+
print("Converting to BGR image in OpenCV format")
77+
bgr = _point_cloud_to_cv_bgr(point_cloud)
8278

83-
depth_map_file = "DepthMap.png"
84-
print(f"Visualizing and saving Depth map to file: {depth_map_file}")
85-
_visualize_and_save_image(z_color_map, depth_map_file, "Depth map")
79+
bgr_image_file = "ImageRGB.png"
80+
print(f"Visualizing and saving BGR image to file: {bgr_image_file}")
81+
_visualize_and_save_image(bgr, bgr_image_file, "BGR image")
82+
83+
print("Converting to Depth map in OpenCV format")
84+
z_color_map = _point_cloud_to_cv_z(point_cloud)
85+
86+
depth_map_file = "DepthMap.png"
87+
print(f"Visualizing and saving Depth map to file: {depth_map_file}")
88+
_visualize_and_save_image(z_color_map, depth_map_file, "Depth map")
8689

8790

8891
if __name__ == "__main__":

source/applications/advanced/downsample.py

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,38 +34,40 @@ def _options() -> argparse.Namespace:
3434

3535

3636
def _main() -> None:
37-
with zivid.Application():
38-
user_options = _options()
39-
data_file = user_options.zdf_path
37+
# Application class must be initialized before using other Zivid classes.
38+
app = zivid.Application() # noqa: F841 # pylint: disable=unused-variable
4039

41-
print(f"Reading ZDF frame from file: {data_file}")
42-
frame = zivid.Frame(data_file)
40+
user_options = _options()
41+
data_file = user_options.zdf_path
4342

44-
point_cloud = frame.point_cloud()
45-
xyz = point_cloud.copy_data("xyz")
46-
rgba = point_cloud.copy_data("rgba_srgb")
43+
print(f"Reading ZDF frame from file: {data_file}")
44+
frame = zivid.Frame(data_file)
4745

48-
print(f"Before downsampling: {point_cloud.width * point_cloud.height} point cloud")
46+
point_cloud = frame.point_cloud()
47+
xyz = point_cloud.copy_data("xyz")
48+
rgba = point_cloud.copy_data("rgba_sgrb")
4949

50-
display_pointcloud(xyz, rgba[:, :, 0:3])
50+
print(f"Before downsampling: {point_cloud.width * point_cloud.height} point cloud")
5151

52-
print("Downsampling point cloud")
53-
print("This does not modify the current point cloud but returns")
54-
print("the downsampled point cloud as a new point cloud instance.")
55-
downsampled_point_cloud = point_cloud.downsampled(zivid.PointCloud.Downsampling.by2x2)
52+
display_pointcloud(xyz, rgba[:, :, 0:3])
5653

57-
print(f"After downsampling: {downsampled_point_cloud.width * downsampled_point_cloud.height} point cloud")
54+
print("Downsampling point cloud")
55+
print("This does not modify the current point cloud but returns")
56+
print("the downsampled point cloud as a new point cloud instance.")
57+
downsampled_point_cloud = point_cloud.downsampled(zivid.PointCloud.Downsampling.by2x2)
5858

59-
print("Downsampling point cloud (in-place)")
60-
print("This modifies the current point cloud.")
61-
point_cloud.downsample(zivid.PointCloud.Downsampling.by2x2)
59+
print(f"After downsampling: {downsampled_point_cloud.width * downsampled_point_cloud.height} point cloud")
6260

63-
xyz_donwsampled = point_cloud.copy_data("xyz")
64-
rgba_downsampled = point_cloud.copy_data("rgba_srgb")
61+
print("Downsampling point cloud (in-place)")
62+
print("This modifies the current point cloud.")
63+
point_cloud.downsample(zivid.PointCloud.Downsampling.by2x2)
6564

66-
print(f"After downsampling: {point_cloud.width * point_cloud.height} point cloud")
65+
xyz_donwsampled = point_cloud.copy_data("xyz")
66+
rgba_downsampled = point_cloud.copy_data("rgba_srgb")
6767

68-
display_pointcloud(xyz_donwsampled, rgba_downsampled[:, :, 0:3])
68+
print(f"After downsampling: {point_cloud.width * point_cloud.height} point cloud")
69+
70+
display_pointcloud(xyz_donwsampled, rgba_downsampled[:, :, 0:3])
6971

7072

7173
if __name__ == "__main__":

source/applications/advanced/gamma_correction.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ def _capture_bgr_image(camera: zivid.Camera, gamma: float) -> np.ndarray:
4646
settings_2d.processing.color.gamma = gamma
4747

4848
print("Capturing 2D frame")
49-
with camera.capture_2d(settings_2d) as frame_2d:
50-
image = frame_2d.image_bgra_srgb()
51-
bgra = image.copy_data()
52-
return bgra[:, :, :3]
49+
frame_2d = camera.capture_2d(settings_2d)
50+
image = frame_2d.image_bgra_srgb()
51+
bgra = image.copy_data()
52+
return bgra[:, :, :3]
5353

5454

5555
def _combine_images(image_one: np.ndarray, image_two: np.ndarray) -> np.ndarray:

source/applications/advanced/get_checkerboard_pose_from_zdf.py

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -65,26 +65,29 @@ def _visualize_checkerboard_point_cloud_with_coordinate_system(
6565

6666

6767
def _main() -> None:
68-
with zivid.Application():
69-
data_file = get_sample_data_path() / "CalibrationBoardInCameraOrigin.zdf"
70-
print(f"Reading ZDF frame from file: {data_file}")
71-
frame = zivid.Frame(data_file)
72-
point_cloud = frame.point_cloud()
73-
74-
print("Detecting checkerboard and estimating its pose in camera frame")
75-
camera_to_checkerboard_transform = zivid.calibration.detect_calibration_board(frame).pose().to_matrix()
76-
print(f"Camera pose in checkerboard frame:\n{camera_to_checkerboard_transform}")
77-
78-
transform_file_name = "CameraToCheckerboardTransform.yaml"
79-
print(f"Saving detected checkerboard pose to YAML file: {transform_file_name}")
80-
transform_file_path = Path(__file__).parent / transform_file_name
81-
assert_affine_matrix_and_save(camera_to_checkerboard_transform, transform_file_path)
82-
83-
print("Visualizing checkerboard with coordinate system")
84-
checkerboard_point_cloud = _create_open3d_point_cloud(point_cloud)
85-
_visualize_checkerboard_point_cloud_with_coordinate_system(
86-
checkerboard_point_cloud, camera_to_checkerboard_transform
87-
)
68+
# Application class must be initialized before using other Zivid classes.
69+
app = zivid.Application() # noqa: F841 # pylint: disable=unused-variable
70+
71+
data_file = get_sample_data_path() / "CalibrationBoardInCameraOrigin.zdf"
72+
print(f"Reading ZDF frame from file: {data_file}")
73+
74+
frame = zivid.Frame(data_file)
75+
point_cloud = frame.point_cloud()
76+
77+
print("Detecting checkerboard and estimating its pose in camera frame")
78+
camera_to_checkerboard_transform = zivid.calibration.detect_calibration_board(frame).pose().to_matrix()
79+
print(f"Camera pose in checkerboard frame:\n{camera_to_checkerboard_transform}")
80+
81+
transform_file_name = "CameraToCheckerboardTransform.yaml"
82+
print(f"Saving detected checkerboard pose to YAML file: {transform_file_name}")
83+
transform_file_path = Path(__file__).parent / transform_file_name
84+
assert_affine_matrix_and_save(camera_to_checkerboard_transform, transform_file_path)
85+
86+
print("Visualizing checkerboard with coordinate system")
87+
checkerboard_point_cloud = _create_open3d_point_cloud(point_cloud)
88+
_visualize_checkerboard_point_cloud_with_coordinate_system(
89+
checkerboard_point_cloud, camera_to_checkerboard_transform
90+
)
8891

8992

9093
if __name__ == "__main__":

source/applications/advanced/hand_eye_calibration/pose_conversions.py

Lines changed: 49 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ class Representations:
8282
"""Class to hold various transformation representations."""
8383

8484
axis_angle: AxisAngle = AxisAngle()
85-
rotation_vector: np.ndarray = np.zeros(3)
86-
quaternion: np.ndarray = np.zeros(4)
85+
rotation_vector: np.ndarray = field(default_factory=lambda: np.zeros(3))
86+
quaternion: np.ndarray = field(default_factory=lambda: np.zeros(4))
8787
rotations: list = field(default_factory=list)
8888

8989

@@ -216,51 +216,53 @@ def print_header(txt: str) -> None:
216216

217217

218218
def _main() -> None:
219-
with zivid.Application():
220-
np.set_printoptions(precision=4, suppress=True)
221-
print_header("This example shows conversions to/from Transformation Matrix")
222-
223-
transformation_matrix = load_and_assert_affine_matrix(get_sample_data_path() / "RobotTransform.yaml")
224-
print(f"Transformation Matrix:\n{transformation_matrix}")
225-
226-
# Extract Rotation Matrix and Translation Vector from Transformation Matrix
227-
rotation_matrix = transformation_matrix[:3, :3]
228-
translation_vector = transformation_matrix[:-1, -1]
229-
print(f"Rotation Matrix:\n{rotation_matrix}")
230-
print(f"Translation Vector:\n{translation_vector}")
231-
232-
###
233-
# Convert from Zivid to Robot (Transformation Matrix --> any format)
234-
###
235-
print_header("Convert from Zivid (Rotation Matrix) to Robot")
236-
axis_angle = rotation_matrix_to_axis_angle(rotation_matrix)
237-
print(f"AxisAngle:\n{axis_angle.axis}, {axis_angle.angle:.4f}")
238-
rotation_vector = rotation_matrix_to_rotation_vector(rotation_matrix)
239-
print(f"Rotation Vector:\n{rotation_vector}")
240-
quaternion = rotation_matrix_to_quaternion(rotation_matrix)
241-
print(f"Quaternion:\n{quaternion}")
242-
rpy_list = rotation_matrix_to_roll_pitch_yaw(rotation_matrix)
243-
244-
###
245-
# Convert from Robot to Zivid (any format --> Rotation Matrix (part of Transformation Matrix))
246-
###
247-
print_header("Convert from Robot to Zivid (Rotation Matrix)")
248-
rotation_matrix_from_axis_angle = axis_angle_to_rotation_matrix(axis_angle)
249-
print(f"Rotation Matrix from Axis Angle:\n{rotation_matrix_from_axis_angle}")
250-
rotation_matrix_from_rotation_vector = rotation_vector_to_rotation_matrix(rotation_vector)
251-
print(f"Rotation Matrix from Rotation Vector:\n{rotation_matrix_from_rotation_vector}")
252-
rotation_matrix_from_quaternion = quaternion_to_rotation_matrix(quaternion)
253-
print(f"Rotation Matrix from Quaternion:\n{rotation_matrix_from_quaternion}")
254-
roll_pitch_yaw_to_rotation_matrix(rpy_list)
255-
256-
# Replace rotation matrix in transformation matrix
257-
transformation_matrix_from_quaternion = np.eye(4)
258-
transformation_matrix_from_quaternion[:3, :3] = rotation_matrix_from_quaternion
259-
transformation_matrix_from_quaternion[:-1, -1] = translation_vector
260-
# Save transformation matrix which has passed through quaternion representation
261-
assert_affine_matrix_and_save(
262-
transformation_matrix_from_quaternion, Path(__file__).parent / "RobotTransformOut.yaml"
263-
)
219+
# Application class must be initialized before using other Zivid classes.
220+
app = zivid.Application() # noqa: F841 # pylint: disable=unused-variable
221+
222+
np.set_printoptions(precision=4, suppress=True)
223+
print_header("This example shows conversions to/from Transformation Matrix")
224+
225+
transformation_matrix = load_and_assert_affine_matrix(get_sample_data_path() / "RobotTransform.yaml")
226+
print(f"Transformation Matrix:\n{transformation_matrix}")
227+
228+
# Extract Rotation Matrix and Translation Vector from Transformation Matrix
229+
rotation_matrix = transformation_matrix[:3, :3]
230+
translation_vector = transformation_matrix[:-1, -1]
231+
print(f"Rotation Matrix:\n{rotation_matrix}")
232+
print(f"Translation Vector:\n{translation_vector}")
233+
234+
###
235+
# Convert from Zivid to Robot (Transformation Matrix --> any format)
236+
###
237+
print_header("Convert from Zivid (Rotation Matrix) to Robot")
238+
axis_angle = rotation_matrix_to_axis_angle(rotation_matrix)
239+
print(f"AxisAngle:\n{axis_angle.axis}, {axis_angle.angle:.4f}")
240+
rotation_vector = rotation_matrix_to_rotation_vector(rotation_matrix)
241+
print(f"Rotation Vector:\n{rotation_vector}")
242+
quaternion = rotation_matrix_to_quaternion(rotation_matrix)
243+
print(f"Quaternion:\n{quaternion}")
244+
rpy_list = rotation_matrix_to_roll_pitch_yaw(rotation_matrix)
245+
246+
###
247+
# Convert from Robot to Zivid (any format --> Rotation Matrix (part of Transformation Matrix))
248+
###
249+
print_header("Convert from Robot to Zivid (Rotation Matrix)")
250+
rotation_matrix_from_axis_angle = axis_angle_to_rotation_matrix(axis_angle)
251+
print(f"Rotation Matrix from Axis Angle:\n{rotation_matrix_from_axis_angle}")
252+
rotation_matrix_from_rotation_vector = rotation_vector_to_rotation_matrix(rotation_vector)
253+
print(f"Rotation Matrix from Rotation Vector:\n{rotation_matrix_from_rotation_vector}")
254+
rotation_matrix_from_quaternion = quaternion_to_rotation_matrix(quaternion)
255+
print(f"Rotation Matrix from Quaternion:\n{rotation_matrix_from_quaternion}")
256+
roll_pitch_yaw_to_rotation_matrix(rpy_list)
257+
258+
# Replace rotation matrix in transformation matrix
259+
transformation_matrix_from_quaternion = np.eye(4)
260+
transformation_matrix_from_quaternion[:3, :3] = rotation_matrix_from_quaternion
261+
transformation_matrix_from_quaternion[:-1, -1] = translation_vector
262+
# Save transformation matrix which has passed through quaternion representation
263+
assert_affine_matrix_and_save(
264+
transformation_matrix_from_quaternion, Path(__file__).parent / "RobotTransformOut.yaml"
265+
)
264266

265267

266268
if __name__ == "__main__":

0 commit comments

Comments
 (0)