Resampling
Zivid의 주요 장점 중 하나는 2D에서 3D로의 매핑이 가능하다는 것입니다. 포인트 클라우드는 organized array 형태로 반환되며, RGB 값은 해당 포인트와 일대일 대응됩니다.
그러나 3D 데이터에 필요한 해상도가 2D 데이터에 필요한 해상도와 항상 동일한 것은 아닙니다. 예를 들어, 3D보다 2D 데이터의 해상도가 더 높은 경우가 많습니다. 별도의 2D 이미지와 3D 포인트 클라우드를 캡처하는 경우, 2D 이미지의 해상도가 3D 포인트 클라우드보다 높을 수 있습니다. 이는 Sampling::Pixel 설정을 사용하여 수행할 수 있습니다. Pixel 및 Pixel 을 참조하세요.
2D 데이터와 3D 데이터 간의 일대일 대응을 유지하기 위해 3D 데이터를 2D 데이터의 해상도에 맞춰 리샘플링할 수 있습니다. 이 작업은 Settings::Processing::Resampling 을 사용하여 수행할 수 있습니다.
리샘플링은 업샘플링과 다운샘플링을 모두 지칭할 수 있습니다. 두 가지 모두 다음 두 섹션에서 별도로 논의됩니다.
Upsampling
일반적으로 3D 해상도가 2D 해상도보다 낮은 경우 2D 해상도와 일치시키는 데 사용됩니다.
Examples
다음 예제에서는 2D 및 3D 데이터 간의 1:1 대응을 유지하면서 서로 다른 해상도로 2D 및 3D 데이터를 캡처하는 방법을 보여줍니다.
2x2 subsampled 3D and full resolution 2D
다음은 전체 해상도 2D 설정과 서브샘플링된 3D 설정으로 촬영되었습니다. 3D 데이터는 2D 이미지의 해상도에 맞춰 추가로 업샘플링됩니다.
auto settings2D = Zivid::Settings2D{
Zivid::Settings2D::Acquisitions{ Zivid::Settings2D::Acquisition{} },
Zivid::Settings2D::Sampling::Pixel::all,
};
auto settings = Zivid::Settings{
Zivid::Settings::Engine::stripe,
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 = "stripe"
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
4x4 subsampled 3D and 2x2 subsampled 2D
다음은 2x2 서브샘플링된 2D 설정으로 캡처한 이미지입니다. 3D 설정은 4x4 서브샘플링된 후, 2D 이미지의 해상도에 맞춰 2x2 업샘플링됩니다.
auto settings = Zivid::Settings{ Zivid::Settings::Acquisitions{ Zivid::Settings::Acquisition{} },
Zivid::Settings::Color{ Zivid::Settings2D{
Zivid::Settings2D::Acquisitions{ Zivid::Settings2D::Acquisition{} } } } };
auto model = camera.info().model();
switch(model.value())
{
case Zivid::CameraInfo::Model::ValueType::zividTwo:
case Zivid::CameraInfo::Model::ValueType::zividTwoL100:
{
settings.set(Zivid::Settings::Sampling::Pixel::blueSubsample2x2);
settings.set(Zivid::Settings::Processing::Resampling::Mode::upsample2x2);
settings.color().value().set(Zivid::Settings2D::Sampling::Pixel::all);
break;
}
case Zivid::CameraInfo::Model::ValueType::zivid2PlusM130:
case Zivid::CameraInfo::Model::ValueType::zivid2PlusM60:
case Zivid::CameraInfo::Model::ValueType::zivid2PlusL110:
{
settings.set(Zivid::Settings::Sampling::Pixel::blueSubsample4x4);
settings.set(Zivid::Settings::Processing::Resampling::Mode::upsample2x2);
settings.color().value().set(Zivid::Settings2D::Sampling::Pixel::blueSubsample2x2);
break;
}
case Zivid::CameraInfo::Model::ValueType::zivid2PlusMR130:
case Zivid::CameraInfo::Model::ValueType::zivid2PlusMR60:
case Zivid::CameraInfo::Model::ValueType::zivid2PlusLR110:
case Zivid::CameraInfo::Model::ValueType::zivid3XL250:
{
settings.set(Zivid::Settings::Sampling::Pixel::by4x4);
settings.set(Zivid::Settings::Processing::Resampling::Mode::upsample2x2);
settings.color().value().set(Zivid::Settings2D::Sampling::Pixel::by2x2);
break;
}
case Zivid::CameraInfo::Model::ValueType::zividOnePlusSmall:
case Zivid::CameraInfo::Model::ValueType::zividOnePlusMedium:
case Zivid::CameraInfo::Model::ValueType::zividOnePlusLarge:
{
throw std::runtime_error("Unsupported camera model '" + model.toString() + "'");
}
default: throw std::runtime_error("Unhandled enum value '" + model.toString() + "'");
}
settings = zivid.Settings(
acquisitions=[zivid.Settings.Acquisition()],
color=zivid.Settings2D(acquisitions=[zivid.Settings2D.Acquisition()]),
)
model = camera.info.model
if model in {zivid.CameraInfo.Model.zividTwo, zivid.CameraInfo.Model.zividTwoL100}:
settings.sampling.pixel = zivid.Settings.Sampling.Pixel.blueSubsample2x2
settings.processing.resampling.mode = zivid.Settings.Processing.Resampling.Mode.upsample2x2
settings.color.sampling.pixel = zivid.Settings2D.Sampling.Pixel.all
elif model in {
zivid.CameraInfo.Model.zivid2PlusM130,
zivid.CameraInfo.Model.zivid2PlusM60,
zivid.CameraInfo.Model.zivid2PlusL110,
}:
settings.sampling.pixel = zivid.Settings.Sampling.Pixel.blueSubsample4x4
settings.processing.resampling.mode = zivid.Settings.Processing.Resampling.Mode.upsample2x2
settings.color.sampling.pixel = zivid.Settings2D.Sampling.Pixel.blueSubsample2x2
elif model in {
zivid.CameraInfo.Model.zivid2PlusMR130,
zivid.CameraInfo.Model.zivid2PlusMR60,
zivid.CameraInfo.Model.zivid2PlusLR110,
zivid.CameraInfo.Model.zivid3XL250,
}:
settings.sampling.pixel = zivid.Settings.Sampling.Pixel.by4x4
settings.processing.resampling.mode = zivid.Settings.Processing.Resampling.Mode.upsample2x2
settings.color.sampling.pixel = zivid.Settings2D.Sampling.Pixel.by2x2
else:
raise ValueError(f"Unsupported camera model '{model}'")
Downsampling
일반적으로 포인트 클라우드에서 노이즈가 적은 저해상도 포인트 클라우드를 얻는 데 사용됩니다. 자세한 내용은 Downsample 을 참조하세요.
Zivid SDK를 사용하여 포인트 클라우드를 다운샘플링하는 방법에는 두 가지가 있습니다.
캡처 설정인
Settings::Processing::Resampling설정을 통해 제어됩니다.API
Zivid::PointCloud::downsample를 통해 제어됩니다.
Zivid::Settings::Processing::Resampling 을 통해 다운샘플링합니다.
설정을 통해 다운샘플링이 호출되면 frame.pointCloud() 에서 반환된 포인트 클라우드는 이미 다운샘플링됩니다.
auto settings = Zivid::Settings{
Zivid::Settings::Engine::stripe,
Zivid::Settings::Acquisitions{ Zivid::Settings::Acquisition{} },
Zivid::Settings::Sampling::Pixel::all,
Zivid::Settings::Processing::Resampling::Mode::downsample2x2,
};
const auto cameraModel = camera.info().model();
if(cameraModel == Zivid::CameraInfo::Model::zivid2PlusM130
|| cameraModel == Zivid::CameraInfo::Model::zivid2PlusM60
|| cameraModel == Zivid::CameraInfo::Model::zivid2PlusL110)
{
// For 2+, we must lower Brightness from the default 2.5 to 2.2, when using `all` mode.
// This code can be removed by changing the Config.yml option 'Camera/Power/Limit'.
for(auto &a : settings.acquisitions())
{
a.set(Zivid::Settings::Acquisition::Brightness{ 2.2 });
}
}
std::cout << "Capturing frame" << std::endl;
const auto frame = camera.capture(settings);
const auto pointCloud = frame.pointCloud();
std::cout << "Getting BGRA image" << std::endl;
const auto image = pointCloud.copyColorsRGBA_SRGB();
const cv::Mat bgra(
image.height(),
image.width(),
CV_8UC4, // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
const_cast<void *>(static_cast<const void *>(image.data())));
std::cout << "Visualizing point cloud" << std::endl;
displayPointCloud(pointCloud, bgra);
settings = zivid.Settings()
settings.engine = "stripe"
settings.acquisitions.append(zivid.Settings.Acquisition())
settings.sampling.pixel = zivid.Settings.Sampling.Pixel.all
settings.processing.resampling.mode = zivid.Settings.Processing.Resampling.Mode.downsample2x2
model = camera.info.model
if model in (
zivid.CameraInfo.Model.zivid2PlusM130,
zivid.CameraInfo.Model.zivid2PlusM60,
zivid.CameraInfo.Model.zivid2PlusL110,
):
# For 2+, we must lower Brightness from the default 2.5 to 2.2, when using `all` mode.
# This code can be removed by changing the Config.yml option 'Camera/Power/Limit'.
for acquisition in settings.acquisitions:
acquisition.brightness = 2.2
print("Capturing frame")
with camera.capture(settings) as frame:
point_cloud = frame.point_cloud()
xyz = point_cloud.copy_data("xyz")
rgba = point_cloud.copy_data("rgba_srgb")
print("Visualizing point cloud")
display_pointcloud(xyz, rgba)
Zivid::PointCloud::downsample 을 통해 다운샘플링합니다.
다음은 이전 예제와 동일하지만, 다운샘플링은 frame.pointCloud() 대신 Zivid::PointCloud 인스턴스에서 호출됩니다.
auto settings = Zivid::Settings{
Zivid::Settings::Engine::stripe,
Zivid::Settings::Acquisitions{ Zivid::Settings::Acquisition{} },
Zivid::Settings::Sampling::Pixel{ Zivid::Settings::Sampling::Pixel::all },
};
const auto cameraModel = camera.info().model();
if(cameraModel == Zivid::CameraInfo::Model::zivid2PlusM130
|| cameraModel == Zivid::CameraInfo::Model::zivid2PlusM60
|| cameraModel == Zivid::CameraInfo::Model::zivid2PlusL110)
{
// For 2+, we must lower Brightness from the default 2.5 to 2.2, when using `all` mode.
// This code can be removed by changing the Config.yml option 'Camera/Power/Limit'.
for(auto &a : settings.acquisitions())
{
a.set(Zivid::Settings::Acquisition::Brightness{ 2.2 });
}
}
std::cout << "Capturing frame" << std::endl;
const auto frame = camera.capture(settings);
auto pointCloud = frame.pointCloud();
pointCloud.downsample(Zivid::PointCloud::Downsampling::by2x2);
std::cout << "Getting BGRA image" << std::endl;
const auto image = pointCloud.copyColorsRGBA_SRGB();
const cv::Mat bgra(
image.height(),
image.width(),
CV_8UC4, // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
const_cast<void *>(static_cast<const void *>(image.data())));
std::cout << "Visualizing point cloud" << std::endl;
displayPointCloud(pointCloud, bgra);
settings = zivid.Settings()
settings.engine = "stripe"
settings.acquisitions.append(zivid.Settings.Acquisition())
settings.sampling.pixel = zivid.Settings.Sampling.Pixel.all
model = camera.info.model
if model in (
zivid.CameraInfo.Model.zivid2PlusM130,
zivid.CameraInfo.Model.zivid2PlusM60,
zivid.CameraInfo.Model.zivid2PlusL110,
):
# For 2+, we must lower Brightness from the default 2.5 to 2.2, when using `all` mode.
# This code can be removed by changing the Config.yml option 'Camera/Power/Limit'.
for acquisition in settings.acquisitions:
acquisition.brightness = 2.2
print("Capturing frame")
with camera.capture(settings) as frame:
point_cloud = frame.point_cloud()
point_cloud.downsample(zivid.PointCloud.Downsampling.by2x2)
xyz = point_cloud.copy_data("xyz")
rgba = point_cloud.copy_data("rgba_srgb")
print("Visualizing point cloud")
display_pointcloud(xyz, rgba)
다운샘플링은 현재 포인트 클라우드를 수정하는 방식으로 그 자리에서 수행할 수 있습니다.
기존 포인트 클라우드를 변경하지 않고 다운샘플링된 포인트 클라우드를 새로운 포인트 클라우드 인스턴스로 가져오는 것도 가능합니다.