SAL3D Objects and Acquisition Overview
- Frame - Image object
- Profile - Laser triangulation profile
- RangeMap - Accumulation of laser triangulation profiles
- COP - Organized Cloud of Points
- ZMap - Projection of a COP on the XY plane
A Frame represents an image taken by a camera. In this kind of 3D acquisition, the images correspond to the projection of the laser on the object to be digitized. A common camera - laser setup configuration can be seen in the next figure.
Example of a projection of the laser on an object.
Example of a frame captured by the camera.
See how the laser stripe shape varies related with the object's height can be seen in the right figure
A Profile contains the information of the laser position within a Frame (see Peak Detector Tool for more description about the peak detection).
a) A frame with the detected profile overlay;
b) Profile coordinates as obtained from the frame where coordinate g represents the position of the peak within the frame
A RangeMap is defined as the composition of a surface consisting of several consecutive Profiles, acquired by equally spaced displacements of the part under the laser. Equivalently, the part could be static while the camera - laser set moves.
The following figures describe the process of building a RangeMap. For each Frame from the camera, a Profile contains the pixel coordinates of each laser stripe. The accumulation of different Profiles (moving the scanned part under the laser) results in a RangeMap, containing 3D information of scanned part's surface.
a) Coordinates in the peak position in the current frame
b) Current profile in (u, v, g) coordinates
c) Set of consecutive profiles
Generation of the RangeMap from Profiles
Any RangeMap can be represented as a bi-dimensional image encoding the g coordinate as gray level values (see the following figure). Each column of the image represents data from a single Profile.
Depending on the acquisition technique or the 3D camera used, the profiles will be arranged in rows, instead of columns.
A part's RangeMap acquisition example, represented as a gray level image. Each column correspond to one single profile, rows correspond to the camera pixel y-dimension, while gray level correspond to the depth information. Alternatively, the row-column roles can be switched, depending on the acquisition approach.
A COP consists on a set of organized 3D points. Unlike the rangemaps, the cop values correspond to metric coordinates. COP Object consists of three planes, one for each metric coordinate (x, y and, z). Each COP plane consists on a bi-dimensional grid. The COP object assumes that neighbours on the grid are neighbours on the 3D Space. So, if two points are neighbours in the COP structure, there exists a triangle that connects them in the 3D space.
Obtaining a COP from range maps
Although no linear relation exists between pixels on a range map, and 3D points on a COP, an approximation can be done to generate COP without any calibration.
- Xcop = factorU × Y
- Ycop = factorV × X
- Zcop = factorG × RangeMap(X,Y)
For that, the user should create a MetricConfig using these linear factors as follows:
sal3d::MetricConfig::MetricConfig ( float factorU, float factorV, float factorG)
The cop coordinate Xcop depends on the range map coordinates Y instead of X. Similar with Ycop (see the following picture).
Coordinate modification during rangeMap to COP transformation
This linear assumption is not useful to get accurate reconstructions. In that case, the SAL3D-Metric Tool is recommended.
This SDK provides a calibration tool which allows for the correction of projective distortion. See section Metric Calibration Tool for a more in-depth information on our calibration tool.
Obtaining a COP from 3D points
As a COP object assumes neighborhood between consecutive COP elements, unorganized cloud of points cannot be used to generate a COP object.
The following list presents some of the compatible options to obtain a COP from organized data:
- Time-of-flight Cameras
- 3D Stereo Disparity
- Linear Laser Scanning
In all these situations data is structured in neighborhood, so, it can be directly use for COP objects.
How to Populate a COP Object
Example of how to populate a COP from organized 3D data:
//we define the size of the COP object
const int width = 100;
const int height = 100;
//we create an empty COP object of the desired size. In this example, we
//are going to fill in all the points. Otherwise, we could use true in the
//fillWithNaN parameter to initialize the COP with NaNs.
COP model(width, height, false);
//we get the components of the COP object
//we iterate over all the COP points
for (int i=0; i<height; i++)
for (int j=0; j<width; j++)
//we fill the points with arbitrary coordinates in this case. We
//could load them from a file or any other source. In this example
//all the points are set, otherwise the points not defined should
//be set to NaN.
xModel[i][j] = i;
yModel[i][j] = j;
const float hScal = (float)(i-height/2)*2 / height;
const float wScal = (float)(j-width/2)*2 / width;
//we create a saddle-like surface
zModel[i][j] = (hScal*wScal / (hScal*hScal + wScal*wScal + 0.1)) * height / 2;
The ZMap consists on a planar projection of COP onto the z plane. The CreateZMap(...) function transforms each COP element to the ZMap using the following relation:
YZMap = round((height-1)×(Xcop - xmin)/(xmax - xmin))
XZMap = round((width-1)×(Ycop - ymin)/(ymax - ymin))
ZMap(X, Y) = Zcop
Creating a Z map from a COP
ZMap axes naming does not correspond directly to 3D coordinate axes. Y ZMap axis is related to the vertical axis, that axis corresponds to the X-axis on the 3D coordinate system, so, the motion axis.
A ZMap object internally contains a list of factors:
- xmin: minimum x-coordinate of the associated COP
- xmax: maximum x-coordinate of the associated COP
- ymin: minimum y-coordinate of the associated COP
- ymax: maximum y-coordinate of the associated COP
- width: Total number of columns of the ZMap
- height: Total number of rows of the ZMap
Although the ZMap only contains metric information of the z-coordinate, metric information along x, and y axis can be extracted using ZMapFactors as follows:
- Xmetric = xmin + YZMap×(xmax - xmin)/(height-1)
- Ymetric = ymin + XZMap×(ymax - ymin)/(width-1)
The SAL3D Core contains functions to directly obtain metric information of the 3D point (see sal3d::ZMap::getPoint) or for a unique coordinate (see sal3d::ZMap::getX, sal3d::ZMap::getY, and sal3d::ZMap::getZ)
Ratio Pixel/Metric units
One characteristic of the ZMap is the constant ratio pixel/metric units. So, the metric distance between consecutive pixels along a main axis is always constant.
This constant ratio can be computed from the ZMapFactors:
ratioX = (xmax - xmin)/ (height - 1)
ratioY = (ymax - ymin)/ (width - 1)
Advantages of ZMap
The ZMap has several advantages compared with the typical range map:
- Remove effects of perspective distortion present on a Range Map
- Remove the effects of Range Map distortion due to scanning resolution for laser scanning systems
- Allows to perform 3D measures with 2D libraries
- Simple direct proportional relation between pixels and X,Y metric units
- Z directly in metric units
The following figure displays the same object in 3 different formats: a typical Range Map, a SAL3D ZMap, and a SAL3D ZMap after forcing the top plane parallel to plane Z.
ZMAP after COP orientation
The range map is affected by several reasons: different acquisition resolution on X and Y axis, projective distortion, and the acquisition of the object not being aligned parallel to the camera sensor. With all this deformations it is difficult to compute metric distances over the range map.
The ZMap solves all these deformations. Metric coordinates of each pixel can be determined by using the ZMapFactors.
In addition, if after the ZMap generation, the COP is correctly oriented, it is possible to generate a ZMap aligned with a reference plane. After that, 3D measures can be computed over the ZMap by using standard 2D libraries (like region growing, diameter computation, etc. The right image displays a ZMap where holes are perfectly rounded regardless of the camera orientation. Using this image, it is easy to compute the metric diameter of the hole. It is only required to multiply this value with the metric ratio. (see Forcing an equation metric ratio in both axes and Ratio Pixel/Metric units sections for more information).
Undefined lines on the ZMap
During the creation of the ZMap from a COP, the ZMap could present some black lines (see following picture). These lines correspond to a set of undefined points. This problem appears when no point of the COP object is mapped on those ZMap pixel positions. These undefined points are represented as NaN values on the ZMap.
a) ZMap with undefined lines, b) ZMap without undefined lines
These lines can be avoided by reducing the resolution of the ZMap, i.e., by choosing a smaller height and width in the ZMapFactors (see previous figure b).
Forcing an equation metric ratio in both axes
In addition, the ZMap proportions depends on its factors. As the predefined values depends on the resolution on x and y axis during the acquisition, not always both axis have the same proportions. So, ZMaps could appear different scaled in both axis.
In order to get a ZMap with the same ratio pixels/metric units on both axis, user must take care on the following equation:
(xmax - xmin) * width = (ymax - ymin)*height
ZMap by default
ZMap forcing equal ratio pixels/metric