感兴趣区域(ROI)的使用教程

感兴趣区域 (ROI) 会移除用户定义感兴趣区域之外的点,从而缩短捕获时间。ROI 可以是 3D 中的框、相机的 z 值范围,或两者兼而有之。

如果应用程序只需要一部分视野而不是整个场景,那么ROI功能会很有用。例如,如果您想要检测料箱中的零件,相对于针对真个场景进行检测,您的检测算法可能会受益于搜索空间减少的料箱*内部*空间。

../../_images/roi.png

将 ROI 定义为框

ROI 框过滤的好处

ROI 框过滤提供以下一种或多种优势:

减少捕获时间(相同点云质量)

需要传输、复制和处理的数据更少;通过以下一项或两项操作可以显著提高速度:

  • 性能较低的 GPU (Intel/Jetson)

  • 繁重的点云处理工作(Omni/Stripe、5MP 分辨率、多采集 HDR)

更好的点云质量(相同的捕获时间)

可以使用不同的设置;例如:

  • 使用 Stripe/Omni 引擎代替 Phase

  • 使用 Sampling::Pixel 实现更高分辨率

  • 在 HDR 中添加更多采集

更便宜的 GPU(相同的捕获时间)

由于需要处理的数据较少,因此您可以使用诸如以下的硬件:

  • 使用Intel/Jetson 代替 Nvidia 独立显卡

更便宜的网卡(相同的捕获时间)

由于需要传输的数据较少,您可能不会使网络饱和,从而可以使用例如:

  • 1G 而非 2.5G/10G 网卡

  • 2.5G 而非 10G 网卡

参数 RegionOfInterest::Box 允许将 ROI 设置为过滤框。 三个点(point) 定义了框的底面, 两个范围(extent) 定义了高度:

  • 这三个点( Box::PointOBox::PointABox::PointB )在 3D 相机参考系中给出,并定义ROI框的基平面。系统会自动找到第四个点,将基平面绑定到坐标系中并完成矩形的设定。三点依次构成两个向量:

    • 点O是向量的原点。

    • 点A定义了从原点生成的第一个向量。

    • 点B定义了从原点生成的第二个向量。

  • 两个范围( Box::Extents )将基坐标系挤压成一个框。由点 O、点 A 和点 B 定义的向量 OAOB 的叉积给出了范围(extent)的方向。因此,负范围(extent)将沿叉积的相反方向延伸。

../../_images/roi_explanation.png

ROI盒的示意图:三个点(O、A和B)定义了框的底部平面,并自动选择第四个点来完成矩形。然后可以向上 (+E2) 和向下 (-E1) 拉伸由四个点定义的有界平面以完成框的定义。

备注

ROI盒的基坐标系 没有 被限制为一个角垂直的矩形。因此可以定义一个平行四边形作为底面,并定义一个平行六面体的ROI盒。

小技巧

请遵循以下经验法则来选择三个定义点:

  1. 在任意的一个角落选择点O。

  2. 选择点A,使点B位于相对于点A 逆时针 方向的位置。

  3. 在点A逆时针方向的某个位置选择点B。

这样,范围(extents)将具有朝向相机的正方向。

在 Zivid Studio 中配置 ROI 框

备注

使用点选择器时,您无法选择点云中为 NaN 的像素。因此,您只能选择与点云中的实际点相对应的像素。

在 Zivid Studio 中创建 ROI 框后,您可以导出 YAML 格式的配置文件,并将其重新加载到您的应用程序中。

跳转到源码

source

const auto settingsFile = "Settings.yml";
std::cout << "Loading settings from file: " << settingsFile << std::endl;
const auto settingsFromFile = Zivid::Settings(settingsFile);
跳转到源码

源码

var settingsFile = "Settings.yml";
Console.WriteLine("Loading settings from file: " + settingsFile);
var settingsFromFile = new Zivid.NET.Settings(settingsFile);
跳转到源码

源码

settings_file = "Settings.yml"
print(f"Loading settings from file: {settings_file}")
settings_from_file = zivid.Settings.load(settings_file)

ROI 框示例和性能

机器人拾取示例

这是一个使用低端PC(配备Nvidia MX 250笔记本 GPU 和 1G 网卡)进行大规模点云处理的例子,在此场景中 ROI 框区域过滤技术极为有益。

想象一下,一个机器人用固定安装的 Zivid 2+ M130 相机从 600 x 400 x 300 毫米的箱子中拾取物品。为了给机器人留出足够的空间,相机安装在距离箱子顶部 1700 毫米的位置,提供大约 1000 x 800 毫米的视场。当相机安装在这个距离时,大部分视场都在 ROI 之外,因此可以从每一侧裁剪约 20/25% 的像素列/行。从下表可以看出,使用 ROI 框过滤可以显著缩短捕获时间。

../../_images/roi_example_bin_picking.png

预设值

采集时间

捕获时间

未设置 ROI

设置了 ROI

未设置 ROI

设置了 ROI

Manufacturing Specular

0.64 s

0.64 s

2.1 s

1.0 s

Consumer Goods Quality

0.90 s

0.88 s

5.0 s

3.0 s

机器人引导/装配示例

这是一个使用低端PC(配备Nvidia MX 250笔记本 GPU 和 1G 网卡)进行大规模点云处理的例子,在此场景中 ROI 框区域过滤技术极为有益。

在某些机器人引导应用(如钻孔、焊接、涂胶)或装配应用(如插销入孔)中,相对于相机在成像距离下的视场(FOV),感兴趣的区域(ROI)可能非常小。在这种情况下,ROI 往往仅包含点云中 5-10% 的点,利用 ROI 框过滤可以大幅减少数据采集时间(见下表)。

../../_images/roi_example_robot_guidance.png

预设值

采集时间

捕获时间

未设置 ROI

设置了 ROI

未设置 ROI

设置了 ROI

Manufacturing Specular

0.65 s

0.63 s

1.3 s

0.7 s

Manufacturing Small Features

0.70 s

0.65 s

5.0 s

0.8 s

深度范围定义的ROI

参数 RegionOfInterest::Depth 允许用户将 ROI 用作根据相机坐标系的一个 z 值范围来进行过滤,以下阈值范围内的点才会被保留:

  • 最小深度阈值( RegionOfInterest::Depth::minValue

  • 最大深度阈值( RegionOfInterest::Depth::maxValue

如果场景的前方或后方有需要过滤的点,那么这种方式将会很有用。请注意,z值是基于相机参考系给出的,即垂直于相机方向进行过滤。因此,如果相机垂直安装在您要拍摄的物体上,效果最佳。

../../_images/roi_depth.png

ROI API

ROI是 相机设置 的一部分,在Zivid SDK主设置对象下进行设置。因此,它在*当您捕获时*应用,而不是之后应用在点云对象上。

小技巧

ROI 框过滤方法可以减少捕获时间,而深度范围定义的 ROI 则 不会

跳转到源码

source

std::cout << "Configuring settings for capture:" << std::endl;
Zivid::Settings settings{
    Zivid::Settings::Engine::phase,
    Zivid::Settings::Sampling::Color::rgb,
    Zivid::Settings::Sampling::Pixel::blueSubsample2x2,
    Zivid::Settings::RegionOfInterest::Box::Enabled::yes,
    Zivid::Settings::RegionOfInterest::Box::PointO{ 1000, 1000, 1000 },
    Zivid::Settings::RegionOfInterest::Box::PointA{ 1000, -1000, 1000 },
    Zivid::Settings::RegionOfInterest::Box::PointB{ -1000, 1000, 1000 },
    Zivid::Settings::RegionOfInterest::Box::Extents{ -1000, 1000 },
    Zivid::Settings::RegionOfInterest::Depth::Enabled::yes,
    Zivid::Settings::RegionOfInterest::Depth::Range{ 200, 2000 },
    Zivid::Settings::Processing::Filters::Smoothing::Gaussian::Enabled::yes,
    Zivid::Settings::Processing::Filters::Smoothing::Gaussian::Sigma{ 1.5 },
    Zivid::Settings::Processing::Filters::Noise::Removal::Enabled::yes,
    Zivid::Settings::Processing::Filters::Noise::Removal::Threshold{ 7.0 },
    Zivid::Settings::Processing::Filters::Noise::Suppression::Enabled::yes,
    Zivid::Settings::Processing::Filters::Noise::Repair::Enabled::yes,
    Zivid::Settings::Processing::Filters::Outlier::Removal::Enabled::yes,
    Zivid::Settings::Processing::Filters::Outlier::Removal::Threshold{ 5.0 },
    Zivid::Settings::Processing::Filters::Reflection::Removal::Enabled::yes,
    Zivid::Settings::Processing::Filters::Reflection::Removal::Mode::global,
    Zivid::Settings::Processing::Filters::Cluster::Removal::Enabled::yes,
    Zivid::Settings::Processing::Filters::Cluster::Removal::MaxNeighborDistance{ 10 },
    Zivid::Settings::Processing::Filters::Cluster::Removal::MinArea{ 100 },
    Zivid::Settings::Processing::Filters::Experimental::ContrastDistortion::Correction::Enabled::yes,
    Zivid::Settings::Processing::Filters::Experimental::ContrastDistortion::Correction::Strength{ 0.4 },
    Zivid::Settings::Processing::Filters::Experimental::ContrastDistortion::Removal::Enabled::no,
    Zivid::Settings::Processing::Filters::Experimental::ContrastDistortion::Removal::Threshold{ 0.5 },
    Zivid::Settings::Processing::Filters::Hole::Repair::Enabled::yes,
    Zivid::Settings::Processing::Filters::Hole::Repair::HoleSize{ 0.2 },
    Zivid::Settings::Processing::Filters::Hole::Repair::Strictness{ 1 },
    Zivid::Settings::Processing::Resampling::Mode::upsample2x2,
    Zivid::Settings::Processing::Color::Balance::Red{ 1.0 },
    Zivid::Settings::Processing::Color::Balance::Green{ 1.0 },
    Zivid::Settings::Processing::Color::Balance::Blue{ 1.0 },
    Zivid::Settings::Processing::Color::Gamma{ 1.0 },
    Zivid::Settings::Processing::Color::Experimental::Mode::automatic
};
std::cout << settings << std::endl;
跳转到源码

源码

Console.WriteLine("Configuring settings for capture:");
var settings = new Zivid.NET.Settings()
{
    Engine = Zivid.NET.Settings.EngineOption.Phase,
    Sampling = { Color = Zivid.NET.Settings.SamplingGroup.ColorOption.Rgb, Pixel = Zivid.NET.Settings.SamplingGroup.PixelOption.BlueSubsample2x2 },
    RegionOfInterest = { Box = {
                            Enabled = true,
                            PointO = new Zivid.NET.PointXYZ{ x = 1000, y = 1000, z = 1000 },
                            PointA = new Zivid.NET.PointXYZ{ x = 1000, y = -1000, z = 1000 },
                            PointB = new Zivid.NET.PointXYZ{ x = -1000, y = 1000, z = 1000 },
                            Extents = new Zivid.NET.Range<double>(-1000, 1000),
                        },
                        Depth =
                        {
                            Enabled = true,
                            Range = new Zivid.NET.Range<double>(200, 2000),
                        }
    },
    Processing = { Filters = { Smoothing = { Gaussian = { Enabled = true, Sigma = 1.5 } },
                               Noise = { Removal = { Enabled = true, Threshold = 7.0 },
                                         Suppression = { Enabled = true },
                                         Repair ={ Enabled = true } },
                               Outlier = { Removal = { Enabled = true, Threshold = 5.0 } },
                               Reflection = { Removal = { Enabled = true, Mode = ReflectionFilterModeOption.Global} },
                               Cluster = { Removal = { Enabled = true, MaxNeighborDistance = 10, MinArea = 100} },
                               Hole = { Repair = { Enabled = true, HoleSize = 0.2, Strictness = 1 } },
                               Experimental = { ContrastDistortion = { Correction = { Enabled = true,
                                                                                      Strength = 0.4 },
                                                                       Removal = { Enabled = true,
                                                                                   Threshold = 0.5 } } } },
                   Resampling = { Mode = Zivid.NET.Settings.ProcessingGroup.ResamplingGroup.ModeOption.Upsample2x2},
                   Color = { Balance = { Red = 1.0, Green = 1.0, Blue = 1.0 },
                             Gamma = 1.0,
                             Experimental = { Mode = ColorModeOption.Automatic } } }
};
Console.WriteLine(settings);
跳转到源码

源码

print("Configuring settings for capture:")
settings = zivid.Settings()
settings.engine = zivid.Settings.Engine.phase
settings.sampling.color = zivid.Settings.Sampling.Color.rgb
settings.sampling.pixel = zivid.Settings.Sampling.Pixel.blueSubsample2x2
settings.region_of_interest.box.enabled = True
settings.region_of_interest.box.point_o = [1000, 1000, 1000]
settings.region_of_interest.box.point_a = [1000, -1000, 1000]
settings.region_of_interest.box.point_b = [-1000, 1000, 1000]
settings.region_of_interest.box.extents = [-1000, 1000]
settings.region_of_interest.depth.enabled = True
settings.region_of_interest.depth.range = [200, 2000]
filters = settings.processing.filters
filters.smoothing.gaussian.enabled = True
filters.smoothing.gaussian.sigma = 1.5
filters.noise.removal.enabled = True
filters.noise.removal.threshold = 7.0
filters.noise.suppression.enabled = True
filters.noise.repair.enabled = True
filters.outlier.removal.enabled = True
filters.outlier.removal.threshold = 5.0
filters.reflection.removal.enabled = True
filters.reflection.removal.mode = zivid.Settings.Processing.Filters.Reflection.Removal.Mode.global_
filters.cluster.removal.enabled = True
filters.cluster.removal.max_neighbor_distance = 10
filters.cluster.removal.min_area = 100
filters.experimental.contrast_distortion.correction.enabled = True
filters.experimental.contrast_distortion.correction.strength = 0.4
filters.experimental.contrast_distortion.removal.enabled = False
filters.experimental.contrast_distortion.removal.threshold = 0.5
filters.hole.repair.enabled = True
filters.hole.repair.hole_size = 0.2
filters.hole.repair.strictness = 1
resampling = settings.processing.resampling
resampling.mode = zivid.Settings.Processing.Resampling.Mode.upsample2x2
color = settings.processing.color
color.balance.red = 1.0
color.balance.blue = 1.0
color.balance.green = 1.0
color.gamma = 1.0
settings.processing.color.experimental.mode = zivid.Settings.Processing.Color.Experimental.Mode.automatic
print(settings)

教程

查看以下教程,了解如何使用ROI API的示例。

有关性能信息,请查看 Region of Interest(感兴趣区域)

版本历史

SDK

变更

2.12.0

ROI 框过滤可减少捕获时间。

2.9.0

添加了ROI API。