可视化教程
介绍
本教程介绍如何使用Zivid SDK和第三方库来可视化Zivid相机捕获的3D和2D数据。
先决条件
安装 Zivid 软件 。
对于Python: 安装 Zivid-python
本教程从Zivid帧(frame)开始。查看 捕获教程 了解更多有关如何捕获帧的信息。
点云
在C++和C#中使用Zivid SDK
您可以通过帧(frame)可视化点云。
std::cout << "Setting up visualization" << std::endl;
Zivid::Visualization::Visualizer visualizer;
std::cout << "Visualizing point cloud" << std::endl;
visualizer.showMaximized();
visualizer.show(frame);
visualizer.resetToFit();
std::cout << "Running visualizer. Blocking until window closes." << std::endl;
visualizer.run();
Console.WriteLine("Setting up visualization");
using (var visualizer = new Zivid.NET.Visualization.Visualizer())
{
Console.WriteLine("Visualizing point cloud");
visualizer.Show(frame);
visualizer.ShowMaximized();
visualizer.ResetToFit();
Console.WriteLine("Running visualizer. Blocking until window closes.");
visualizer.Run();
}
您也可以从点云对象来可视化点云。
std::cout << "Getting point cloud from frame" << std::endl;
auto pointCloud = frame.pointCloud();
std::cout << "Setting up visualization" << std::endl;
Zivid::Visualization::Visualizer visualizer;
std::cout << "Visualizing point cloud" << std::endl;
visualizer.showMaximized();
visualizer.show(pointCloud);
visualizer.resetToFit();
std::cout << "Running visualizer. Blocking until window closes." << std::endl;
visualizer.run();
Console.WriteLine("Getting point cloud from frame");
var pointCloud = frame.PointCloud;
Console.WriteLine("Setting up visualization");
var visualizer = new Zivid.NET.Visualization.Visualizer();
Console.WriteLine("Visualizing point cloud");
visualizer.Show(pointCloud);
visualizer.ShowMaximized();
visualizer.ResetToFit();
Console.WriteLine("Running visualizer. Blocking until window closes.");
visualizer.Run();
Live 3D Point Cloud
The Zivid SDK can be used to continuously capture and visualize 3D point clouds in a loop.
Zivid SDK in C++
The visualizer runs in the main thread while a dedicated thread continuously captures new frames and pushes them to the visualizer. The visualizer must be created and run in the same thread, so keeping it in the main thread lets it outlive the capture thread.
std::cout << "Setting up visualization" << std::endl;
auto visualizer = Zivid::Visualization::Visualizer();
std::cout << "Visualizing point cloud" << std::endl;
visualizer.showMaximized();
visualizer.show(frame);
visualizer.resetToFit();
std::atomic_bool visualizerRunning{ true };
std::exception_ptr captureException;
std::thread captureThread([&camera, &settings, &visualizer, &visualizerRunning, &captureException]() {
try
{
while(visualizerRunning)
{
const auto newFrame = camera.capture2D3D(settings);
if(visualizerRunning)
{
visualizer.show(newFrame);
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
catch(...)
{
captureException = std::current_exception();
visualizer.close();
}
});
std::cout << "Running visualizer. Blocking until window closes." << std::endl;
visualizer.run();
visualizerRunning = false;
captureThread.join();
if(captureException)
{
std::rethrow_exception(captureException);
}
std::cout << "Visualizer closed" << std::endl;
Console.WriteLine("Setting up visualization");
var visualizerRunning = new ManualResetEventSlim(false);
Zivid.NET.Visualization.Visualizer visualizerHandle = null;
var visualizerReady = new ManualResetEventSlim(false);
var visualizationThread = new Thread(() =>
{
using (var visualizer = new Zivid.NET.Visualization.Visualizer())
{
// Pass the visualizer to the main thread
visualizerHandle = visualizer;
visualizerReady.Set();
Console.WriteLine("Visualizing point cloud");
visualizer.ShowMaximized();
visualizer.Show(frame);
visualizer.ResetToFit();
Console.WriteLine("Running visualizer. Blocking until window closes.");
visualizerRunning.Set();
visualizer.Run();
visualizerRunning.Reset();
}
});
visualizationThread.Start();
// Get the visualizer handle in the main thread
visualizerReady.Wait();
visualizerRunning.Wait();
while (visualizerRunning.IsSet)
{
frame = camera.Capture2D3D(settings);
if (!visualizerRunning.IsSet)
break;
visualizerHandle.Show(frame);
Thread.Sleep(10);
}
visualizationThread.Join();
Console.WriteLine("Visualizer closed");
print("Setting up visualization")
visualizer_running = threading.Event()
print("Visualizing point cloud")
with zivid.visualization.Visualizer() as visualizer:
visualizer.show(frame)
visualizer.reset_to_fit()
def _capture_thread() -> None:
while visualizer_running.is_set():
new_frame = camera.capture_2d_3d(settings)
if visualizer_running.is_set():
visualizer.show(new_frame)
time.sleep(0.01)
capture_thread = threading.Thread(target=_capture_thread)
print("Running visualizer. Blocking until window closes.")
visualizer_running.set()
capture_thread.start()
visualizer.run()
visualizer_running.clear()
capture_thread.join()
print("Visualizer closed")
To exit the loop by pressing 'q' in the terminal:
std::cout << "Setting up visualization" << std::endl;
auto visualizer = Zivid::Visualization::Visualizer();
std::cout << "Visualizing point cloud" << std::endl;
visualizer.showMaximized();
visualizer.show(frame);
visualizer.resetToFit();
std::atomic_bool visualizerRunning{ true };
std::exception_ptr captureException;
std::thread captureThread([&camera, &settings, &visualizer, &visualizerRunning, &captureException]() {
try
{
std::cout << "Press 'q' in the terminal to quit " << std::endl;
while(visualizerRunning)
{
if(getKeyNonBlocking() == 'q')
{
std::cout << "Closing application because user pressed 'q'" << std::endl;
visualizer.close();
break;
}
const auto newFrame = camera.capture2D3D(settings);
if(visualizerRunning)
{
visualizer.show(newFrame);
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
catch(...)
{
captureException = std::current_exception();
visualizer.close();
}
});
std::cout << "Running visualizer. Blocking until the window closes or 'q' is pressed." << std::endl;
visualizer.run();
visualizerRunning = false;
captureThread.join();
if(captureException)
{
std::rethrow_exception(captureException);
}
std::cout << "Visualizer closed" << std::endl;
Console.WriteLine("Setting up visualization");
var visualizerRunning = new ManualResetEventSlim(false);
var acceptEnd = new ManualResetEventSlim(true);
var quitRequested = new ManualResetEventSlim(false);
Zivid.NET.Visualization.Visualizer visualizerHandle = null;
var visualizerReady = new ManualResetEventSlim(false);
var visualizationThread = new Thread(() =>
{
using (var visualizer = new Zivid.NET.Visualization.Visualizer())
{
// Pass the visualizer to the main thread
visualizerHandle = visualizer;
visualizerReady.Set();
Console.WriteLine("Visualizing point cloud");
visualizer.ShowMaximized();
visualizer.Show(frame);
visualizer.ResetToFit();
Console.WriteLine("Running visualizer. Blocking until window closes.");
do
{
visualizerRunning.Set();
visualizer.Run();
visualizerRunning.Reset();
if (quitRequested.IsSet)
break;
Console.WriteLine(
"Visualizer window closed by user. It will be reopened if we're currently capturing."
);
} while (!acceptEnd.IsSet);
}
});
visualizationThread.Start();
// Get the visualizer handle in the main thread
visualizerReady.Wait();
visualizerRunning.Wait();
Console.WriteLine("Press 'q' in the terminal to quit");
while (visualizerRunning.IsSet)
{
if (Console.KeyAvailable)
{
var key = Console.ReadKey(intercept: true);
if (key.KeyChar == 'q')
{
Console.WriteLine("Closing application because user pressed 'q'");
quitRequested.Set();
Application.DoEvents();
foreach (Form form in Application.OpenForms)
{
if (form.Text.Contains("Zivid"))
{
form.Invoke(new Action(() => form.Close()));
break;
}
}
}
}
else
{
acceptEnd.Reset();
frame = camera.Capture2D3D(settings);
visualizerHandle.Show(frame);
acceptEnd.Set();
}
Thread.Sleep(10);
}
visualizationThread.Join();
Console.WriteLine("Visualizer closed");
print("Setting up visualization")
visualizer_running = threading.Event()
visualizer_running.set()
use_raw_terminal = sys.platform != "win32" and sys.stdin.isatty()
if use_raw_terminal:
old_terminal_settings = termios.tcgetattr(sys.stdin)
tty.setcbreak(sys.stdin.fileno())
try:
print("Visualizing point cloud")
with zivid.visualization.Visualizer() as visualizer:
visualizer.show(frame)
visualizer.reset_to_fit()
def _capture_and_keypress_thread() -> None:
print("Press 'q' in the terminal to quit")
while visualizer_running.is_set():
if _get_key_non_blocking() == "q":
print("Closing application because user pressed 'q'")
visualizer.close()
break
new_frame = camera.capture_2d_3d(settings)
if visualizer_running.is_set():
visualizer.show(new_frame)
time.sleep(0.01)
capture_thread = threading.Thread(target=_capture_and_keypress_thread)
capture_thread.start()
print("Running visualizer. Blocking until the window closes or 'q' is pressed.")
visualizer.run()
visualizer_running.clear()
capture_thread.join()
print("Visualizer closed")
finally:
if use_raw_terminal:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_terminal_settings)
Live 3D Point Cloud
The Zivid SDK can be used to continuously capture and visualize 3D point clouds in a loop.
Zivid SDK in C++
The visualizer runs in a dedicated thread while the main thread continuously captures new frames and pushes them to the visualizer.
std::cout << "Setting up visualization" << std::endl;
auto visualizer = Zivid::Visualization::Visualizer();
std::cout << "Visualizing point cloud" << std::endl;
visualizer.showMaximized();
visualizer.show(frame);
visualizer.resetToFit();
std::atomic_bool visualizerRunning{ true };
std::exception_ptr captureException;
std::thread captureThread([&camera, &settings, &visualizer, &visualizerRunning, &captureException]() {
try
{
while(visualizerRunning)
{
const auto newFrame = camera.capture2D3D(settings);
if(visualizerRunning)
{
visualizer.show(newFrame);
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
catch(...)
{
captureException = std::current_exception();
visualizer.close();
}
});
std::cout << "Running visualizer. Blocking until window closes." << std::endl;
visualizer.run();
visualizerRunning = false;
captureThread.join();
if(captureException)
{
std::rethrow_exception(captureException);
}
std::cout << "Visualizer closed" << std::endl;
Console.WriteLine("Setting up visualization");
var visualizerRunning = new ManualResetEventSlim(false);
Zivid.NET.Visualization.Visualizer visualizerHandle = null;
var visualizerReady = new ManualResetEventSlim(false);
var visualizationThread = new Thread(() =>
{
using (var visualizer = new Zivid.NET.Visualization.Visualizer())
{
// Pass the visualizer to the main thread
visualizerHandle = visualizer;
visualizerReady.Set();
Console.WriteLine("Visualizing point cloud");
visualizer.ShowMaximized();
visualizer.Show(frame);
visualizer.ResetToFit();
Console.WriteLine("Running visualizer. Blocking until window closes.");
visualizerRunning.Set();
visualizer.Run();
visualizerRunning.Reset();
}
});
visualizationThread.Start();
// Get the visualizer handle in the main thread
visualizerReady.Wait();
visualizerRunning.Wait();
while (visualizerRunning.IsSet)
{
frame = camera.Capture2D3D(settings);
if (!visualizerRunning.IsSet)
break;
visualizerHandle.Show(frame);
Thread.Sleep(10);
}
visualizationThread.Join();
Console.WriteLine("Visualizer closed");
print("Setting up visualization")
visualizer_running = threading.Event()
print("Visualizing point cloud")
with zivid.visualization.Visualizer() as visualizer:
visualizer.show(frame)
visualizer.reset_to_fit()
def _capture_thread() -> None:
while visualizer_running.is_set():
new_frame = camera.capture_2d_3d(settings)
if visualizer_running.is_set():
visualizer.show(new_frame)
time.sleep(0.01)
capture_thread = threading.Thread(target=_capture_thread)
print("Running visualizer. Blocking until window closes.")
visualizer_running.set()
capture_thread.start()
visualizer.run()
visualizer_running.clear()
capture_thread.join()
print("Visualizer closed")
To exit the loop by pressing 'q' in the terminal:
std::cout << "Setting up visualization" << std::endl;
auto visualizer = Zivid::Visualization::Visualizer();
std::cout << "Visualizing point cloud" << std::endl;
visualizer.showMaximized();
visualizer.show(frame);
visualizer.resetToFit();
std::atomic_bool visualizerRunning{ true };
std::exception_ptr captureException;
std::thread captureThread([&camera, &settings, &visualizer, &visualizerRunning, &captureException]() {
try
{
std::cout << "Press 'q' in the terminal to quit " << std::endl;
while(visualizerRunning)
{
if(getKeyNonBlocking() == 'q')
{
std::cout << "Closing application because user pressed 'q'" << std::endl;
visualizer.close();
break;
}
const auto newFrame = camera.capture2D3D(settings);
if(visualizerRunning)
{
visualizer.show(newFrame);
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
catch(...)
{
captureException = std::current_exception();
visualizer.close();
}
});
std::cout << "Running visualizer. Blocking until the window closes or 'q' is pressed." << std::endl;
visualizer.run();
visualizerRunning = false;
captureThread.join();
if(captureException)
{
std::rethrow_exception(captureException);
}
std::cout << "Visualizer closed" << std::endl;
Console.WriteLine("Setting up visualization");
var visualizerRunning = new ManualResetEventSlim(false);
var acceptEnd = new ManualResetEventSlim(true);
var quitRequested = new ManualResetEventSlim(false);
Zivid.NET.Visualization.Visualizer visualizerHandle = null;
var visualizerReady = new ManualResetEventSlim(false);
var visualizationThread = new Thread(() =>
{
using (var visualizer = new Zivid.NET.Visualization.Visualizer())
{
// Pass the visualizer to the main thread
visualizerHandle = visualizer;
visualizerReady.Set();
Console.WriteLine("Visualizing point cloud");
visualizer.ShowMaximized();
visualizer.Show(frame);
visualizer.ResetToFit();
Console.WriteLine("Running visualizer. Blocking until window closes.");
do
{
visualizerRunning.Set();
visualizer.Run();
visualizerRunning.Reset();
if (quitRequested.IsSet)
break;
Console.WriteLine(
"Visualizer window closed by user. It will be reopened if we're currently capturing."
);
} while (!acceptEnd.IsSet);
}
});
visualizationThread.Start();
// Get the visualizer handle in the main thread
visualizerReady.Wait();
visualizerRunning.Wait();
Console.WriteLine("Press 'q' in the terminal to quit");
while (visualizerRunning.IsSet)
{
if (Console.KeyAvailable)
{
var key = Console.ReadKey(intercept: true);
if (key.KeyChar == 'q')
{
Console.WriteLine("Closing application because user pressed 'q'");
quitRequested.Set();
Application.DoEvents();
foreach (Form form in Application.OpenForms)
{
if (form.Text.Contains("Zivid"))
{
form.Invoke(new Action(() => form.Close()));
break;
}
}
}
}
else
{
acceptEnd.Reset();
frame = camera.Capture2D3D(settings);
visualizerHandle.Show(frame);
acceptEnd.Set();
}
Thread.Sleep(10);
}
visualizationThread.Join();
Console.WriteLine("Visualizer closed");
print("Setting up visualization")
visualizer_running = threading.Event()
visualizer_running.set()
use_raw_terminal = sys.platform != "win32" and sys.stdin.isatty()
if use_raw_terminal:
old_terminal_settings = termios.tcgetattr(sys.stdin)
tty.setcbreak(sys.stdin.fileno())
try:
print("Visualizing point cloud")
with zivid.visualization.Visualizer() as visualizer:
visualizer.show(frame)
visualizer.reset_to_fit()
def _capture_and_keypress_thread() -> None:
print("Press 'q' in the terminal to quit")
while visualizer_running.is_set():
if _get_key_non_blocking() == "q":
print("Closing application because user pressed 'q'")
visualizer.close()
break
new_frame = camera.capture_2d_3d(settings)
if visualizer_running.is_set():
visualizer.show(new_frame)
time.sleep(0.01)
capture_thread = threading.Thread(target=_capture_and_keypress_thread)
capture_thread.start()
print("Running visualizer. Blocking until the window closes or 'q' is pressed.")
visualizer.run()
visualizer_running.clear()
capture_thread.join()
print("Visualizer closed")
finally:
if use_raw_terminal:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_terminal_settings)
彩色图像
由于Zivid SDK 和 Zivid-Python 不支持2D彩色图像可视化,我们使用第三方库实现该功能: 使 用 OpenCV 在C++和Python中实现,以及使 用 Matplotlib 在Python中实现。
OpenCV in C++ and Python
首先,我们将点云转换为OpenCV彩色图像。
下面展示了如何实现将点云转换为彩色图像的功能。
小技巧
也可以直接从Zivid 2D彩色图像中获取OpenCV彩色图像。
我们现在可以可视化彩色图像了。
Python中通过Matplotlib实现
Matplotlib提供了一种更简单的在Python中可视化彩色图像的方法。
函数实现如下所示。
深度图
由于Zivid SDK 和 Zivid-Python 不支持深度图的可视化功能,我们使用第三方库实现该功能: 使 用 OpenCV 在C++和Python中实现,以及使 用 Matplotlib 在Python中实现。
OpenCV in C++ and Python
首先,我们将点云转换为OpenCV深度图。
下面展示了将点云转换为深度图的函数。
cv::Mat pointCloudToCvZ(const Zivid::PointCloud &pointCloud)
{
cv::Mat z(pointCloud.height(), pointCloud.width(), CV_8UC1, cv::Scalar(0)); // NOLINT(hicpp-signed-bitwise)
const auto points = pointCloud.copyPointsZ();
// Getting min and max values for X, Y, Z images
const auto *maxZ = std::max_element(points.begin(), points.end(), isLesserOrNan);
const auto *minZ = std::max_element(points.begin(), points.end(), isGreaterOrNaN);
// Filling in OpenCV matrix with the cloud data
for(size_t i = 0; i < pointCloud.height(); i++)
{
for(size_t j = 0; j < pointCloud.width(); j++)
{
if(std::isnan(points(i, j).z))
{
z.at<uchar>(i, j) = 0;
}
else
{
z.at<uchar>(i, j) =
static_cast<unsigned char>((255.0F * (points(i, j).z - minZ->z) / (maxZ->z - minZ->z)));
}
}
}
// Applying color map
cv::Mat zColorMap;
cv::applyColorMap(z, zColorMap, cv::COLORMAP_VIRIDIS);
// Setting invalid points (nan) to black
for(size_t i = 0; i < pointCloud.height(); i++)
{
for(size_t j = 0; j < pointCloud.width(); j++)
{
if(std::isnan(points(i, j).z))
{
auto &zRGB = zColorMap.at<cv::Vec3b>(i, j);
zRGB[0] = 0;
zRGB[1] = 0;
zRGB[2] = 0;
}
}
}
return zColorMap;
}
def _point_cloud_to_cv_z(point_cloud: zivid.PointCloud) -> np.ndarray:
"""Get depth map from frame.
Args:
point_cloud: Zivid point cloud
Returns:
depth_map_color_map: Depth map (HxWx1 ndarray)
"""
depth_map = point_cloud.copy_data("z")
depth_map_uint8 = ((depth_map - np.nanmin(depth_map)) / (np.nanmax(depth_map) - np.nanmin(depth_map)) * 255).astype(
np.uint8
)
depth_map_color_map = cv2.applyColorMap(depth_map_uint8, cv2.COLORMAP_VIRIDIS)
# Setting nans to black
depth_map_color_map[np.isnan(depth_map)[:, :]] = 0
return depth_map_color_map
我们现在可以可视化深度图了。
Python中通过Matplotlib实现
Matplotlib提供了一种更简单的在Python中可视化深度图的方法。
函数实现如下所示。
def display_depthmap(xyz: np.ndarray, block: bool = True) -> None:
"""Create and display depthmap.
Args:
xyz: A numpy array of X, Y and Z point cloud coordinates
block: Stops the running program until the windows is closed
"""
plt.figure()
plt.imshow(
xyz[:, :, 2],
vmin=np.nanmin(xyz[:, :, 2]),
vmax=np.nanmax(xyz[:, :, 2]),
cmap="viridis",
)
plt.colorbar()
plt.title("Depth map")
plt.show(block=block)
法线
由于Zivid SDK不支持法线的可视化,我们使用第三方库实现该功能:使用 PCL 在C++中实现,以及使用 Open3D 在Python中实现。
C++中的使用PCL实现
我们可以按下面的方式可视化法线。
函数实现如下所示。
void visualizePointCloudAndNormalsPCL(
const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr &pointCloud,
const pcl::PointCloud<pcl::PointXYZRGBNormal>::ConstPtr &pointCloudWithNormals)
{
auto viewer = pcl::visualization::PCLVisualizer("Viewer");
int viewRgb(0);
viewer.createViewPort(0.0, 0.0, 0.5, 1.0, viewRgb);
viewer.addText("Cloud RGB", 0, 0, "RGBText", viewRgb);
viewer.addPointCloud<pcl::PointXYZRGB>(pointCloud, "cloud", viewRgb);
const int normalsSkipped = 10;
std::cout << "Note! 1 out of " << normalsSkipped << " normals are visualized" << std::endl;
int viewNormals(0);
viewer.createViewPort(0.5, 0.0, 1.0, 1.0, viewNormals);
viewer.addText("Cloud Normals", 0, 0, "NormalsText", viewNormals);
viewer.addPointCloud<pcl::PointXYZRGBNormal>(pointCloudWithNormals, "cloudNormals", viewNormals);
viewer.addPointCloudNormals<pcl::PointXYZRGBNormal>(
pointCloudWithNormals, normalsSkipped, 1, "normals", viewNormals);
viewer.setCameraPosition(0, 0, -100, 0, 0, 1000, 0, -1, 0);
std::cout << "Press r to centre and zoom the viewer so that the entire cloud is visible" << std::endl;
std::cout << "Press q to exit the viewer application" << std::endl;
while(!viewer.wasStopped())
{
viewer.spinOnce(100);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
在Python中使用Open3D
我们可以按下面的方式可视化法线。
normals_colormap = 0.5 * (1 - normals)
normals_colormap = np.nan_to_num(normals_colormap, nan=0.0, posinf=1.0, neginf=0.0)
print("Visualizing normals in 2D")
display_rgb(rgb=rgba[:, :, :3], title="RGB image", block=False)
display_rgb(rgb=normals_colormap, title="Colormapped normals", block=True)
print("Visualizing normals in 3D")
display_pointcloud_with_downsampled_normals(point_cloud, zivid.PointCloud.Downsampling.by4x4)
函数实现如下所示。
def _copy_to_open3d_point_cloud(xyz: np.ndarray, rgb: np.ndarray, normals: np.ndarray) -> o3d.geometry.PointCloud:
"""Copy point cloud data to Open3D PointCloud object.
Args:
xyz: A numpy array of X, Y and Z point cloud coordinates
rgb: RGB image
normals: Ordered array of normal vectors, mapped to xyz
Returns:
An Open3D PointCloud object
"""
xyz = np.nan_to_num(xyz).reshape(-1, 3)
normals = np.nan_to_num(normals).reshape(-1, 3)
rgb = rgb.reshape(-1, rgb.shape[-1])[:, :3]
open3d_point_cloud = o3d.geometry.PointCloud(o3d.utility.Vector3dVector(xyz))
open3d_point_cloud.colors = o3d.utility.Vector3dVector(rgb / 255)
open3d_point_cloud.normals = o3d.utility.Vector3dVector(normals)
return open3d_point_cloud
def _display_open3d_point_cloud(open3d_point_cloud: o3d.geometry.PointCloud) -> None:
"""Display Open3D PointCloud object.
Args:
open3d_point_cloud: Open3D PointCloud object to display
"""
visualizer = o3d.visualization.Visualizer() # pylint: disable=no-member
visualizer.create_window()
visualizer.add_geometry(open3d_point_cloud)
if len(open3d_point_cloud.normals) > 0:
print("Open 3D controls:")
print(" n: for normals")
print(" 9: for point cloud colored by normals")
print(" h: for all controls")
visualizer.get_render_option().background_color = (0, 0, 0)
visualizer.get_render_option().point_size = 2
visualizer.get_render_option().show_coordinate_frame = True
visualizer.get_view_control().set_front([0, 0, -1])
visualizer.get_view_control().set_up([0, -1, 0])
visualizer.run()
visualizer.destroy_window()
def display_pointcloud_with_downsampled_normals(
point_cloud: zivid.PointCloud,
downsampling: zivid.PointCloud.Downsampling,
) -> None:
"""Display point cloud with downsampled normals.
Args:
point_cloud: A Zivid point cloud handle
downsampling: A valid Zivid downsampling factor to apply to normals
"""
point_cloud.downsample(downsampling)
rgb = point_cloud.copy_data("rgba_srgb")[:, :, :3]
xyz = point_cloud.copy_data("xyz")
normals = point_cloud.copy_data("normals")
open3d_point_cloud = _copy_to_open3d_point_cloud(xyz, rgb, normals)
_display_open3d_point_cloud(open3d_point_cloud)
结论
本教程展示了如何使用Zivid SDK在C++和C#中可视化点云,以及如何使用第三方库在Python中实现可视化功能。还展示了如何使用第三方库在C++、C#和Python中可视化彩色图像、深度图和法线。