2D + 3D Capture Strategy
애플리케이션에 2D 및 3D 데이터가 모두 필요한 경우 이 튜토리얼이 도움이 됩니다.
다양한 2D-3D 캡처 접근 방식의 장단점을 설명 및 강조하고, 몇 가지 제한 사항을 명확히 하고, 사이클 시간에 미치는 영향을 설명합니다. 2D용 외부 조명과 내부 프로젝터 사용의 차이점에 대해 다룹니다.
- 2D data
RGB image
- 3D data
2D 데이터를 얻는 방법에는 크게 두 가지가 있습니다.
camera.capture(Zivid::Settings2D).imageRGBA()
명령을 통해 2D 이미지를 얻습니다. 2D Image Capture Process 를 참조하십시오.3D 캡처
camera.capture(Zivid::Settings).pointCloud.copyImageRGBA()
를 통해 2D 이미지를 얻습니다. Point Cloud Capture Process process` 를 참조하십시오.
그러나 어느 것을 사용할지는 요구 사항에 따라 다릅니다.
다른 시나리오는 다른 장단점으로 이어질 것입니다. 먼저 필요한 데이터를 기준으로 분류합니다. 그런 다음 다양한 시나리오에 대한 속도와 품질의 장단점에 대해 논의합니다.
About external light
다양한 전략을 살펴보기 전에 외부 광원에 대해 먼저 설명해야 합니다. 2D 캡처에 이상적인 광원은 blooming effects 를 제한하기 때문에 강하고 확산되는 광원입니다. 내부 프로젝터를 광원으로 사용하면 블루밍 효과는 거의 피할 수 없습니다. Mounting the camera at an angle 하면 이 효과가 크게 줄어들지만 여전히 외부 확산 광원이 더 좋습니다. 외부 조명은 3D 데이터에 노이즈를 유발하므로 3D 캡처 중에는 외부 조명을 끄는 것이 이상적입니다.
블루밍 효과의 감소 외에도 강한 외부 조명은 주변 조명의 변화로 인한 노출 변화를 완화할 수 있습니다. 주변광 변화의 일반적인 예시:
일광의 변화(낮/밤, 구름 등)
도어 개폐
천장 조명의 켜짐 및 꺼짐
노출의 이러한 변화는 3D 및 2D 데이터에 다르게 영향을 미칩니다. 2D 데이터에서 노출 변화의 영향은 사용된 감지 알고리즘에 따라 다릅니다. 분할이 2D에서 수행되는 경우 이러한 변형은 분할 성능에 영향을 미칠 수도 있고 그렇지 않을 수도 있습니다. 포인트 클라우드의 경우 노이즈 변동으로 인해 포인트 클라우드 완성도에 변동이 있을 수 있습니다.
이것은 다음과 같은 질문으로 이어집니다. 2D에 프로젝터를 사용해야 합니까?
해당 주제에 대한 자세한 내용은 Optimizing Color Image 를 확인하십시오.
2D data before 3D data
예를 들어 2D에서 분할을 수행한 다음 나중에 피킹 포즈를 결정하는 경우 3D보다 빠른 2D가 필요합니다. 2D 데이터를 얻는 가장 빠른 방법은 별도의 2D 캡처를 이용하는 것입니다. 따라서 3D 데이터보다 먼저 2D 데이터가 필요한 경우에는 별도의 2D 캡처를 수행해야 합니다.
팁
When you capture 2D separately you should disable RGB in the 3D capture.
This saves both on acquisition and processing time.
Disable RGB in 3D capture by setting Sampling::Color
to disabled
.
경고
On Zivid 2+ we have a 4x4 subsampling mode, Monochrome Capture. When this is used there is a 35ms switching penalty between 2D and 3D capture. This happens only if the captures happen right after each other.
다음 코드 샘플은 아래의 내용을 수행하는 방법을 보여줍니다.
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();
The following shows actual benchmark numbers. You will find a more extensive table at the bottom of the page.
3D 데이터를 사용해서 얻은 2D 데이터
이 경우 3D 데이터보다 먼저 2D 데이터에 액세스할 필요가 없습니다. 항상 3D 획득의 일부로 2D 데이터를 얻습니다. 따라서 우리는 전반적인 속도와 품질에만 신경을 쓰면 됩니다.
Speed
최적의 속도를 위해 우리는 단순히 3D 획득에 의존하여 우수한 2D 데이터를 제공합니다. 2D 데이터에 대한 추가 획득 또는 별도의 캡처가 없습니다.
2D Quality
For optimal 2D quality, it is recommended to use a separate acquisition for 2D.
Following is a table that shows what you can expect from the different configurations. At the end you will find a table showing actual measurements on different hardware.
- Fast
3D 캡처의 2D 데이터를 사용합니다. 2D에 대한 특별한 획득이나 설정이 없습니다.
- Best
2D 캡처와 3D 캡처를 따로 진행합니다.
Fast |
Best |
||
---|---|---|---|
3D [2] |
2D + 3D |
||
Zivid 2 |
2D |
N/A |
~25 ms |
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 |
The following shows actual benchmark numbers. You will find a more extensive table at the bottom of the page.
2D data after I have used the 3D data
항상 3D 획득의 일부로 2D 데이터를 얻습니다. 아래 표는 3D 캡처 시간 예를 보여줍니다.
However, optimizing for 3D quality does not always optimize for 2D quality. Thus, it might be a good idea to have a separate 2D capture after the 3D capture.
The following shows actual benchmark numbers. You will find a more extensive table at the bottom of the page.
Camera resolution and 1-to-1 mapping
For accurate 2D segmentation and detection, it is beneficial with a high-resolution color image. Zivid 2+ has a 5 MPx imaging sensor, while Zivid 2 has a 2.3 MPx sensors. The following table shows the resolution outputs of the different cameras for both 2D and 3D captures.
2D capture |
Zivid 2 |
Zivid 2+ |
---|---|---|
Full resolution |
1944 x 1200 |
2448 x 2048 |
2x2 subsampled |
972 x 600 |
1224 x 1024 |
4x4 subsampled |
Not available |
612 x 512 |
3D capture |
Zivid 2 |
Zivid 2+ |
---|---|---|
Full resolution [1] |
1944 x 1200 |
2448 x 2048 |
2x2 subsampled [1] |
972 x 600 |
1224 x 1024 |
4x4 subsampled [1] |
Not available |
612 x 512 |
2D information extracted from the 3D data will have same resolution.
Output resolution of both 2D and 3D captures in controlled via the combination of the Sampling::Pixel
and the Processing::Resampling
settings, see pixel sampling and Resampling.
This means that it is possible to no longer have a 1-to-1 correlation between a 2D pixel and a 3D point.
Consequently, it is more challenging to extract the 3D data from a segmented mask in the 2D image.
As mentioned, it is common to require high-resolution 2D data for segmentation and detection.
For example, our recommended preset for Consumer Goods Z2+ M130 Quality
preset uses Sampling::Pixel
set to blueSubsample2x2
.
In this case we should either:
Upsample the 3D data to restore 1-to-1 correspondence, or
Map 2D indices to the indices in the subsampled 3D data.
Resampling
In order to match the resolution of the 2D capture, simply apply an upsampling which undoes the subsampling. This retains the speed advantages of the subsampled capture. For example:
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
For more details see Resampling.
Mapping pixel indices between different resolutions
The other option is to map the 2D indices to the indices in the subsampled 3D data. This option is a bit more complicated, but it is potentially more efficient. The point cloud can remain subsampled, and thus consume less memory and processing power.
To establish a correlation between the full-resolution 2D image and the subsampled point cloud, a specific mapping technique is required. This process involves extracting RGB values from the pixels that correspond to the Blue or Red pixels from the Bayer grid.
Zivid::Experimental::Calibration::pixelMapping(camera, settings);
can be used to get parameters required to perform this mapping.
Following is an example which uses this function.
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,
]
For more details about mapping (example for blueSubsample2x2
)
In order to extract all the RGB values which correspond to the blue pixels we use the indices:
In order to extract all the RGB values which correspond to the red pixels we use the indices:
참고
If you use intrinsics and 2D and 3D capture have different resolutions, ensure you use them correctly. See Camera Intrinsics for more information.
Summary
- Our recommendation:
2D capture with full resolution
3D monochrome capture with subsampled resolution
참고
Subsampling or downsampling in user code is only necessary if you want to have 1-to-1 pixel correspondence when you capture and copy 2D and 3D with different resolutions.
The following tables list the different 2D+3D capture configurations. It shows how they are expected to perform relative to each other with respect to speed and quality.
Capture Cycle |
Speed |
2D-Quality |
|
---|---|---|---|
Zivid 2 |
Zivid 2+ |
||
Faster |
Fast |
Best |
|
3D ➞ 2D / 2D ➞ 3D |
Fast |
Fast |
Best |
3D (w/RGB enabled) |
Fastest |
Fastest |
Good |
Following is a table showing actual measurements on different hardware. For the 3D capture we use the Fast Consumer Goods settings.
- Zivid 2+
- Zivid 2
팁
PC에서 다양한 2D-3D 전략을 테스트하려면 YML 파일에서 로드된 설정으로 ZividBenchmark.cpp 샘플을 실행할 수 있습니다. Samples 로 이동하고 튜토리얼을 보려면 C++를 선택합니다.
Version History
SDK |
Changes |
---|---|
2.12.0 |
Acquisition time is reduced by up to 50% for 2D captures and up to 5% for 3D captures for Zivid 2+. Zivid One+ has reached its End-of-Life and is no longer supported; thus, most of the complexities related to 2D+3D captures are no longer applicable. |
2.11.0 |
Zivid 2 and Zivid 2+ now support concurrent processing and acquisition for 3D ➞ 2D and 3D ➞ 2D, and switching between capture modes have been optimized. |