2D+3D捕获策略
如果您的应用同时需要2D和3D数据,那么您可以参考本教程。
我们解释并强调了不同的2D-3D捕获方法的优缺点,阐明了一些限制,并解释了它们如何影响循环时间。我们也谈到了使用外部光源和使用内部投影仪来拍摄2D图像的区别。
- 2D数据
RGB图像
- 3D数据
获取2D数据有两种不同的方式:
单独通过
camera.capture(Zivid::Settings2D).imageRGBA()
获取,请参阅 2D图像捕获流程 。作为3D捕获的一部分
camera.capture(Zivid::Settings).pointCloud.copyImageRGBA()
,请参阅 点云捕获过程 。
使用哪一种方式来获取2D数据取决于您的要求。
不同的场景会导致不同的权衡。我们首先根据您需要的数据对其进行细分。然后我们将讨论不同场景下捕获速度与图像质量的权衡。
关于外部光源
在我们讨论不同的策略之前,我们需要讨论外部光源。2D捕获的理想光源是强漫射光,因为这会限制 光晕效果 。使用内部投影仪作为光源时,光晕效果几乎是不可避免的。 以一定角度安装相机 可显着降低这种影响,但外部漫射光源仍然会提供更好的效果。外部光源会导致3D数据中出现额外噪声,因此最好在3D采集期间关闭外部光源。
除了减少光晕效应外,高照度的外部光源还可以消除由环境光变化引起的曝光变化。环境光变化的典型来源有:
日光变化(白天/黑夜、云等)
开门和关门
顶灯打开和关闭
这些曝光变化对3D和2D数据的影响不同。2D数据中曝光变化的影响取决于所使用的检测算法。如果在2D中执行分割,这些变化可能会,也可能不会影响分割性能。对于点云,您可能会发现由于噪声的变化而导致点云完整性的变化。
这就引出了一个问题:我们是否应该使用相机的投影仪来捕获2D图像?
查看 优化彩色图像 了解有关该主题的更多信息。
2D数据先于3D数据
如果您在2D中执行分割,然后确定您的抓取位姿,那么您需要在获取3D之前得到2D数据。获取2D数据的最快方法是使用单独的2D捕获。因此,如果您在使用3D数据之前就需要使用2D数据,那么您应该先执行单独的2D捕获。
小技巧
当您单独捕获 2D 时,您应该在 3D 捕获中禁用 RGB。这可以节省采集和处理时间。通过将 Sampling::Color
设置为 disabled
来禁用 3D 捕获中的 RGB。
警告
对于 Zivid 2+ 相机,可以使用 4x4 子采样模式(4x4 subsampling), Monochrome Capture(单色捕获) 。使用此功能时,2D 和 3D 捕获之间会有 35ms 的切换损失。仅当捕获紧随其后发生时才会发生这种情况。
以下代码示例展示了您可以如何:
捕获2D图像
使用2D数据和并行执行3D捕获
const auto frame2dAndCaptureTime = captureAndMeasure<Zivid::Frame2D>(camera, settings2D);
std::future<Duration> userThread =
std::async(std::launch::async, useFrame<Zivid::Frame2D>, std::ref(frame2dAndCaptureTime.frame));
const auto frameAndCaptureTime = captureAndMeasure<Zivid::Frame>(camera, settings);
const auto processTime = useFrame(frameAndCaptureTime.frame);
const auto processTime2D = userThread.get();
下面显示了实际的基准数字。您会在页面底部找到更详细的表格。
2D数据作为如何使用3D数据的一部分
在这种情况下,我们不必在使用3D数据之前获取2D数据。作为3D采集的一部分,您始终会获得2D数据。因此,我们只需要关心整体捕获速度和图像质量。
速度
为了获得最佳速度,我们仅依靠3D采集来获取良好的2D数据。2D数据无需额外采集或单独采集。
2D图像质量
为了获得最佳 2D 质量,建议使用单独的 2D 采集。
下表显示了不同配置的预期效果。文末有一个表格,它显示不同硬件上的实际测量结果。
- 快速
使用来自3D捕获中的2D数据。无需特殊的2D采集或设置。
- 最好
单独的2D捕获,紧接着执行3D捕获。
快速 |
最好 |
||
---|---|---|---|
3D [2] |
2D + 3D |
||
Zivid 2 |
2D |
N/A |
~25 毫秒 |
3D |
~295 ms |
~290 ms |
|
2D+3D |
~295 ms |
~300 ms |
|
Zivid 2+ |
2D |
N/A |
~55 ms |
3D |
~170 ms |
~220 ms |
|
2D+3D |
~170 ms |
~260 ms |
下面显示了实际的基准数字。您会在页面底部找到更详细的表格。
2D数据在使用3D数据之后
作为3D采集的一部分,您总是能够获得2D数据。下表展示了3D捕获时间的示例。
然而,针对 3D 质量进行的优化并不总是能够优化 2D 图像质量。因此,在 3D 捕获之后进行单独的 2D 捕获可能是个好主意。
下面显示了实际的基准数字。您会在页面底部找到更详细的表格。
相机分辨率和 1:1 映射
为了实现准确的 2D 分割和检测,高分辨率彩色图像非常有用。Zivid 2+ 配备了 5 MPx 成像传感器,而 Zivid 2 配备了 2.3 MPx 传感器。下表显示了不同相机在 2D 和 3D 捕获时的分辨率输出。
2D 捕获 |
Zivid 2 |
Zivid 2+ |
---|---|---|
全分辨率 |
1944 x 1200 |
2448 x 2048 |
2x2 子采样 |
972 x 600 |
1224 x 1024 |
4x4 子采样 |
不支持 |
612 x 512 |
3D 捕获 |
Zivid 2 |
Zivid 2+ |
---|---|---|
全分辨率 [1] |
1944 x 1200 |
2448 x 2048 |
2x2 子采样 [1] |
972 x 600 |
1224 x 1024 |
4x4 子采样 [1] |
不支持 |
612 x 512 |
从 3D 数据提取的 2D 信息将具有相同的分辨率。
2D 和 3D 捕获的输出分辨率是由 Sampling::Pixel
和 Processing::Resampling
设置的组合进行控制,详细内容请参阅 像素采样 和 Resampling(重采样) 。这意味着 2D 像素和 3D 点之间可能不再具有 1:1 的对应关系。因此,从 2D 图像中的分割掩模中提取 3D 数据变得更加具有挑战性。
如上所述,分割和检测通常需要高分辨率 2D 数据。例如,我们推荐的 Consumer Goods(消费品) Z2+ M130 Quality
预设使用的 Sampling::Pixel
设置为 blueSubsample2x2
。在这种情况下,我们应该:
对 3D 数据进行上采样,以恢复 1:1 对应关系,或
将二维索引映射到子采样三维数据中的索引。
重采样
为了匹配 2D 捕获的分辨率,只需应用取消子采样的上采样即可。这样操作仍保留了子采样捕获的速度优势。例如:
auto settings2D = Zivid::Settings2D{
Zivid::Settings2D::Acquisitions{ Zivid::Settings2D::Acquisition{} },
Zivid::Settings2D::Sampling::Pixel::all,
};
auto settings = Zivid::Settings{
Zivid::Settings::Engine::phase,
Zivid::Settings::Acquisitions{ Zivid::Settings::Acquisition{} },
Zivid::Settings::Sampling::Pixel::blueSubsample2x2,
Zivid::Settings::Sampling::Color::disabled,
Zivid::Settings::Processing::Resampling::Mode::upsample2x2,
};
settings_2d = zivid.Settings2D()
settings_2d.acquisitions.append(zivid.Settings2D.Acquisition())
settings_2d.sampling.pixel = zivid.Settings2D.Sampling.Pixel.all
settings = zivid.Settings()
settings.engine = "phase"
settings.acquisitions.append(zivid.Settings.Acquisition())
settings.sampling.pixel = zivid.Settings.Sampling.Pixel.blueSubsample2x2
settings.sampling.color = zivid.Settings.Sampling.Color.disabled
settings.processing.resampling.mode = zivid.Settings.Processing.Resampling.Mode.upsample2x2
更多相关的详细信息,请参阅 Resampling(重采样) 。
在不同分辨率之间映射像素索引
另一种方法是将 2D 索引映射到子采样 3D 数据中的索引。此选项稍微复杂一些,但可能更高效。点云可以保持子采样,因此消耗更少的内存和处理能力。
为了建立全分辨率 2D 图像与子采样点云之间的关联,需要一种特定的映射技术。此过程涉及从与拜耳网格中的蓝色或红色像素相对应的像素中提取 RGB 值。
Zivid::Experimental::Calibration::pixelMapping(camera, settings);
可用于获取执行此映射所需的参数。以下是使用此函数的示例。
const auto pixelMapping = Zivid::Experimental::Calibration::pixelMapping(camera, settings);
std::cout << "Pixel mapping: " << pixelMapping << std::endl;
cv::Mat mappedBGR(
fullResolutionBGR.rows / pixelMapping.rowStride(),
fullResolutionBGR.cols / pixelMapping.colStride(),
CV_8UC3);
std::cout << "Mapped width: " << mappedBGR.cols << ", height: " << mappedBGR.rows << std::endl;
for(size_t row = 0; row < static_cast<size_t>(fullResolutionBGR.rows - pixelMapping.rowOffset());
row += pixelMapping.rowStride())
{
for(size_t col = 0; col < static_cast<size_t>(fullResolutionBGR.cols - pixelMapping.colOffset());
col += pixelMapping.colStride())
{
mappedBGR.at<cv::Vec3b>(row / pixelMapping.rowStride(), col / pixelMapping.colStride()) =
fullResolutionBGR.at<cv::Vec3b>(row + pixelMapping.rowOffset(), col + pixelMapping.colOffset());
}
}
return mappedBGR;
pixel_mapping = calibration.pixel_mapping(camera, settings)
return rgba[
int(pixel_mapping.row_offset) :: pixel_mapping.row_stride,
int(pixel_mapping.col_offset) :: pixel_mapping.col_stride,
0:3,
]
有关映射的更多详细信息(例如 blueSubsample2x2
)
为了提取与蓝色像素相对应的所有 RGB 值,我们使用以下索引:
为了提取与红色像素相对应的所有 RGB 值,我们使用以下索引:
备注
如果您需要使用内参,并且 2D 和 3D 捕获具有不同的分辨率,请确保正确使用它们。有关更多信息,请参阅 相机内参 。
总结
- 我们的建议:
使用全分辨率进行 2D 捕获
使用子采样降低分辨率进行 3D 单色捕获
备注
仅当您在捕获和复制具有不同分辨率的 2D 和 3D 时想要实现 1 对 1 像素对应关系时,才需要在用户代码中进行子采样或降采样。
下表列出了不同的 2D+3D 捕获配置。显示了它们在速度和质量方面的相对表现。
捕获周期 |
速度 |
2D质量 |
|
---|---|---|---|
Zivid 2 |
Zivid 2+ |
||
较快 |
快速 |
最好 |
|
D ➞ 2D / 2D ➞ 3D |
快速 |
快速 |
最好 |
3D(启用 w/RGB) |
最快 |
最快 |
良好 |
下表列出了不同硬件上的实际测量结果。这里我们使用了Fast Consumer Goods的预设设置进行3D捕获。
- Zivid 2+
(
Z2+ M130 Fast
)- Zivid 2
(
Z2 M70 Fast
)
小技巧
如需在 PC 上测试不同的 2D-3D 策略,您可以运行 ZividBenchmark.cpp 示例,并使用从 YML 文件加载的设置。您可以在 示例 页面选择 C++ 选项查看说明。
版本历史
SDK |
变更 |
---|---|
2.12.0 |
对于 Zivid 2+,2D 捕获的采集时间最多可减少 50%,3D 捕获的采集时间最多可减少 5%。请注意,Zivid One+已达到其生命周期终点,不再提供支持。因此,与 2D+3D 捕获相关的大多数复杂性不再适用。 |
2.11.0 |
Zivid 2 和 Zivid 2+ 现在支持 3D ➞ 2D 和 3D ➞ 2D 的并发处理和采集,并且优化了捕获模式之间的切换。 |