Common Vision Blox 15.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Friends Modules Pages
Creating a Calibrated Point Cloud with CVB

Example Programs

Example programs for generating point clouds using a calibration file are available in C++ and Python. You can find them in your CVB setup under %cvb%Tutorial/Image Manager or in the online documentation, as listed in the table below:

Link to Example Location in your CVB Setup
C++ CppPointCloudCreateCalibrated %cvb%Tutorial/Image Manager/Cvb++/CppPointCloudCreateCalibrated
Python CreateAndAccessCalibratedPointCloud %cvb%Tutorial/Image Manager/CVBpy/CreateAndAccessCalibratedPointCloud

Prerequisites

The creation of calibrated point clouds is implemented in the CVCore3D.dll. To execute the code snippets provided in this documentation, following DLLs are additionally required:

To utilize this functionality, the following namespaces and include files are required:

#include "cvb/point_cloud_factory.hpp"
#include "cvb/point_cloud.hpp"
#include "cvb/calibrator_3d.hpp"
using namespace Cvb;

import cvb

Creating a Calibrated Point Cloud

The following sections outline the process for applying a specific calibration. For details on managing background values, refer to section Handling Background Values.

Static Factors for ZMaps

Many area-based 3D sensors provide calibrated point clouds or height maps, commonly referred to as ZMaps, along with resolution values for the x, y, and z dimensions.

To generate a metrically calibrated point cloud from these ZMaps, the resolution factors must be applied. CVB offers functionality to handle this process. The following code example demonstrates how to load a ZMap and apply the provided resolution factors, resulting in an organized (dense) point cloud:

auto zmap = Cvb::Image::Load(CVB_LIT("zmap.tif"));
auto calibrator = Cvb::FactorsCalibrator3D::Create(0.097,0.09799,0.0014);
auto cloud = Cvb::PointCloudFactory::Create<Cvb::DensePointCloud>(zmap->Plane(0), *calibrator, Cvb::PointCloudFlags::Float | Cvb::PointCloudFlags::XYZConfidence);
static FactorsCalibrator3DPtr Create(double x, double y, double z)
static std::unique_ptr< Image > Load(const String &fileName)
static PointCloudPtr Create(const ImagePlane &rangeMap, const Calibrator3D &calibrator, PointCloudFlags flags)

var zmap = Image.FromFile("zmap.tif");
var calibrator = new FactorsCalibrator3D(0.097, 0.09799, 0.0014);
var cloud = calibrator.CreatePointCloud(zmap, PointCloudFlags.Float | PointCloudFlags.XYZConfidence);
__int3264 Image

zmap = cvb.Image.load('zmap.tif')
calibrator = cvb.FactorsCalibrator3D(0.097, 0.09799, 0.0014)
cloud = cvb.PointCloudFactory.create(zmap.planes[0], calibrator, cvb.PointCloudFlags.Float | cvb.PointCloudFlags.XYZConfidence)
cvb.Image load(str file_name)
Union[cvb.PointCloud, cvb.DensePointCloud, cvb.SparsePointCloud] create(cvb.ImagePlane range_map, cvb.Calibrator3D calibrator, int flags, Union[Type[cvb.PointCloud|cvb.DensePointCloud|cvb.SparsePointCloud]] point_cloud_type=DensePointCloud)

This code example demonstrates how to generate not only the x, y, and z planes but also a confidence plane, defined through the point cloud flags. For further information refer to section Handling Background Values.

Intrinsic and Extrinsic Calibration for Laser Triangulation Systems

Laser triangulation setups require a more advanced calibration process (see also the section on Calibration Theory). The calibration parameters are typically stored in JSON or XML files. The following sections provide detailed instructions on how to apply these calibrations.

Attention
When using cameras from Automation Technology (AT), be careful when modifying sensor settings. If the sensor settings differ between acquiring the calibration target and capturing the actual objects (where the calibration is applied), you must specify the updated settings. For detailed guidance, refer to the section Special Case: Modifying AT Sensor Settings.

Intrinsic Calibration

For the intrinsic calibration, CVB supports the following types of calibration files:

  • ZigZag calibration files (JSON): The ZigZag calibration is a highly precise intrinsic calibration, provided by Stemmer Imaging.
  • Factory calibration files (XML): Certain camera manufacturers, such as Automation Technology, supply compact sensors where an XML file containing an intrinsic factory calibration can be downloaded.

After loading the range map and the calibration file, the point cloud can be created as the following code snippet demonstrates:

auto rangemap = Cvb::Image::Load(CVB_LIT("rangemap.tif"));
auto calibrator = Cvb::Calibrator3D::Load<Cvb::LaserPlaneCalibrator3D>(CVB_LIT("IntrinsicCalibration.json"));
auto cloud = Cvb::PointCloudFactory::Create<Cvb::DensePointCloud>(rangemap->Plane(0), *calibrator, Cvb::PointCloudFlags::Float | Cvb::PointCloudFlags::XYZConfidence);
static std::shared_ptr< T > Load(const String &fileName)

var rangemap = Image.FromFile("rangemap.tif");
var calibrator = Calibrator3D.FromFile<LaserPlaneCalibrator3D>("IntrinsicCalibration.json");
var cloud = calibrator.CreatePointCloud(rangemap, PointCloudFlags.Float | PointCloudFlags.XYZConfidence);
PointCloud CreatePointCloud(Image rangeMap)
static Calibrator3D FromFile(string fileName)

rangemap = cvb.Image("rangemap.tif")
calibrator = cvb.Calibrator3D.load("IntrinsicCalibration.json")
cloud = cvb.PointCloudFactory.create_dense(rangemap.planes[0], calibrator, cvb.PointCloudFlags.Float | cvb.PointCloudFlags.XYZConfidence)
Union[cvb.Calibrator3DAT, cvb.LaserPlaneHomographyCalibrator3D, cvb.LaserPlaneZigZagCalibrator3D, cvb.FactorsCalibrator3D, cvb.MatrixCalibrator3D, cvb.PinholeCameraCalibrator3D] load(str file_name)
cvb.DensePointCloud create_dense(cvb.ImagePlane range_map, cvb.Calibrator3D calibrator, int flags)

When applying only an intrinsic calibration, the resulting point cloud is always organized (dense). For C++ it is recommended to use the template argument DensePointCloud to avoid the need for casting when accessing the specific functionalities of a DensePointCloud.

When creating an intrinsically calibrated (dense) point cloud, it is recommended to include an additional confidence plane, as explained in section Handling Background Values.

Extrinsic Calibration

Extrinsic Calibration for Range Maps

The CVB AQS12 calibration generates a JSON file containing both intrinsic and extrinsic calibration data. The following code snippet demonstrates how to apply this calibration to a range map to generate a calibrated point cloud:

auto rangemap = Cvb::Image::Load(CVB_LIT("rangemap.tif"));
auto calibrator = Cvb::Calibrator3D::Load<Cvb::LaserPlaneCalibrator3D>(CVB_LIT("ExtrinsicCalibration.json"));
auto cloud = Cvb::PointCloudFactory::Create(image->Plane(0), *calibrator, Cvb::PointCloudFlags::Float);

var rangemap = Image.FromFile("rangemap.tif");
var calibrator = Calibrator3D.FromFile<LaserPlaneCalibrator3D>("ExtrinsicCalibration.json");
var cloud = calibrator.CreatePointCloud(rangemap, PointCloudFlags.Float);

rangemap = cvb.Image("rangemap.tif")
calibrator = cvb.Calibrator3D.load("ExtrinsicCalibration.json")
cloud = cvb.PointCloudFactory.create(rangemap.planes[0], calibrator, cvb.PointCloudFlags.Float)

When applying an extrinsic calibration, the resulting point cloud is un-organized (sparse). Background values are excluded as explained in section Handling Background Values.

Extrinsic Calibration for Point Clouds

If you have already received a point cloud from your camera and wish to transform it into a superordinate coordinate system (typically through a rigid-body transformation), you can achieve this using the following code:

auto cloudFromCamera = ...
Cvb::AffineMatrix3D transformation = ...
auto cloud = cloudFromCamera->Transform(transformation);

var cloudFromCamera = ...
var transformation = ...
var cloud = cloudFromCamera.Transform(transformation);

cloudFromCamera = ...
transformation = ...
cloud = cloudFromCamera.transform(transformation)

Note, that when transforming a point cloud with the Transform function, the resulting point cloud is always un-organized (sparse).

Handling Background Values

Empty background areas within the range map should be excluded from the calibration process. To achieve this, users have to define the background value using the RangeMapIgnoreValue parameter. By default, the RangeMapIgnoreValue is set to zero.

When applying only an intrinsic calibration, it is recommended to create an organized (dense) point cloud with a confidence plane, which can be specified via the point cloud flags (as shown in the code snippet below). Background values are represented as non-confident points with values (x, y, z, confidence) = (0, 0, 0, 0). Valid points contain valid x, y, and z coordinates along with a confidence value of 1.

The following code snippet illustrates how to set the RangeMapIgnoreValue and define the point cloud flags:

// Set background values to calibrator.
auto calibrator = ...
calibrator.SetRangeMapIgnoreValue(0);
// Point cloud flags with confidence plane.
auto flags = Cvb::PointCloudFlags::Float | Cvb::PointCloudFlags::XYZConfidence;

// Set background values to calibrator.
var calibrator = ...
calibrator.RangeMapIgnoreValue = 0;
// Point cloud flags with confidence plane.
var flags = PointCloudFlags.Float | PointCloudFlags.XYZConfidence;

# Set background values to calibrator.
calibrator = ...
calibrator.range_map_ignore_value = 0
# Point cloud flags with confidence plane.
flags = cvb.PointCloudFlags.Float | cvb.PointCloudFlags.XYZConfidence

When applying an extrinsic calibration the resulting point cloud is un-organized (sparse). Thus a confidence plane should not be specified. All background values are excluded in this case.

Special Case: Modifying AT Sensor Settings

It is essential to note that the calibration parameters stored in the calibrator always correspond to the entire sensor (without any pixel coordinate mirroring). If the camera's sensor settings specify a region of interest (ROI) or involve mirrored pixel coordinates, the range map values will be transformed to sensor coordinates before the calibration parameters are applied. Users of AT cameras, in particular, should exercise caution when configuring camera settings. In the AT or ZigZag calibration file the default sensor settings are stored.

The default sensor settings are stored in the respective calibration file and refer to:

  • the sensor settings used acquiring the target for the ZigZag calibration (JSON file).
  • the sensor settings used when the calibration file (XML) was loaded from the AT compact sensor.

If you acquire a range map using sensor settings that differ from the defaults stored in the calibrator, you must not use the standard function applying the calibration (see for C++, .NET, and Python)! Instead, use the advanced creation function, which allows you to specify the current sensor settings (see C++, .NET, and Python for details).

You can check the default sensor settings stored in the calibrator in C++, .NET, and Python. These settings, along with their purposes, are described below:

  • Range Scale: Scales the range map values. It can be calculated from , where NumSubpixel is the number of sub-pixels.
  • Pixel Position: Indicates whether the pixel position on the sensor in the Y direction is absolute or relative. For relative positions, sensor coordinates are calculated relative to OffsetTop (top of ROI). For absolute positions, OffsetTop is set to zero in the calibration file.
  • Pixels Mirrored: Specifies whether the x and/or y sensor coordinates of the laser profile are mirrored.
  • ROI: Defines the region of interest on the sensor.
  • Resolution Reduction: Horizontal and vertical resolution reduction factor resulting from sensor binning.
  • Encoder Step: Factor used for values in the movement direction.

The table below lists the sensor settings along with their notations in the camera properties, the AT calibration file, and the ZigZag calibration file. Note that CVB currently supports sensor settings for AT cameras only.

Sensor Setting AT Camera Calibration File
C5 C6 AT (XML) ZigZag (JSON)
Range Scale has to be calculated from Cust::NumSubPixel Std::Scan3dCoordinateScale intrinsic.rangeScale 3rd value of intrinsic.factors
Pixel Position Cust::AbsOffsetPos Cust::Scan3dCoordinateMode OffsetTop = 0 intrinsic.sensorsettings.mode.absolutepositiony
Pixels Mirrored Std::ReverseX not available Width is negative intrinsic.sensorsettings.mode.reverse.x
Std::ReverseY Cust::RegionReverseY Height is negative intrinsic.sensorsettings.mode.reverse.y
OffsetLeft (ROI) Std::OffsetX Std::OffsetX intrinsic.sensorRoi intrinsic.sensorsettings.sensorroi
OffsetTop (ROI) Cust::AoiOffsetY Std::OffsetY
Width (ROI) Std::Width Std::SensorWidth
Height Cust::AoiHeight Std::SensorHeight
Reduction Resolution not available yet intrinsic.rrH
intrinsic.rrV
not supported yet
Encoder Step not available extrinsic.Sy 2nd value of intrinsic.factors

Post-Calibration Processing of Point Clouds

If further point cloud processing is needed, please refer to section 3D Point Cloud Processing.

In many cases a gapless rectified point cloud are required to enable 2D image processing. For further details, refer to the sections Rectification of Point Clouds and Filling Gaps in Range Maps. Please, be aware, the coordinate system of your calibrated point cloud is defined by the given reference coordinates. Since image coordinates follow a left-handed system, the point cloud to be rectified should also conform to a left-handed trihedron. For more information, see the section Recommendation for Point Cloud Rectification).