教程5:使用ZED进行空间映射
本教程说明了如何在ZED中使用空间映射模块。 它将循环播放直到抓取500帧,提取网格,对其进行过滤并将其另存为obj文件。
我们假定您已遵循以前的教程。
先决条件
- Windows 7 64bits or later, Ubuntu 16.04
- ZED SDK and its dependencies (CUDA)
构建程序(Linux)
mkdir build
cd build
cmake ..
make
代码概述
创建一个相机
和以前的教程一样,我们创建,配置和打开ZED。 在此示例中,我们选择使用Y轴向上的右手坐标系,因为它是3D查看软件(例如,meshlab)中最常用的系统。
// Create a ZED camera object
Camera zed;
// Set configuration parameters
InitParameters init_params;
init_params.camera_resolution = RESOLUTION_HD720; // Use HD720 video mode (default fps: 60)
init_params.coordinate_system = COORDINATE_SYSTEM_RIGHT_HANDED_Y_UP; // Use a right-handed Y-up coordinate system
init_params.coordinate_units = UNIT_METER; // Set units in meters
// Open the camera
ERROR_CODE err = zed.open(init_params);
if (err != SUCCESS)
exit(-1);
启用位置跟踪
空间映射需要激活位置跟踪。 因此,与教程4-位置跟踪一样,我们需要首先启用跟踪模块。
sl::TrackingParameters tracking_parameters;
err = zed.enableTracking(tracking_parameters);
if (err != SUCCESS)
exit(-1);
启用空间映射
现在启用了跟踪,我们需要启用空间映射模块。 您将看到它非常接近位置跟踪:我们创建了一个空间映射参数,并使用此参数调用enableSpatialMapping()函数。
sl::SpatialMappingParameters mapping_parameters;
err = zed.enableSpatialMapping(mapping_parameters);
if (err != SUCCESS)
exit(-1);
本教程的目的不是进入SpatialMappingParameters类的详细信息,但是您可以在API文档中找到模式信息。
现在已激活空间映射。
采集数据
空间映射在抓取过程中不需要任何函数调用。 ZED SDK会处理并检查是否可以在映射模块中摄取新的图像,深度和位置,并将自动异步启动计算。
这意味着您只需捕获图像即可在背景中创建网格。
在本教程中,我们获取500帧,然后停止循环以提取网格
// Grab data during 500 frames
int i = 0;
sl::Mesh mesh; // Create a mesh object
while (i < 500) {
if (zed.grab() == SUCCESS) {
// In background, spatial mapping will use new images, depth and pose to create and update the mesh. No specific functions are required here
sl::SPATIAL_MAPPING_STATE mapping_state = zed.getSpatialMappingState();
// Print spatial mapping state
std::cout << "\rImages captured: " << i << " / 500 || Spatial mapping state: " << spatialMappingState2str(mapping_state) << " " << std::flush;
i++;
}
}
提取网格
现在,我们已经抓取了500帧,并且已经在后台创建了网格。 现在我们需要提取它。
首先,我们需要创建一个网格对象来操作它:sl :: Mesh。 然后使用Camera :: extractWholeMesh()启动提取。 该功能将一直阻塞,直到可用网格为止。
zed.extractWholeMesh(mesh); // Extract the whole mesh
现在我们有了一个网格。 可以过滤该网格(如果需要)以删除重复的顶点和不需要的面。 这将使网格更轻巧。
由于我们正在处理网格,因此此函数是sl :: Mesh的函数成员。
mesh.filter(sl::MeshFilterParameters::FILTER_LOW); // Filter the mesh (remove unnecessary vertices and faces)
您可以看到过滤器采用了过滤参数。 这使您可以微调处理。 同样,API文档中提供了有关过滤参数的更多信息。
现在,您可以将网格另存为obj文件,以进行外部操作:
mesh.save("mesh.obj"); // Save the mesh in an obj file
禁用模块并退出
一旦网格被提取并保存,别忘了在退出程序之前禁用模块并关闭相机。
由于空间映射需要位置跟踪,因此请始终在禁用跟踪之前禁用空间映射。
// Disable tracking and mapping and close the camera
zed.disableSpatialMapping();
zed.disableTracking();
zed.close();
return 0;
就是这样!
您现在可以使用ZED映射您的环境。