pyorbbec 1.0.1.6__py3-none-any.whl → 1.0.1.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyorbbec-1.0.1.6.dist-info → pyorbbec-1.0.1.8.dist-info}/METADATA +1 -1
- pyorbbec-1.0.1.8.dist-info/RECORD +59 -0
- pyorbbecsdk/OrbbecSDKConfig.xml +2332 -0
- pyorbbecsdk/examples/.gitkeep +0 -0
- pyorbbecsdk/examples/OrbbecSDK.dll +0 -0
- pyorbbecsdk/examples/OrbbecSDK.lib +0 -0
- pyorbbecsdk/examples/README.md +26 -0
- pyorbbecsdk/examples/__pycache__/utils.cpython-313.pyc +0 -0
- pyorbbecsdk/examples/callback.py +303 -0
- pyorbbecsdk/examples/color.py +64 -0
- pyorbbecsdk/examples/coordinate_transform.py +184 -0
- pyorbbecsdk/examples/depth.py +107 -0
- pyorbbecsdk/examples/depth_work_mode.py +50 -0
- pyorbbecsdk/examples/device_firmware_update.py +155 -0
- pyorbbecsdk/examples/device_optional_depth_presets_update.py +142 -0
- pyorbbecsdk/examples/enumerate.py +118 -0
- pyorbbecsdk/examples/extensions/depthengine/depthengine.dll +0 -0
- pyorbbecsdk/examples/extensions/depthengine/depthengine.lib +0 -0
- pyorbbecsdk/examples/extensions/filters/FilterProcessor.dll +0 -0
- pyorbbecsdk/examples/extensions/filters/ob_priv_filter.dll +0 -0
- pyorbbecsdk/examples/extensions/firmwareupdater/firmwareupdater.dll +0 -0
- pyorbbecsdk/examples/extensions/frameprocessor/ob_frame_processor.dll +0 -0
- pyorbbecsdk/examples/hdr.py +216 -0
- pyorbbecsdk/examples/hot_plug.py +160 -0
- pyorbbecsdk/examples/hw_d2c_align.py +135 -0
- pyorbbecsdk/examples/imu.py +60 -0
- pyorbbecsdk/examples/infrared.py +115 -0
- pyorbbecsdk/examples/logger.py +55 -0
- pyorbbecsdk/examples/metadata.py +64 -0
- pyorbbecsdk/examples/multi_device.py +169 -0
- pyorbbecsdk/examples/multi_streams.py +219 -0
- pyorbbecsdk/examples/net_device.py +158 -0
- pyorbbecsdk/examples/playback.py +277 -0
- pyorbbecsdk/examples/point_cloud.py +90 -0
- pyorbbecsdk/examples/post_processing.py +119 -0
- pyorbbecsdk/examples/preset.py +67 -0
- pyorbbecsdk/examples/pyorbbecsdk.cp313-win_amd64.pyd +0 -0
- pyorbbecsdk/examples/quick_start.py +90 -0
- pyorbbecsdk/examples/recorder.py +236 -0
- pyorbbecsdk/examples/requirements.txt +9 -0
- pyorbbecsdk/examples/save_image_to_disk.py +106 -0
- pyorbbecsdk/examples/sync_align.py +109 -0
- pyorbbecsdk/examples/two_devices_sync.py +233 -0
- pyorbbecsdk/examples/utils.py +127 -0
- pyorbbec-1.0.1.6.dist-info/RECORD +0 -17
- {pyorbbec-1.0.1.6.dist-info → pyorbbec-1.0.1.8.dist-info}/WHEEL +0 -0
- {pyorbbec-1.0.1.6.dist-info → pyorbbec-1.0.1.8.dist-info}/licenses/LICENSE +0 -0
- {pyorbbec-1.0.1.6.dist-info → pyorbbec-1.0.1.8.dist-info}/licenses/NOTICE +0 -0
- {pyorbbec-1.0.1.6.dist-info → pyorbbec-1.0.1.8.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,107 @@
|
|
1
|
+
# ******************************************************************************
|
2
|
+
# Copyright (c) 2024 Orbbec 3D Technology, Inc
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http:# www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
# ******************************************************************************
|
16
|
+
import time
|
17
|
+
|
18
|
+
import cv2
|
19
|
+
import numpy as np
|
20
|
+
|
21
|
+
from pyorbbecsdk import *
|
22
|
+
|
23
|
+
ESC_KEY = 27
|
24
|
+
PRINT_INTERVAL = 1 # seconds
|
25
|
+
MIN_DEPTH = 20 # 20mm
|
26
|
+
MAX_DEPTH = 10000 # 10000mm
|
27
|
+
|
28
|
+
|
29
|
+
class TemporalFilter:
|
30
|
+
def __init__(self, alpha):
|
31
|
+
self.alpha = alpha
|
32
|
+
self.previous_frame = None
|
33
|
+
|
34
|
+
def process(self, frame):
|
35
|
+
if self.previous_frame is None:
|
36
|
+
result = frame
|
37
|
+
else:
|
38
|
+
result = cv2.addWeighted(frame, self.alpha, self.previous_frame, 1 - self.alpha, 0)
|
39
|
+
self.previous_frame = result
|
40
|
+
return result
|
41
|
+
|
42
|
+
|
43
|
+
def main():
|
44
|
+
config = Config()
|
45
|
+
pipeline = Pipeline()
|
46
|
+
temporal_filter = TemporalFilter(alpha=0.5)
|
47
|
+
try:
|
48
|
+
profile_list = pipeline.get_stream_profile_list(OBSensorType.DEPTH_SENSOR)
|
49
|
+
assert profile_list is not None
|
50
|
+
depth_profile = profile_list.get_default_video_stream_profile()
|
51
|
+
assert depth_profile is not None
|
52
|
+
print("depth profile: ", depth_profile)
|
53
|
+
config.enable_stream(depth_profile)
|
54
|
+
except Exception as e:
|
55
|
+
print(e)
|
56
|
+
return
|
57
|
+
pipeline.start(config)
|
58
|
+
last_print_time = time.time()
|
59
|
+
while True:
|
60
|
+
try:
|
61
|
+
frames = pipeline.wait_for_frames(100)
|
62
|
+
if frames is None:
|
63
|
+
continue
|
64
|
+
depth_frame = frames.get_depth_frame()
|
65
|
+
if depth_frame is None:
|
66
|
+
continue
|
67
|
+
depth_format = depth_frame.get_format()
|
68
|
+
if depth_format != OBFormat.Y16:
|
69
|
+
print("depth format is not Y16")
|
70
|
+
continue
|
71
|
+
width = depth_frame.get_width()
|
72
|
+
height = depth_frame.get_height()
|
73
|
+
scale = depth_frame.get_depth_scale()
|
74
|
+
|
75
|
+
depth_data = np.frombuffer(depth_frame.get_data(), dtype=np.uint16)
|
76
|
+
depth_data = depth_data.reshape((height, width))
|
77
|
+
|
78
|
+
depth_data = depth_data.astype(np.float32) * scale
|
79
|
+
depth_data = np.where((depth_data > MIN_DEPTH) & (depth_data < MAX_DEPTH), depth_data, 0)
|
80
|
+
depth_data = depth_data.astype(np.uint16)
|
81
|
+
# Apply temporal filtering
|
82
|
+
depth_data = temporal_filter.process(depth_data)
|
83
|
+
|
84
|
+
center_y = int(height / 2)
|
85
|
+
center_x = int(width / 2)
|
86
|
+
center_distance = depth_data[center_y, center_x]
|
87
|
+
|
88
|
+
current_time = time.time()
|
89
|
+
if current_time - last_print_time >= PRINT_INTERVAL:
|
90
|
+
print("center distance: ", center_distance)
|
91
|
+
last_print_time = current_time
|
92
|
+
|
93
|
+
depth_image = cv2.normalize(depth_data, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)
|
94
|
+
depth_image = cv2.applyColorMap(depth_image, cv2.COLORMAP_JET)
|
95
|
+
|
96
|
+
cv2.imshow("Depth Viewer", depth_image)
|
97
|
+
key = cv2.waitKey(1)
|
98
|
+
if key == ord('q') or key == ESC_KEY:
|
99
|
+
break
|
100
|
+
except KeyboardInterrupt:
|
101
|
+
break
|
102
|
+
cv2.destroyAllWindows()
|
103
|
+
pipeline.stop()
|
104
|
+
|
105
|
+
|
106
|
+
if __name__ == "__main__":
|
107
|
+
main()
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# ******************************************************************************
|
2
|
+
# Copyright (c) 2024 Orbbec 3D Technology, Inc
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http:# www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
# ******************************************************************************
|
16
|
+
from pyorbbecsdk import *
|
17
|
+
|
18
|
+
ESC = 27
|
19
|
+
|
20
|
+
|
21
|
+
def main():
|
22
|
+
pipeline = Pipeline()
|
23
|
+
assert pipeline is not None
|
24
|
+
device = pipeline.get_device()
|
25
|
+
assert device is not None
|
26
|
+
if not device.is_property_supported(OBPropertyID.OB_STRUCT_CURRENT_DEPTH_ALG_MODE,
|
27
|
+
OBPermissionType.PERMISSION_READ_WRITE):
|
28
|
+
print("Current device not support depth work mode!")
|
29
|
+
return
|
30
|
+
current_depth_work_mode = device.get_depth_work_mode()
|
31
|
+
assert current_depth_work_mode is not None
|
32
|
+
print("Current depth work mode: ", current_depth_work_mode)
|
33
|
+
depth_work_mode_list = device.get_depth_work_mode_list()
|
34
|
+
assert depth_work_mode_list is not None
|
35
|
+
for i in range(depth_work_mode_list.get_count()):
|
36
|
+
depth_work_mode = depth_work_mode_list.get_depth_work_mode_by_index(i)
|
37
|
+
assert depth_work_mode is not None
|
38
|
+
print("{}. {}".format(i, depth_work_mode))
|
39
|
+
if depth_work_mode_list.get_count() > 1:
|
40
|
+
index = int(input("Please input depth work mode index: "))
|
41
|
+
if depth_work_mode_list.get_count() > index >= 0:
|
42
|
+
select_depth_work_mode = depth_work_mode_list.get_depth_work_mode_by_index(index)
|
43
|
+
assert select_depth_work_mode is not None
|
44
|
+
device.set_depth_work_mode(select_depth_work_mode.name)
|
45
|
+
assert select_depth_work_mode == device.get_depth_work_mode()
|
46
|
+
print("Set depth work mode to {} success!".format(select_depth_work_mode))
|
47
|
+
|
48
|
+
|
49
|
+
if __name__ == '__main__':
|
50
|
+
main()
|
@@ -0,0 +1,155 @@
|
|
1
|
+
# ******************************************************************************
|
2
|
+
# Copyright (c) 2024 Orbbec 3D Technology, Inc
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http:# www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
# ******************************************************************************
|
16
|
+
|
17
|
+
import os
|
18
|
+
import sys
|
19
|
+
from pyorbbecsdk import *
|
20
|
+
|
21
|
+
devices = []
|
22
|
+
first_call = True
|
23
|
+
|
24
|
+
|
25
|
+
def get_firmware_path():
|
26
|
+
"""Prompt user for the firmware file path with improved Windows compatibility."""
|
27
|
+
while True:
|
28
|
+
firmware_path = input("Please input the path of the firmware file (.bin) to be updated (or 'q' to quit): ")
|
29
|
+
|
30
|
+
if firmware_path.lower() == 'q':
|
31
|
+
sys.exit("Exiting...")
|
32
|
+
|
33
|
+
# Clean up the input path
|
34
|
+
firmware_path = firmware_path.strip().strip("'").strip('"') # Remove quotes and extra spaces
|
35
|
+
|
36
|
+
# Normalize path separators for Windows compatibility
|
37
|
+
firmware_path = os.path.normpath(firmware_path)
|
38
|
+
|
39
|
+
try:
|
40
|
+
# Convert to absolute path with proper handling of relative paths
|
41
|
+
firmware_path = os.path.abspath(os.path.expanduser(firmware_path))
|
42
|
+
|
43
|
+
# Verify the file exists and has .bin extension
|
44
|
+
if os.path.isfile(firmware_path) and firmware_path.lower().endswith(".bin"):
|
45
|
+
# Try to open the file to verify access permissions
|
46
|
+
try:
|
47
|
+
with open(firmware_path, 'rb') as f:
|
48
|
+
pass
|
49
|
+
print(f"Firmware file confirmed: {firmware_path}\n")
|
50
|
+
return firmware_path
|
51
|
+
except PermissionError:
|
52
|
+
print("Error: Permission denied. Cannot access the specified file.\n")
|
53
|
+
except Exception as e:
|
54
|
+
print(f"Error accessing file: {str(e)}\n")
|
55
|
+
else:
|
56
|
+
print("Invalid file format or path. Please provide a valid .bin file.\n")
|
57
|
+
except Exception as e:
|
58
|
+
print(f"Error processing path: {str(e)}\n")
|
59
|
+
print("Please provide a valid file path.\n")
|
60
|
+
|
61
|
+
|
62
|
+
def print_device_list():
|
63
|
+
"""Print the list of connected devices."""
|
64
|
+
print("--------------------------------------------------------------------------------")
|
65
|
+
for i, device in enumerate(devices):
|
66
|
+
device_info = device.get_device_info()
|
67
|
+
print(
|
68
|
+
f"[{i}] Device: {device_info.get_name()} | SN: {device_info.get_serial_number()} | Firmware version: {device_info.get_firmware_version()}")
|
69
|
+
print("--------------------------------------------------------------------------------")
|
70
|
+
|
71
|
+
|
72
|
+
def select_device():
|
73
|
+
"""Allow user to select a device by index."""
|
74
|
+
while True:
|
75
|
+
choice = input(
|
76
|
+
"Please select a device to update the firmware, enter 'l' to list devices, or 'q' to quit: \n").strip()
|
77
|
+
|
78
|
+
if choice.lower() == 'q':
|
79
|
+
return None
|
80
|
+
|
81
|
+
if choice.lower() == 'l':
|
82
|
+
print_device_list()
|
83
|
+
continue
|
84
|
+
|
85
|
+
try:
|
86
|
+
index = int(choice)
|
87
|
+
if 0 <= index < len(devices):
|
88
|
+
print()
|
89
|
+
return index
|
90
|
+
else:
|
91
|
+
print("Invalid index. Please select a valid device index.")
|
92
|
+
except ValueError:
|
93
|
+
print("Invalid input. Please enter a numeric index.")
|
94
|
+
|
95
|
+
|
96
|
+
def firmware_update_callback(state, message, percent):
|
97
|
+
"""Callback function to report firmware update progress."""
|
98
|
+
global first_call
|
99
|
+
if first_call:
|
100
|
+
first_call = False
|
101
|
+
else:
|
102
|
+
print("\033[F\033[F", end="") # Move up two lines to overwrite previous output
|
103
|
+
|
104
|
+
print(f"Progress: {percent}%")
|
105
|
+
print(f"Status : {state}")
|
106
|
+
print(f"Message : {message}\n")
|
107
|
+
|
108
|
+
|
109
|
+
def main():
|
110
|
+
global first_call
|
111
|
+
try:
|
112
|
+
context = Context()
|
113
|
+
device_list = context.query_devices()
|
114
|
+
|
115
|
+
if device_list.get_count() == 0:
|
116
|
+
print("No device found. Please connect a device first!")
|
117
|
+
input("Press Enter to exit...")
|
118
|
+
return
|
119
|
+
|
120
|
+
for i in range(device_list.get_count()):
|
121
|
+
devices.append(device_list[i])
|
122
|
+
|
123
|
+
print("Devices found:")
|
124
|
+
print_device_list()
|
125
|
+
|
126
|
+
while True:
|
127
|
+
first_call = True
|
128
|
+
device_index = select_device()
|
129
|
+
|
130
|
+
if device_index is None:
|
131
|
+
break
|
132
|
+
|
133
|
+
firmware_path = get_firmware_path()
|
134
|
+
|
135
|
+
print("Upgrading device firmware, please wait...\n")
|
136
|
+
try:
|
137
|
+
devices[device_index].update_firmware(firmware_path, firmware_update_callback, async_update=False)
|
138
|
+
print("Firmware update completed successfully! Please reboot the device.")
|
139
|
+
except Exception as e:
|
140
|
+
print("\nThe upgrade was interrupted! An error occurred!")
|
141
|
+
print(f"Error message: {str(e)}")
|
142
|
+
input("Press Enter to exit...")
|
143
|
+
break
|
144
|
+
|
145
|
+
if input("Enter 'q' to quit, or any other key to continue: ").lower() == 'q':
|
146
|
+
break
|
147
|
+
|
148
|
+
except Exception as e:
|
149
|
+
print(f"Error: {str(e)}")
|
150
|
+
input("Press Enter to exit.")
|
151
|
+
sys.exit(1)
|
152
|
+
|
153
|
+
|
154
|
+
if __name__ == "__main__":
|
155
|
+
main()
|
@@ -0,0 +1,142 @@
|
|
1
|
+
import time
|
2
|
+
import sys
|
3
|
+
from pyorbbecsdk import *
|
4
|
+
|
5
|
+
# Callback function to display update progress
|
6
|
+
def preset_update_callback(first_call, state, message, percent):
|
7
|
+
if not first_call:
|
8
|
+
sys.stdout.write("\033[3F") # Move cursor up 3 lines
|
9
|
+
sys.stdout.write("\033[K") # Clear the current line
|
10
|
+
print(f"Progress: {percent}%")
|
11
|
+
sys.stdout.write("\033[K")
|
12
|
+
print(f"Status : {state}")
|
13
|
+
sys.stdout.write("\033[K")
|
14
|
+
print(f"Message : {message}\n", end='')
|
15
|
+
|
16
|
+
# Helper function to return the update state message
|
17
|
+
# def get_update_status(state):
|
18
|
+
# if state == OBFwUpdateState.STAT_VERIFY_SUCCESS:
|
19
|
+
# return "Image file verification success"
|
20
|
+
# elif state == OBFwUpdateState.STAT_FILE_TRANSFER:
|
21
|
+
# return "File transfer in progress"
|
22
|
+
# elif state == OBFwUpdateState.STAT_DONE:
|
23
|
+
# return "Update completed"
|
24
|
+
# elif state == OBFwUpdateState.STAT_DONE_WITH_DUPLICATES:
|
25
|
+
# return "Update completed, duplicated presets have been ignored"
|
26
|
+
# elif state == OBFwUpdateState.STAT_IN_PROGRESS:
|
27
|
+
# return "Update in progress"
|
28
|
+
# elif state == OBFwUpdateState.STAT_START:
|
29
|
+
# return "Starting the update"
|
30
|
+
# elif state == OBFwUpdateState.STAT_VERIFY_IMAGE:
|
31
|
+
# return "Verifying image file"
|
32
|
+
# else:
|
33
|
+
# return "Unknown status or error"
|
34
|
+
|
35
|
+
# Function to simulate input of preset file paths
|
36
|
+
def get_preset_paths():
|
37
|
+
paths = []
|
38
|
+
print("Please input the file paths of the optional depth preset file (.bin):")
|
39
|
+
print(" - Press 'Enter' to finish this input")
|
40
|
+
print(" - Press 'Q' or 'q' to exit the program")
|
41
|
+
while len(paths) < 10:
|
42
|
+
path = input("Enter Path: ")
|
43
|
+
if path.lower() == 'q':
|
44
|
+
return None
|
45
|
+
if path == '':
|
46
|
+
if len(paths) == 0:
|
47
|
+
print("You didn't input any file paths")
|
48
|
+
continue
|
49
|
+
break
|
50
|
+
if path.endswith(".bin"):
|
51
|
+
paths.append(path)
|
52
|
+
else:
|
53
|
+
print("Invalid file format. Please provide a .bin file.")
|
54
|
+
return paths
|
55
|
+
|
56
|
+
# Main loop to simulate device selection, preset update, and handling
|
57
|
+
def main():
|
58
|
+
# Assuming `devices` is a list of `Device` objects that you've already gathered
|
59
|
+
devices = []
|
60
|
+
context = Context()
|
61
|
+
device_list = context.query_devices()
|
62
|
+
|
63
|
+
if device_list.get_count() == 0:
|
64
|
+
print("No device found. Please connect a device first!")
|
65
|
+
input("Press Enter to exit...")
|
66
|
+
return
|
67
|
+
|
68
|
+
for i in range(device_list.get_count()):
|
69
|
+
devices.append(device_list[i])
|
70
|
+
|
71
|
+
print("Devices found:")
|
72
|
+
print_device_list(devices)
|
73
|
+
|
74
|
+
while True:
|
75
|
+
device = select_device(devices) # User selects a device
|
76
|
+
|
77
|
+
if not device:
|
78
|
+
break
|
79
|
+
|
80
|
+
preset_paths = get_preset_paths()
|
81
|
+
if not preset_paths:
|
82
|
+
break
|
83
|
+
|
84
|
+
print("Start to update optional depth preset, please wait a moment...\n")
|
85
|
+
|
86
|
+
# Pass the paths list to the update function and update via callback
|
87
|
+
try:
|
88
|
+
device.update_optional_depth_presets(
|
89
|
+
preset_paths,
|
90
|
+
lambda state, message, percent: preset_update_callback(True, state, message, percent)
|
91
|
+
)
|
92
|
+
except Exception as e:
|
93
|
+
print(f"\nThe update was interrupted! An error occurred: {str(e)}")
|
94
|
+
break
|
95
|
+
|
96
|
+
print("\nUpdate completed successfully!")
|
97
|
+
# Assuming `print_preset(device)` will show the updated preset information
|
98
|
+
print_preset(device)
|
99
|
+
|
100
|
+
if not should_continue():
|
101
|
+
break
|
102
|
+
|
103
|
+
# Function to print device list (similar to the C++ printDeviceList function)
|
104
|
+
def print_device_list(devices):
|
105
|
+
for i, device in enumerate(devices):
|
106
|
+
print(f"[{i}] Device: {device.get_device_info().get_name()} | "
|
107
|
+
f"SN: {device.get_device_info().get_serial_number()} | "
|
108
|
+
f"Firmware version: {device.get_device_info().get_firmware_version()}")
|
109
|
+
|
110
|
+
# Function to let the user select a device
|
111
|
+
def select_device(devices):
|
112
|
+
while True:
|
113
|
+
device_index = input("Please select a device by index, or press 'q' to quit: ")
|
114
|
+
if device_index.lower() == 'q':
|
115
|
+
return None
|
116
|
+
try:
|
117
|
+
index = int(device_index)
|
118
|
+
if 0 <= index < len(devices):
|
119
|
+
return devices[index]
|
120
|
+
else:
|
121
|
+
print("Invalid index. Please try again.")
|
122
|
+
except ValueError:
|
123
|
+
print("Invalid input. Please enter a number.")
|
124
|
+
|
125
|
+
# Function to check if the user wants to continue
|
126
|
+
def should_continue():
|
127
|
+
input_str = input("Enter 'Q' or 'q' to quit, or any other key to continue: ")
|
128
|
+
return input_str.lower() != 'q'
|
129
|
+
|
130
|
+
# Placeholder function to retrieve devices, implement this to match your system setup
|
131
|
+
def get_devices():
|
132
|
+
# Example: Returning a list of Device objects.
|
133
|
+
# In real usage, you'll need to query connected devices.
|
134
|
+
return []
|
135
|
+
|
136
|
+
# Placeholder function to print preset info after the update, implement as needed
|
137
|
+
def print_preset(device):
|
138
|
+
print(f"Updated preset for device {device.get_device_info().get_name()}")
|
139
|
+
|
140
|
+
# Run the program
|
141
|
+
if __name__ == "__main__":
|
142
|
+
main()
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# ******************************************************************************
|
2
|
+
# Copyright (c) 2024 Orbbec 3D Technology, Inc
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http:# www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
# ******************************************************************************
|
16
|
+
|
17
|
+
import sys
|
18
|
+
from pyorbbecsdk import *
|
19
|
+
|
20
|
+
ESC_KEY = 'q'
|
21
|
+
|
22
|
+
|
23
|
+
def get_input_option():
|
24
|
+
"""Get user input option, return -1 to exit"""
|
25
|
+
option = input("Please enter an option (or press 'q' to exit): ")
|
26
|
+
if option.lower() == ESC_KEY:
|
27
|
+
return -1
|
28
|
+
try:
|
29
|
+
return int(option)
|
30
|
+
except ValueError:
|
31
|
+
print("Invalid input, please enter a number!")
|
32
|
+
return get_input_option()
|
33
|
+
|
34
|
+
|
35
|
+
def print_video_profile(profile, index, sensor_type):
|
36
|
+
"""Print video stream profile information, including sensor type"""
|
37
|
+
# Check if VideoStreamProfile has the required methods
|
38
|
+
if all(hasattr(profile, attr) for attr in ["get_format", "get_width", "get_height", "get_fps"]):
|
39
|
+
format_name = profile.get_format()
|
40
|
+
width = profile.get_width()
|
41
|
+
height = profile.get_height()
|
42
|
+
fps = profile.get_fps()
|
43
|
+
print(
|
44
|
+
f"Sensor type: {sensor_type} | {index}. format: {format_name}, width: {width}, height: {height}, fps: {fps}")
|
45
|
+
else:
|
46
|
+
print(f"{index}. VideoStreamProfile is missing expected methods")
|
47
|
+
|
48
|
+
|
49
|
+
def enumerate_stream_profiles(sensor):
|
50
|
+
"""List stream profiles based on sensor type"""
|
51
|
+
try:
|
52
|
+
stream_profile_list = sensor.get_stream_profile_list()
|
53
|
+
except Exception as e:
|
54
|
+
print(f"Unable to get StreamProfileList: {e}")
|
55
|
+
return
|
56
|
+
|
57
|
+
sensor_type = sensor.get_type()
|
58
|
+
print("Available stream profiles:")
|
59
|
+
for index in range(stream_profile_list.get_count()):
|
60
|
+
try:
|
61
|
+
profile = stream_profile_list.get_stream_profile_by_index(index)
|
62
|
+
profile_type = type(profile).__name__
|
63
|
+
print(f"Profile #{index} type: {profile_type}")
|
64
|
+
if profile_type == "VideoStreamProfile":
|
65
|
+
print_video_profile(profile, index, sensor_type)
|
66
|
+
else:
|
67
|
+
print(f"{index}. Unknown video stream profile type")
|
68
|
+
except Exception as e:
|
69
|
+
print(f"Unable to retrieve stream profile: {e}")
|
70
|
+
|
71
|
+
|
72
|
+
def enumerate_sensors(device):
|
73
|
+
"""List device sensor information and allow user to select a sensor"""
|
74
|
+
sensor_list = device.get_sensor_list()
|
75
|
+
print("Available sensor list:")
|
76
|
+
for index in range(sensor_list.get_count()):
|
77
|
+
sensor_type = sensor_list.get_type_by_index(index)
|
78
|
+
print(f" - {index}. Sensor type: {sensor_type}")
|
79
|
+
|
80
|
+
# Prompt user to select a sensor
|
81
|
+
sensor_selected = get_input_option()
|
82
|
+
if sensor_selected == -1:
|
83
|
+
return
|
84
|
+
if sensor_selected >= sensor_list.get_count() or sensor_selected < 0:
|
85
|
+
print("Invalid input, please select again!")
|
86
|
+
return enumerate_sensors(device)
|
87
|
+
|
88
|
+
sensor = sensor_list.get_sensor_by_index(sensor_selected)
|
89
|
+
print(f"Selected sensor type: {sensor.get_type()}")
|
90
|
+
enumerate_stream_profiles(sensor)
|
91
|
+
|
92
|
+
|
93
|
+
def main():
|
94
|
+
context = Context()
|
95
|
+
device_list = context.query_devices()
|
96
|
+
if device_list.get_count() < 1:
|
97
|
+
print("No device found, please connect a device and try again.")
|
98
|
+
return
|
99
|
+
|
100
|
+
print("Enumerated devices:")
|
101
|
+
for index in range(device_list.get_count()):
|
102
|
+
device = device_list[index]
|
103
|
+
device_info = device.get_device_info()
|
104
|
+
print(
|
105
|
+
f" - {index}. Device name: {device_info.get_name()}, PID: {device_info.get_pid()}, Serial Number: {device_info.get_serial_number()}")
|
106
|
+
|
107
|
+
# Default to selecting the first device
|
108
|
+
print(f"Please select a device, show between 0 and {device_list.get_count() - 1}")
|
109
|
+
device_selected = get_input_option()
|
110
|
+
if device_selected == -1:
|
111
|
+
print("Exiting...")
|
112
|
+
return
|
113
|
+
selected_device = device_list[device_selected]
|
114
|
+
enumerate_sensors(selected_device)
|
115
|
+
|
116
|
+
|
117
|
+
if __name__ == "__main__":
|
118
|
+
main()
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|