リサンプリング

Zivid の重要な利点の 1 つは、2D から 3D へのマッピング機能が標準搭載されていることです。点群は 整理された配列 で返され、RGB 値はそれぞれの点と 1 対 1 で対応します。

However, the required resolution of the 3D data is not always the same as the required resolution of the 2D data. For example, one often requires higher resolution 2D than 3D. When you capture a separate 2D image and a 3D point cloud, the 2D image may have a higher resolution than the 3D point cloud. This can be done with the Settings::Sampling::Pixel settings, see ピクセル and ピクセル.

To maintain the 1-to-1 correspondence between the 2D and 3D data, the 3D data can be resampled to match the resolution of the 2D data. This can be done with Settings::Processing::Resampling.

リサンプリングとは、アップサンプリングとダウンサンプリングの両方を指します。これら 2 つについては、次の 2 つのセクションでそれぞれ詳しく説明します。

アップサンプリング

通常は、3D 解像度が 2D 解像度よりも低い場合に、2D 解像度に合わせるために使用されます。

以下の例は、2D データと 3D データの間の 1 対 1 の対応関係を維持しながら、異なる解像度で 2D データと 3D データを取得する方法を示しています。

2x2 サブサンプリング 3D とフル解像度 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

フル解像度 2D

3D 深度画像

3D 点群

2x2 にサブサンプリングしてから 2x2 にアップサンプリングした点群

(回転視点)

2D から 3D への対応関係をより明確に示すために、特定領域を拡大表示しました。
点群の比較

フル解像度

サブサンプリング 2x2

サブサンプリング 2x2 + アップサンプリング 2x2

注意

アップサンプリングによるアーティファクト

フル解像度

サブサンプリング 2x2

サブサンプリング 2x2 + アップサンプリング 2x2

ビンの底と市松模様の間にある点の列に注目してください。これは、3D データを 2D データの解像度に合わせるためにアップサンプリングした際に生じたアーティファクトです。

4x4 サブサンプリング 3D と 2x2 サブサンプリング 2D

以下は、2x2 のサブサンプリングを行った 2D 設定で撮影したものです。3D 設定は、4x4 のサブサンプリングを行った後、2D 画像の解像度に合わせるために 2x2 にアップサンプリングされています。

ソースへ移動

source

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() + "'");
}
ソースへ移動

source

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}'")

2x2 サブサンプリング 2D

3D 深度画像

3D 点群

ダウンサンプリング

通常、点群に対して使用され、ノイズの少ない低解像度の点群を取得します。詳細については ダウンサンプル を参照してください。

Zivid SDK を使用して点群をダウンサンプリングする方法は 2 つあります。

  1. Via the setting Settings::Processing::Resampling, which means it's controlled via the capture settings.

  2. Via the API 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 によるダウンサンプリング

The following is identical to the previous example, but the downsampling is invoked on the PointCloud instance returned by frame.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)

ダウンサンプリングはインプレースで行うことができ、その場合、現在の点群が変更されます。

ソースへ移動

source

pointCloud.downsample(Zivid::PointCloud::Downsampling::by2x2);
ソースへ移動

source

pointCloud.Downsample(Zivid.NET.PointCloud.Downsampling.By2x2);
ソースへ移動

source

point_cloud.downsample(zivid.PointCloud.Downsampling.by2x2)

ダウンサンプリングされた点群を新しい点群インスタンスとして取得することも可能で、その場合、既存の点群は変更されません。

ソースへ移動

source

auto downsampledPointCloud = pointCloud.downsampled(Zivid::PointCloud::Downsampling::by2x2);
ソースへ移動

source

var downsampledPointCloud = pointCloud.Downsampled(Zivid.NET.PointCloud.Downsampling.By2x2);
ソースへ移動

source

downsampled_point_cloud = point_cloud.downsampled(zivid.PointCloud.Downsampling.by2x2)

2D ダウンサンプリングの例

フル解像度

サブサンプリング

ダウンサンプリング