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.
An example of how the laser stripe shape varies as a function of the object's height can be seen in the following 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 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.
Any RangeMap can be represented as a bidimensional 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 COP consists on a set of organized 3D points. Unlike the rangemaps, the cop values correspond to metric coordinates. COP Object consists on three planes, one for each metric coordinate (x, y and, z). Each COP plane consists on a bidimensional 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.
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.
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 coordinate Y instead of X. Similar with Ycop (see the following picture).
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.
As a COP object assumes neighborhood between consecutive COP elements, unorganized cloud of points can not be used to generate a COP object.
The following list presents some of the compatible options to obtain a COP from organized data:
In all these situations data is structured in neighborhood, so, it can be directly use for COP objects.
When a COP is not correctly populated, and the coordinate axis is not according the previous figure (Coordinate modification during rangeMap to COP transformation), the COP normals are defined in the wrong direction, so, instead of pointing outside the object, they are pointing inside the object. This could generate errors on some of the SAL3D tools.
So, it is important to assure that x axis is align to the COP rows, so x coordinates increase together with the COP rows and y axis is align with the COP columns, so, y coordinates increase together with the COP colummns.
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 COP::Component xModel(model.getX()); COP::Component yModel(model.getY()); COP::Component zModel(model.getZ()); //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:
A ZMap object internally contains a list of factors:
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:
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)
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:
The ZMap has several advantages compared with the typical range map:
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.
|
|
|
|---|---|---|
| Range Map | Direct ZMap | 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 before 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).
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.
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).
This SAL3D version includes a new ZMap constructor that remove quantization effects. This ZMap constructor is based on 3D interpolated data using neighborhood information to create a more accurate ZMap. In addition, this new version minimizes the Undefined lines on the ZMap.
As this new version is sensiblely slower compared with the previous one, user can choose between this new version or the previous one using a constructor parameter. (See ZMap Constructor for more information). SAL3D uses by default this new technique. In addition, the functions sal3d::ZMap::getDistanceToMovedCOP and sal3d::ZMap::getFineDistanceToMovedCOP internally uses this new constructor. If uses is interested to use the old approach, user must do in two steps. First creating a ZMap using the moved cop especifying the old constructor, and then computing the distance to this ZMap using functions sal3d::ZMap::getDistanceToZMap and sal3d::ZMap::getFineDistanceToZMap.
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
by
1.7.6.1