C++SDK移植指南
介绍
本指南重点介绍了API的更改。该流程遵循基于Zivid SDK的典型应用程序的流程。首先,将显示1.8.1版本中的代码示例,然后是2.0版本的示例。
例如:
1.8.1 |
2.0 |
---|---|
You will find code snippets from SDK 1.8.1 on this side,
|
and code snippets from SDK 2.0 on this side.
|
初始化
应用程序的初始化方式没有变化。
Zivid::Application zivid;
连接
默认连接没有变化。
auto camera = zivid.connectCamera();
连接 - 特定相机和列表相机
序列号现在组织在 Zivid::CameraInfo
下。它是 Zivid::Camera
的一个成员,通过 Zivid:Camera::info()
访问。
1.8.1 |
2.0 |
---|---|
auto camera = zivid.connectCamera(Zivid::SerialNumber{ "2020C0DE" });
|
auto camera = zivid.connectCamera(Zivid::CameraInfo::SerialNumber("2020C0DE"));
|
auto cameras = zivid.cameras();
for(auto cam : cameras)
{
std::cout << "Detected camera: "
<<cam.serialNumber() << std::endl;
}
|
auto cameras = zivid.cameras();
for(auto cam : cameras)
{
std::cout << "Detected camera: "
<< cam.info().serialNumber() << std.endl;
}
|
连接 - File Camera(文件相机)
1.8.1 |
2.0 |
---|---|
auto zdfFile = "MiscObjects.zdf";
auto camera = zivid.createFileCamera(zdfFile);
|
const auto cameraFile = "FileCameraZividOne.zfc";
auto camera = zivid.createFileCamera(cameraFile);
|
这里的变化是文件相机有了自己的文件类型。 Zivid文件相机(ZFC) 包含比普通Zivid数据文件 (ZDF) 更多的信息。
配置
3D设置 - 捕获助手
1.8.1 |
2.0 |
---|---|
const auto suggestSettingsParameters = Zivid::CaptureAssistant::SuggestSettingsParameters{
std::chrono::milliseconds{ 900 },
Zivid::CaptureAssistant::AmbientLightFrequency::none
};
const auto settingsVector{ Zivid::CaptureAssistant::suggestSettings(camera, suggestSettingsParameters) };
|
const auto suggestSettingsParameters = Zivid::CaptureAssistant::SuggestSettingsParameters{
Zivid::CaptureAssistant::SuggestSettingsParameters::AmbientLightFrequency::none,
Zivid::CaptureAssistant::SuggestSettingsParameters::MaxCaptureTime{ std::chrono::milliseconds{ 900 } }
};
const auto settings = Zivid::CaptureAssistant::suggestSettings(camera, suggestSettingsParameters);
|
我们在构造函数中使用显式类型,并接受Zivid::SuggestSettingsParameters的所有后代。
3D设置 - 手动配置
Zivid::Settings
Zivid SDK 2.0对捕获设置进行了重大更改。最显着的变化是单个 Zivid::Settings
对象现在包含了任何捕获任务的完整设置,包括多采集捕获(HDR)。这与SDK 1.x显著不同,在SDK 1.x中,HDR捕获由以下方式表示:
Settings
对象列表,或可以在以后合并的帧列表
在SDK 2.0中, Settings
对象分为两个主要部分:
Zivid::Settings::Acquisitions
:Zivid::Settings::Acquisition
的列表指定了Zivid相机本身的图像采集参数。每个Acquisition
都包含了诸如相机光圈(f-值)和投影仪亮度等设置。Zivid::Settings::Processing
:指定了通过相机获取的图像在PC的GPU上发生的点云处理的参数。这包括过滤器设置和颜色设置。
其次, Settings
不再作为单独的操作在捕获之前提供给相机。在SDK 2.0中,设置作为参数传递给 Zivid::Camera::capture(Zivid::Settings)
。用户可以根据需要指定尽可能少或尽可能多的 Zivid::Settings
的参数。剩余的相机模型适当的默认值将在调用 capture()
时应用。
最后,通过将 Zivid::Settings2D
传递给相同的捕获函数 Zivid::Camera::capture(Settings2D)
来执行2D捕获。新的 Settings2D
的结构类似于新的 Settings
。
Zivid::Settings:Acquisition(s)
在SDK 1.0中,通过构造 Settings
列表来指定HDR捕获。在 SDK 2.0 中,所有内容都包含在单个 Settings
中,并且通过让其包含多个 Zivid::Settings::Acquisition
来指定HDR捕获。这些可以在构建Settings时创建,或者稍后添加,例如 settings.acquisitions().emplaceBack(acquisition)
。如需查看示例,请参阅 CaptureHDRCompleteSettings 示例。
以下是旧设置成员与新 Zivid::Settings::Acquisition
成员之间关系的摘要:
|
→ |
|
|
→ |
|
|
→ |
|
|
→ |
|
|
→ |
此设置已被移除 |
Zivid::Settings::Processing
Filters
加入了一个新的 对比度失真 过滤器, Zivid::Settings::Processing::Experimental::ContrastDistortion
。
备注
对比度失真过滤器与旧的对比度值没有任何关系。
过滤器在采集后应用,并组织在 Zivid::Settings::Processing::Filters
下。下面显示了过滤器是如何移动的,并且在某些情况下是如何改变的。
|
→ |
此过滤器已删除。它将始终处于启用状态。 |
|
→ |
|
|
→ |
|
|
→ |
|
|
→ |
这个过滤器被一个新的过滤器取代 - |
对比度过滤器(contrast filter)根据对比度值阈值移除点。噪声过滤器(noise filter)根据 SNR值 阈值来移除点。SNR和对比度值的计算方式不同,因此这两个滤波器是不同的。可以将噪声过滤器看做对比度过滤器的改进型过滤器。为了获得类似的结果,需要设置不同的阈值。比如,与对比度阈值3相近的是噪声阈值7。
Color Balance
SDK 2.0改进了色彩平衡。颜色平衡设置现在只影响点云的颜色,对计算的XYZ点坐标没有影响。
|
→ |
|
|
→ |
|
N/A |
→ |
|
示例:Settings中的单帧 → 单次采集
1.8.1 |
2.0 |
---|---|
camera << Zivid::Settings::Iris{ 20 }
<< Zivid::Settings::ExposureTime{ std::chrono::microseconds{ 10000 } }
<< Zivid::Settings::Brightness{ 1 }
<< Zivid::Settings::Gain{ 1 }
<< Zivid::Settings::Filters::Contrast::Enabled::yes
<< Zivid::Settings::Filters::Contrast::Threshold{ 5 };
const auto frame = camera.capture();
|
const auto settings = Zivid::Settings{
Zivid::Settings::Acquisitions{
Zivid::Settings::Acquisition{ Zivid::Settings::Acquisition::Aperture{ 5.66 },
Zivid::Settings::Acquisition::ExposureTime{ std::chrono::microseconds{ 10000 } },
Zivid::Settings::Acquisition::Brightness{ 1.0 },
Zivid::Settings::Acquisition::Gain{ 1.0 } } },
Zivid::Settings::Processing::Filters::Noise::Removal::Enabled::yes,
Zivid::Settings::Processing::Filters::Noise::Removal::Threshold{ 7.0 }
};
const auto frame = camera.capture(settings);
|
请注意 Settings
现在作为参数提供给捕获(capture )函数,而不是事先提供给相机。
示例:Settings中的HDR帧 → 多个采集
Zivid::Settings
现在包含一个向量来保存多个采集的设置。
1.8.1 |
2.0 |
---|---|
std::vector<Zivid::Settings> settingsVector;
for(const size_t iris : { 14U, 21U, 35U })
{
std::cout << "Add settings for frame with iris = " << iris << std::endl;
auto settings = Zivid::Settings::Settings();
settings.set(Zivid::Settings::Iris{ iris });
settingsVector.emplace_back(settings);
}
|
const auto settings = Zivid::Settings();
for(const auto aperture : { 10.90, 5.80, 2.83 })
{
const auto acquisitionSettings = Zivid::Settings::Acquisition{
Zivid::Settings::Acquisitions::Aperture{ aperture },
}
settings.acquisitions().emplaceBack(acquisitionSettings);
}
|
示例:导入YML文件
Zivid::Camera
在新的SDK中不再保持settings的相关设置,从文件加载配置是在 Zivid::Settings
中完成的。
1.8.1 |
2.0 |
---|---|
camera.setSettings(Zivid::Settings("Frame01.yml"));
|
const auto settings = Zivid::Settings("Settings.yml");
|
或者,在连接到相机时:
1.8.1 |
2.0 |
---|---|
auto camera = zivid.connectCamera(Zivid::Settings("Frame01.yml"));
|
N/A |
这里的主要变化是输入文件包含了所有采集的设置。以前我们每帧只有一个文件,现在我们有了一个包含所有内容的文件。还要注意在此上下文中名称从Frame更改为Acquisition。
Zivid::Settings 的新旧 .yaml 的完整比较
1.8.1 |
2.0 |
---|---|
__version__: 3
Settings:
Bidirectional: no
BlueBalance: 1.081000
Brightness: 1.000000
ExposureTime: 10000
Filters:
Contrast:
Enabled: yes
Threshold: 3.000000
Gaussian:
Enabled: yes
Sigma: 1.500000
Outlier:
Enabled: yes
Threshold: 20.000000
Reflection:
Enabled: yes
Saturated:
Enabled: yes
Gain: 1.000000
Iris: 17
RedBalance: 1.709000
__version__: 3
Settings:
Bidirectional: no
BlueBalance: 1.081000
Brightness: 1.000000
ExposureTime: 10000
Filters:
Contrast:
Enabled: yes
Threshold: 3.000000
Gaussian:
Enabled: yes
Sigma: 1.500000
Outlier:
Enabled: yes
Threshold: 20.000000
Reflection:
Enabled: yes
Saturated:
Enabled: yes
Gain: 1.000000
Iris: 27
RedBalance: 1.709000
__version__: 3
Settings:
Bidirectional: no
BlueBalance: 1.081000
Brightness: 1.000000
ExposureTime: 10000
Filters:
Contrast:
Enabled: yes
Threshold: 3.000000
Gaussian:
Enabled: yes
Sigma: 1.500000
Outlier:
Enabled: yes
Threshold: 20.000000
Reflection:
Enabled: yes
Saturated:
Enabled: yes
Gain: 4.000000
Iris: 35
RedBalance: 1.709000
|
__version__:
serializer: 1
data: 4
Settings:
Acquisitions:
- Acquisition:
Aperture: 7.98
Brightness: 1.8
ExposureTime: 10000
Gain: 1
- Acquisition:
Aperture: 4.02
Brightness: 1.8
ExposureTime: 10000
Gain: 1
- Acquisition:
Aperture: 2.81
Brightness: 1.8
ExposureTime: 10000
Gain: 4
Processing:
Color:
Balance:
Blue: 1.081
Green: 1
Red: 1.709
Filters:
Experimental:
ContrastDistortion:
Correction:
Enabled: no
Strength: 0.4
Removal:
Enabled: no
Threshold: 0.5
Noise:
Removal:
Enabled: yes
Threshold: 7
Outlier:
Removal:
Enabled: yes
Threshold: 5
Reflection:
Removal:
Enabled: yes
Smoothing:
Gaussian:
Enabled: yes
Sigma: 1.5
|
Settings 2D
配置 Zivid::Settings2D
的方法与 Zivid::Settings
相同。请参阅 3D设置 - 手动配置
Zivid::Settings2D::Acquisition(采集设置 - 以前的帧设置)
Zivid::Settings2D::Acquisition
的更改和 Zivid::Settings::Acquisition
一样,请参阅 Acquisition Settings (3D)。请注意,2D 设置仅允许单次采集(无法进行多次采集2D HDR)。
Zivid::Settings2D::Processing
请注意,我们不支持2D设置的过滤器。
Color Balance
现在为2D设置添加了色彩平衡。配置 Zivid::Settings2D::Processing::Color::Balance
与配置 Zivid::Settings::Processing::Color::Balance
相同,参考 Color Balance (3D )。
Capture
3D - 单次采集
新的 Zivid::Camera::capture()
API总是将设置作为输入。
1.8.1 |
2.0 |
---|---|
auto frame = camera.capture();
|
auto frame = camera.capture(settings);
|
3D - 多次采集HDR
捕获是单次采集还是多次采集 (HDR) 由输入参数设置决定。调用签名始终是 Zivid::Camera::capture(Zivid::Settings)
,无论是单次采集还是HDR。
2D采集
捕获2D图像的API 在*capture*中没有 2D,即它是 Zivid::Camera::capture()
而不是 Zivid::Camera::capture2D()
。Zivid::Camera::capture()
生成2D还是3D由输入参数 Zivid::Settings2D
或 Zivid::Settings
给出。
1.8.1 |
2.0 |
---|---|
auto frame2D = camera.capture2D(settings2D);
auto image = frame2D.image<Zivid::RGBA8>();
|
auto frame2D = camera.capture(settings2D);
auto image = frame2D.imageRGBA();
|
可以通 frame2D.imageRGBA()
而不是 frame2D.image<Zivid::RGBA8>()
来读取捕获的图像。图像始终是具有8位红色、绿色、蓝色和alpha通道的RGBA像素的二维数组。
点云
在SDK 2.0之前,点云是通过Zivid::Frame::getPointCloud()访问的。此API以1200x1920x7矩阵将所有数据从GPU复制到系统内存,请参阅 Point Cloud。在SDK 2.0中,您首先通过 Zivid::Frame::pointCloud()
获取GPU上点云数据的句柄。此调用不会从GPU内存执行任何复制。然后,您可以根据需要有选择地复制数据。您甚至可以直接复制到您自己预先分配的内存中。
并且还引入了新的点云质量值: Signal-to-Noise-Ratio (SNR)。这个值替换了旧的对比度值,并且始终是非负非NaN的数值。
以下是新输出数据格式的完整列表以及如何从GPU复制它们:
返回类型 |
从GPU复制的函数 |
每像素数据 |
复制的总数据 |
---|---|---|---|
|
|
12 bytes |
28 MB |
|
|
16 bytes |
37 MB |
|
|
4 bytes |
9 MB |
|
|
4 bytes |
9 MB |
|
|
4 bytes |
9 MB |
|
|
16 bytes |
37 MB |
|
|
16 bytes |
37 MB |
|
|
4 bytes |
9 MB |
将选定数据从GPU复制到系统内存(Zivid分配)
如果用户只对点云的XYZ坐标感兴趣,他们之前需要调用 Zivid::Frame::getPointCloud()
。然后,此函数会将所有数据复制到系统内存。在SDK 2.0中,这可以通过仅调用 PointCloud::copyPointsXYZ()
更快地实现。同样的,考虑这样一个用例,我们只需要点云中的RGB颜色:
1.8.1 |
2.0 |
---|---|
const auto pointCloud = frame.getPointCloud();
cv::Mat rgb(pointCloud.height(), pointCloud.width(),
CV_8UC3, cv::Scalar(0, 0, 0));
const auto height = pointCloud.height();
const auto width = pointCloud.width();
for(size_t i = 0; i < height; i++)
{
for(size_t j = 0; j < width; j++)
{
auto &color = bgr.at<cv::Vec3b>(i, j);
color[0] = pointCloud(i, j).red();
color[1] = pointCloud(i, j).green();
color[2] = pointCloud(i, j).blue();
}
}
第1行:将XYZ+RGBA+对比度数据从GPU复制到系统内存。
第3行:分配具有适当大小的OpenCV矩阵来仅保存RGB数据。
第8-17行:选择性地将RGB数据从系统内存的一部分复制到另一部分。
|
auto rgba = frame.pointCloud().copyColorsRGBA();
auto *dataPtr = const_cast<void *>(static_cast<const void *>(image.data()));
cv::Mat rgba(rgba.height(), rgba.width(), CV_8UC4, dataPtr);
第1行:将颜色数据从GPU复制到
Zivid::Array2D<Zivid::ColorRGBA> ,它拥有数据的所有权。
第2行:将数据指针转换为
void* ,因为这就是OpenCV矩阵构造函数需要的。
第3行:我们将此数据块包装在OpenCV矩阵中。
这是可能实现的,因为
Zivid::ColorRGBA 的布局完全匹配CV_8UC4的布局。此步骤不会进行复制的操作。
|
将选定数据从GPU复制到系统内存(用户分配)
在上面的示例中,数据的所有权由返回的 Zivid::Array2D<>
对象持有。或者,用户可以为 Zivid::PointCloud::copyData(dataPtr)
提供一个预分配的内存缓冲区。dataPtr
的类型定义了要复制的内容(PointXYZ*
、ColorRGBA*
等)。
现在让我们看一下与上面完全相同的用例。但是,这一次我们让OpenCV分配必要的存储空间,然后我们要求Zivid API将数据直接从GPU复制到这个内存位置:
1.8.1 |
2.0 |
---|---|
const auto pointCloud = frame.getPointCloud();
cv::Mat rgb(pointCloud.height(), pointCloud.width(),
CV_8UC3, cv::Scalar(0, 0, 0));
const auto height = pointCloud.height();
const auto width = pointCloud.width();
for(size_t i = 0; i < height; i++)
{
for(size_t j = 0; j < width; j++)
{
auto &color = bgr.at<cv::Vec3b>(i, j);
color[0] = pointCloud(i, j).red();
color[1] = pointCloud(i, j).green();
color[2] = pointCloud(i, j).blue();
}
}
第1行:将XYZ+RGBA+对比度数据从GPU复制到系统内存。
第3行:分配具有适当大小的OpenCV矩阵。
第8-17行:选择性地将RGB数据从系统内存的一部分复制到另一部分。
|
const auto pointCloud = frame.pointCloud();
auto rgba = cv::Mat(pointCloud.height(), pointCloud.width(), CV_8UC4);
auto *dataPtr = reinterpret_cast<Zivid::ColorRGBA *>(rgba.data);
pointCloud.copyData(dataPtr);
第1行:获取GPU上完整点云的句柄。
第2行:分配一个适当大小的OpenCV矩阵。
第3行:将OpenCV数据指针转换为ColorRGBA*,以便Zivid API可以
了解要复制哪些数据。
第4行:将RGBA数据直接复制到OpenCV内存缓冲区中。
|
可视化
Zivid可视化模块已重命名和移动。
|
→ |
|
|
→ |
|
|
→ |
|
|
→ |
|
1.8.1 |
2.0 |
---|---|
Zivid::CloudVisualizer vis;
zivid.setDefaultComputeDevice(vis.computeDevice());
...
vis.showMaximized();
vis.show(frame);
vis.resetToFit();
vis.run();
|
Zivid::Visualization::Visualizer visualizer;
...
visualizer.showMaximized();
visualizer.show(frame);
visualizer.resetToFit();
visualizer.run();
|
不支持同时使用多个计算设备。因此对 setDefaultComputeDevice
的调用是多余的。
保存
3D
3D数据的保存方式没有变化。
frame.save("Frame");
二维
1.8.1 |
2.0 |
---|---|
frame2D.image<Zivid::RGBA8>().save("Image.png");
|
frame2D.imageRGBA().save("Image.png");
|
Misc
内参
intrinsics()
函数从 Camera
类中移出并放置在 Experimental::Calibration
命名空间内。它现在将 Camera
作为参数。
|
→ |
|
1.8.1 |
2.0 |
---|---|
auto intrinsics = camera.intrinsics();
|
auto intrinsics = Zivid::Experimental::Calibration::intrinsics(camera);
|
信息
Camera
里用于获取固件版本、型号名称等信息的成员函数已被删除。关于相机的信息现在被组织在 Zivid::CameraInfo
下。这是 Zivid::Camera
的成员,通过 Zivid::Camera::info()
访问。
1.8.1 |
2.0 |
---|---|
auto firmwareVersion = camera.firmwareVersion();
|
auto firmwareVersion = camera.info().firmwareVersion();
|
auto modelName = camera.modelName();
|
auto modelName = camera.info().modelName();
|
auto majorRevision = camera.revision().majorRevision();
auto minorRevision = camera.revision().minorRevision();
|
auto majorRevision = camera.info().revision().major();
auto minorRevision = camera.info().revision().minor();
|
auto serialNumber = camera.serialNumber();
|
auto serialNumber = camera.info().serialNumber();
|
auto maxDataSize = camera.userDataMaxSizeBytes();
|
auto maxDataSize = camera.info().userData().maxSizeBytes().value();
|