Examples¶
The EnsensoSDK includes all the examples described on this page in its installation directory, which you can list like this:
ls $ENSENSO_INSTALL/development/examples/Python
dir "%ENSENSO_INSTALL%\development\examples\Python"
ls $env:ENSENSO_INSTALL\development\examples\Python
nx_save_images_verbose.py¶
The following code shows how the Python API is used to initialize the NxLib, open a camera with a given serial number, capture an image pair, rectify those images and then save both the raw and the rectified images as PNG files. This example is utterly verbose since it contains a lot of boilerplate code. The examples below show how this boilerplate code can be reduced to a minimum.
import argparse
import nxlib.api as api
from nxlib import NxLibCommand, NxLibException, NxLibItem
from nxlib.constants import *
def get_camera_node(serial):
# Get the root of the tree.
root = NxLibItem()
# From here on we can use the [] operator to walk the tree.
cameras = root[ITM_CAMERAS][ITM_BY_SERIAL_NO]
for i in range(cameras.count()):
found = cameras[i].name() == serial
if found:
return cameras[i]
parser = argparse.ArgumentParser()
parser.add_argument("serial", type=str,
help="the serial of the stereo camera to open")
args = parser.parse_args()
camera_serial = args.serial
try:
# Wait for the cameras to be initialized
api.initialize()
# Open the camera with the given serial
with NxLibCommand(CMD_OPEN) as cmd:
cmd.parameters()[ITM_CAMERAS] = camera_serial
cmd.execute()
# Capture with the previously opened camera
with NxLibCommand(CMD_CAPTURE) as cmd:
cmd.parameters()[ITM_CAMERAS] = camera_serial
cmd.execute()
# Rectify the images
with NxLibCommand(CMD_RECTIFY_IMAGES) as cmd:
cmd.execute()
# Get the NxLib node of the open camera
camera = get_camera_node(camera_serial)
# Save the raw and rectified images
with NxLibCommand(CMD_SAVE_IMAGE) as cmd:
if camera[ITM_TYPE].as_string() == VAL_STEREO:
cmd.parameters()[ITM_NODE] = camera[ITM_IMAGES][ITM_RAW][ITM_LEFT].path
cmd.parameters()[ITM_FILENAME] = "raw_left.png"
cmd.execute()
cmd.parameters()[ITM_NODE] = camera[ITM_IMAGES][ITM_RAW][ITM_RIGHT].path
cmd.parameters()[ITM_FILENAME] = "raw_right.png"
cmd.execute()
cmd.parameters()[ITM_NODE] = camera[ITM_IMAGES][ITM_RECTIFIED][ITM_LEFT].path
cmd.parameters()[ITM_FILENAME] = "rectified_left.png"
cmd.execute()
cmd.parameters()[ITM_NODE] = camera[ITM_IMAGES][ITM_RECTIFIED][ITM_RIGHT].path
cmd.parameters()[ITM_FILENAME] = "rectified_right.png"
cmd.execute()
else:
cmd.parameters()[ITM_NODE] = camera[ITM_IMAGES][ITM_RAW].path
cmd.parameters()[ITM_FILENAME] = "raw.png"
cmd.execute()
cmd.parameters()[ITM_NODE] = camera[ITM_IMAGES][ITM_RECTIFIED].path
cmd.parameters()[ITM_FILENAME] = "rectified.png"
cmd.execute()
# Close the open camera
with NxLibCommand(CMD_CLOSE) as cmd:
cmd.execute()
except NxLibException as e:
print(f"An NxLib error occured: Error Text: {e.get_error_text()}")
except Exception:
print("An NxLib unrelated error occured:\n")
raise
nx_save_stereo_images.py¶
The above example can be simplified by using the provided context manager
protocol implementing classes nxlib.context.NxLib
and
nxlib.context.StereoCamera
.
import argparse
from nxlib.context import NxLib, StereoCamera
from nxlib.command import NxLibCommand
from nxlib.constants import *
parser = argparse.ArgumentParser()
parser.add_argument("serial", type=str,
help="the serial of the stereo camera to open")
args = parser.parse_args()
def save_image(filename, item):
with NxLibCommand(CMD_SAVE_IMAGE) as cmd:
cmd.parameters()[ITM_NODE] = item.path
cmd.parameters()[ITM_FILENAME] = filename
cmd.execute()
with NxLib(), StereoCamera(args.serial) as camera:
camera.capture()
camera.rectify()
save_image("raw_left.png", camera[ITM_IMAGES][ITM_RAW][ITM_LEFT])
save_image("raw_right.png", camera[ITM_IMAGES][ITM_RAW][ITM_RIGHT])
save_image("rectified_left.png", camera[ITM_IMAGES][ITM_RECTIFIED][ITM_LEFT])
save_image("rectified_right.png", camera[ITM_IMAGES][ITM_RECTIFIED][ITM_RIGHT])
nx_save_mono_images.py¶
This example shows - as the above one - how the image of a mono camera can be
saved as a PNG file by using the provided context manager protocol implementing
classes nxlib.context.NxLib
and nxlib.context.MonoCamera
.
import argparse
from nxlib.context import NxLib, MonoCamera
from nxlib.command import NxLibCommand
from nxlib.constants import *
parser = argparse.ArgumentParser()
parser.add_argument("serial", type=str,
help="the serial of the mono camera to open")
args = parser.parse_args()
def save_image(filename, item):
with NxLibCommand(CMD_SAVE_IMAGE) as cmd:
cmd.parameters()[ITM_NODE] = item.path
cmd.parameters()[ITM_FILENAME] = filename
cmd.execute()
with NxLib(), MonoCamera(args.serial) as camera:
camera.capture()
camera.rectify()
save_image("raw.png", camera[ITM_IMAGES][ITM_RAW])
save_image("rectified.png", camera[ITM_IMAGES][ITM_RECTIFIED])
nx_save_structured_light_images.py¶
This example is analogous to the nx_save_stereo_images.py example using the provided
context manager protocol implementing classes nxlib.context.NxLib
and
nxlib.context.StructuredLightCamera
.
import argparse
from nxlib.context import NxLib, StructuredLightCamera
from nxlib.command import NxLibCommand
from nxlib.constants import *
parser = argparse.ArgumentParser()
parser.add_argument("serial", type=str,
help="the serial of the structured light camera to open")
args = parser.parse_args()
def save_image(filename, item):
with NxLibCommand(CMD_SAVE_IMAGE) as cmd:
cmd.parameters()[ITM_NODE] = item.path
cmd.parameters()[ITM_FILENAME] = filename
cmd.execute()
with NxLib(), StructuredLightCamera(args.serial) as camera:
camera.capture()
camera.rectify()
save_image("raw.png", camera[ITM_IMAGES][ITM_RAW])
save_image("rectified.png", camera[ITM_IMAGES][ITM_RECTIFIED])
nx_version.py¶
This example show how to use the nxlib.item.NxLibItem
class and its
methods to access the NxTree.
from nxlib import NxLib
from nxlib import NxLibItem
from nxlib import NxLibError
from nxlib.constants import *
with NxLib():
major = NxLibItem()[ITM_VERSION][ITM_NX_LIB][ITM_MAJOR]
minor = NxLibItem()[ITM_VERSION][ITM_NX_LIB][ITM_MINOR]
build = NxLibItem()[ITM_VERSION][ITM_NX_LIB][ITM_BUILD]
try:
version = major.as_string() + minor.as_string() + build.as_string()
except NxLibError:
# "The 'as_*()' methods cannot be used to convert an item's value."
pass
if (major.is_int() and minor.is_int() and build.is_int()):
version = ".".join(str(node.as_int()) for node in [major, minor, build])
if major >= 4 or (major == 3 and minor > 3):
print("Ensenso SDK installation contains Python interface")
print(f"NxLib Version {version}")
else:
print("Unexpected node format detected")
nx_list_cams.py¶
This example iterates over all cameras listed by the NxLib and prints their serial number, model and status.
from nxlib import NxLibItem
from nxlib.constants import *
from nxlib.context import NxLib
def check_true(item):
return item.exists() and item.as_bool() is True
def check_false(item):
return item.exists() and item.as_bool() is False
with NxLib():
# Reference to the serials subnode of all cameras
cameras = NxLibItem()[ITM_CAMERAS]
# Print status information for each camera
print("SerialNo", " " * 8, "Model", " " * 10, "Status")
for i in range(cameras.count()):
if not cameras[i][ITM_STATUS].exists():
continue
if check_false(cameras[i][ITM_STATUS][ITM_VALID_IP_ADDRESS]):
status = "Invalid Ip"
elif check_true(cameras[i][ITM_STATUS][ITM_OPEN]):
status = "Open"
elif check_false(cameras[i][ITM_STATUS][ITM_AVAILABLE]):
status = "In Use"
elif check_false(cameras[i][ITM_STATUS][ITM_VALID_CAMERA_FIRMWARE]):
status = "Invalid Camera Firmware"
elif check_false(cameras[i][ITM_STATUS][ITM_VALID_PROJECTOR_FIRMWARE]):
status = "Invalid Projector Firmware"
elif check_false(cameras[i][ITM_STATUS][ITM_CALIBRATED]):
status = "Not Calibrated"
else:
status = "Available"
serial = cameras[i].name()
model = cameras[i][ITM_MODEL_NAME].as_string()
print(f"{serial:<17} {model:<16} {status:<16}")
nx_simple.py¶
This simple example opens a stereo camera, executes the complete pipeline that is necessary to get the computed point map and then calculates the average of the z values.
import argparse
import numpy as np
from nxlib import NxLib, Camera
from nxlib.constants import *
def filter_nans(point_map):
""" Filter NaN values. """
return point_map[~np.isnan(point_map).any(axis=1)]
def reshape_point_map(point_map):
""" Reshape the point map array from (m x n x 3) to ((m*n) x 3). """
return point_map.reshape(
(point_map.shape[0] * point_map.shape[1]), point_map.shape[2])
def compute_z_value_average(point_map):
""" Reshape and filter the point map, then calculate z-value average. """
point_map = reshape_point_map(point_map)
point_map = filter_nans(point_map)
if point_map.shape[0] == 0:
return 0.0
z_idx = 2
z_count, z_sum = 0, 0.0
for i in range(point_map.shape[0]):
z_sum += point_map[i][z_idx]
z_count += 1
return z_sum / z_count
parser = argparse.ArgumentParser()
parser.add_argument("serial", type=str,
help="the serial of the stereo camera to open")
args = parser.parse_args()
with NxLib(), Camera.from_serial(args.serial,
[VAL_STRUCTURED_LIGHT, VAL_STEREO]) as camera:
camera.capture()
camera.rectify()
camera.compute_disparity_map()
camera.compute_point_map()
z_value_average = compute_z_value_average(camera.get_point_map())
print(f"The average z value in the point map is {z_value_average:.1f}mm")
nx_watch_point_cloud.py¶
This example opens a stereo camera, executes the complete pipeline that is
necessary to get the computed point map and then renders the point cloud with
open3d
. If you do not have open3d
installed, follow the instructions
given at the top of the example file.
# This example requires the open3d package to be installed.
# Install it with: python3 -m pip install open3d
import argparse
import numpy as np
import open3d
from nxlib import NxLib
from nxlib import Camera
from nxlib.constants import *
def filter_nans(point_map):
""" Filter NaN values. """
return point_map[~np.isnan(point_map).any(axis=1)]
def reshape_point_map(point_map):
""" Reshape the point map array from (m x n x 3) to ((m*n) x 3). """
return point_map.reshape(
(point_map.shape[0] * point_map.shape[1]), point_map.shape[2])
def convert_to_open3d_point_cloud(point_map):
""" Convert numpy array to Open3D format. """
point_map = reshape_point_map(point_map)
point_map = filter_nans(point_map)
open3d_point_cloud = open3d.geometry.PointCloud()
open3d_point_cloud.points = open3d.utility.Vector3dVector(point_map)
return open3d_point_cloud
parser = argparse.ArgumentParser()
parser.add_argument("serial", type=str,
help="the serial of the depth camera to open")
args = parser.parse_args()
with NxLib(), Camera.from_serial(args.serial,
[VAL_STRUCTURED_LIGHT, VAL_STEREO]) as camera:
camera.capture()
camera.compute_disparity_map()
camera.compute_point_map()
# Watch the captured point cloud with open3d
point_cloud = convert_to_open3d_point_cloud(camera.get_point_map())
open3d.visualization.draw_geometries([point_cloud])
nx_log.py¶
This examples illustrates the use of the classes nxlib.log.NxLog
and nxlib.log.NxDebugBlock
. It opens a log in line 21, which collects
all debug output from the NxLib, and a debug block named TestBlock in line
27. After line 35, the NxLog’s scope ends, causing the log file to be written to
file. In this example, no filename was given and hence the log file will be
written to enslog/temp-0001.enslog (which is composed of the default output path
and a serially numbered default filename). Since the NxLog was created with
open_in_profiler=True, the written log file will automatically be opened with
the NxProfiler executable. In the visual log we can now see our debug message
and our TestBlock among all other NxLib logging.
1import argparse
2
3from nxlib import NxLib
4from nxlib import NxLog
5from nxlib import NxDebugBlock
6from nxlib import StereoCamera
7from nxlib.constants import *
8
9
10parser = argparse.ArgumentParser()
11parser.add_argument("serial", type=str,
12 help="the serial of the stereo camera to open")
13args = parser.parse_args()
14
15
16with NxLib(), StereoCamera(args.serial) as camera:
17
18 # If desired: set the global log level for all further logs.
19 # NxLog.set_log_level(NX_LOG_LEVEL_INFO)
20
21 with NxLog(level=NX_LOG_LEVEL_DEBUG, open_in_profiler=True):
22
23 # Capture with the previously opened camera
24 camera.capture()
25 NxLog.write_debug_message("Capture done")
26
27 with NxDebugBlock(name="TestBlock"):
28 # Rectify the images
29 camera.rectify()
30
31 # Compute the disparity map
32 camera.compute_disparity_map()
33
34 # Compute the point map from the disparity map
35 camera.compute_point_map()
36 point_map = camera.get_point_map()
nx_log_remote_lib.py¶
The following example shows how the NxLibRemote
class can be used in
combination with the NxLog
class to periodically read out the debug
buffer of a remote NxLib.
import argparse
import time
from nxlib import NxLibRemote
from nxlib import NxLog
parser = argparse.ArgumentParser()
parser.add_argument("hostname", type=str,
help="the hostname of the remote NxLib")
parser.add_argument("filename", type=str,
help="the filename the log is written to")
parser.add_argument("-p", "--port", type=int, default=24000, metavar="P",
help="the port of the remote NxLib (default 24000)")
args = parser.parse_args()
with NxLibRemote(args.hostname, args.port):
with open(args.filename, "wb") as f:
try:
while True:
bytes_ = NxLog.get_debug_buffer()
print(f"Received {len(bytes_)} bytes")
f.write(bytes_)
time.sleep(1)
except KeyboardInterrupt:
print("\nKeyboardInterrupt")