C++SDK 移植指南

备注

This guide documents the SDK 1.8.1-to-2.0 transition and presents the unified capture(Settings)/capture(Settings2D) introduced in 2.0 as the current API. Since SDK 2.14, both are deprecated and scheduled for removal in SDK 3.0: use capture2D3D(Settings) or capture3D(Settings) in place of capture(Settings), and capture2D(Settings) or capture2D(Settings2D) in place of capture(Settings2D).

介绍

This guide focuses on changes to the API. The flow follows that of a typical application based on the Zivid SDK. First, an example of the code from 1.8.1 will be shown and then the 2.0 example.

例如:

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();

连接 - 特定相机和列表相机

序列号现在组织在 CameraInfo 下。它是 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 对捕获设置进行了重大更改。最显着的变化是单个 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) 。用户可以根据需要指定尽可能少或尽可能多的 Settings 的参数。剩余的相机模型适当的默认值将在调用 capture() 时应用。

最后,通过将 Settings2D 传递给相同的捕获函数 Zivid::Camera::capture(Settings2D) 来执行 2D 捕获。新的 Settings2D 的结构类似于新的 Settings 。

Zivid::Settings:Acquisition(s)

在 SDK 1 中,通过构造 Settings 列表来指定 HDR 捕获。在 SDK 2.0 中,所有内容都包含在单个 Settings 中,并且通过让其包含多个 Zivid::Settings::Acquisition 来指定 HDR 捕获。这些可以在构建 Settings 时创建,或者稍后添加,例如 settings.acquisitions().emplaceBack(acquisition)。如需查看示例,请参阅 CaptureHDRCompleteSettings.cpp 示例。

以下是旧设置成员与新 Zivid::Settings::Acquisition 成员之间关系的摘要:

Settings::ExposureTime

→

Zivid::Settings::Acquisition::ExposureTime

Settings::Gain

→

Zivid::Settings::Acquisition::Gain

Settings::Brightness

→

Zivid::Settings::Acquisition::Brightness

Settings::Iris

→

Zivid::Settings::Acquisition::Aperture [1]

Settings::Bidirectional

→

此设置已被移除

Zivid::Settings::Processing

Filters

加入了一个新的 对比度失真 过滤器, Zivid::Settings::Processing::Experimental::ContrastDistortion 。

备注

对比度失真过滤器与旧的对比度值没有任何关系。

过滤器在采集后应用,并组织在 Zivid::Settings::Processing::Filters 下。下面显示了过滤器是如何移动的,并且在某些情况下是如何改变的。

Zivid::Settings::Filters::Saturated

→

此过滤器已删除。它将始终处于启用状态。

Zivid::Settings::Filter::Gaussian

→

Zivid::Settings::Processing::Filters::Smoothing::Gaussian

Zivid::Settings::Filter::Outlier

→

Zivid::Settings::Processing::Filters::Outlier::Removal

Zivid::Settings::Filter::Reflection

→

Zivid::Settings::Processing::Filters::Reflection::Removal

Settings::Contrast

→

这个过滤器被一个新的过滤器取代 - Zivid::Settings::Processing::Filters::Noise::Removal [2]

Color Balance

SDK 2.0 改进了色彩平衡。颜色平衡设置现在只影响点云的颜色,对计算的 XYZ 点坐标没有影响。

Settings::BlueBalance

→

Zivid::Settings::Processing::Color::Balance::Blue

Settings::RedBalance

→

Zivid::Settings::Processing::Color::Balance::Red

N/A

→

Zivid::Settings::Processing::Color::Balance::Green (新)

示例: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 帧 → 多个采集

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 文件

Camera 在新的 SDK 中不再保持 settings 的相关设置,从文件加载配置是在 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

配置 Settings2D 的方法与 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 - 单次采集

新的 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,即它是 Camera::capture() 而不是 Camera::capture2D()。Camera::capture() 生成 2D 还是 3D 由输入参数 Settings2D 或 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 之前,点云是通过 Frame::getPointCloud() 访问的。此 API 以 1200x1920x7 矩阵将所有数据从 GPU 复制到系统内存,请参阅 Point Cloud。在 SDK 2.0 中,您首先通过 Frame::pointCloud() 获取 GPU 上点云数据的句柄。此调用不会从 GPU 内存执行任何复制。然后,您可以根据需要有选择地复制数据。您甚至可以直接复制到您自己预先分配的内存中。

并且还引入了新的点云质量值: Signal-to-Noise-Ratio (SNR)。这个值替换了旧的对比度值,并且始终是非负非 NaN 的数值。

以下是新输出数据格式的完整列表以及如何从 GPU 复制它们:

返回类型

从 GPU 复制的函数

每像素数据

复制的总数据

Zivid::Array2D<Zivid::PointXYZ>

PointCloud::copyPointsXYZ() (或 PointCloud::copyData<Zivid::PointXYZ>())

12 bytes

28 MB

Zivid::Array2D<Zivid::PointXYZW>

PointCloud::copyPointsXYZW() (或 PointCloud::copyData<Zivid::PointXYZW>())

16 bytes

37 MB

Zivid::Array2D<Zivid::PointZ>

PointCloud::copyPointsZ() (或 PointCloud::copyData<Zivid::PointZ>())

4 bytes

9 MB

Zivid::Array2D<Zivid::ColorRGBA>

PointCloud::copyColorsRGBA() (或 PointCloud::copyData<Zivid::ColorRGBA>())

4 bytes

9 MB

Zivid::Array2D<Zivid::SNR>

PointCloud::copySNRs() (或 PointCloud::copyData<Zivid::SNR>())

4 bytes

9 MB

Zivid::Array2D<Zivid::PointXYZColorRGBA>

PointCloud::copyData<PointXYZColorRGBA>()

16 bytes

37 MB

Zivid::Array2D<Zivid::PointXYZColorBGRA>

PointCloud::copyPointsXYZColorsBGRA() (或 PointCloud::copyData<PointXYZColorBGRA>())

16 bytes

37 MB

Zivid::Image<Zivid::ColorRGBA>

PointCloud::copyImageRGBA()

4 bytes

9 MB

将选定数据从 GPU 复制到系统内存(Zivid 分配)

如果用户只对点云的 XYZ 坐标感兴趣,他们之前需要调用 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 复制到系统内存(用户分配)

In the Zivid-allocated example above, ownership of the data was held by the returned Zivid::Array2D<> objects. Alternatively, the user may provide a pre-allocated memory buffer to Zivid::PointCloud::copyData(dataPtr). The type of dataPtr defines what shall be copied (PointXYZ*, ColorRGBA*, etc).

Now let us look at the same RGB-copy use case as in the Zivid-allocated example. However, this time we let OpenCV allocate the necessary storage, and then we ask the Zivid API to copy data directly from the GPU into this memory location:

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 可视化模块已重命名和移动。

Vis3D 库

→

Visualization 库

Zivid::CloudVisualizer

→

Visualization::Visualizer

Zivid::CloudVisualizer::EnableColors

→

Visualization::Visualizer::ColorsEnabled

Zivid::CloudVisualizer::EnableMeshing

→

Visualization::Visualizer::MeshingEnabled

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 作为参数。

Camera::intrinsics()

→

Zivid::Experimental::Calibration::intrinsics(camera)

1.8.1

2.0

auto intrinsics = camera.intrinsics();
auto intrinsics = Zivid::Experimental::Calibration::intrinsics(camera);

信息

Camera 里用于获取固件版本、型号名称等信息的成员函数已被删除。关于相机的信息现在被组织在 CameraInfo 下。这是 Camera 的成员,通过 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();