-
Notifications
You must be signed in to change notification settings - Fork 44
Scene
For an overview of tools to obtain your virtual scene or individual sceneparts, check out the Supplementary tools for scene generation.
For infos on dynamic scenes, visit the extra page Dynamic scenes.
The scene is referenced in the <survey>
tag of the survey.xml
together with the survey name
, the platform
, the scanner
and optionally a seed
. Referencing the different components is done by specifying the absolute or relative path of the XML files, followed by a hash (#) and the ID of the entry.
<survey name="toyblocks_als"
platform="data/platforms.xml#sr22"
scanner="data/scanners_als.xml#riegl_vq-880g"
scene="data/scenes/toyblocks/toyblocks_scene.xml#toyblocks_scene">
The scene XML then links to separate files, which hold the actual geometry data. The XML file defines how the raw data that is read from the files should be preprocessed and arranged to build the scene. For an overview of all possible tags and parameters in the survey XML, go to XML Tag and Parameter Summary at the bottom of the page.
A scene XML file starts with a <scene>
tag, containing the id
and name
of the scene.
Any number of <part>
tags can be specified inside the <scene>
tag. Each of them contains one or more <filter>
tags. There are four loaders for different geometry types and three filters for coordinate transformations.
<?xml version="1.0" encoding="UTF-8"?>
<document>
<scene id="toyblocks_scene" name="ToyblocksScene">
<part>
<filter type="objloader">
<param type="string" key="filepath" value="data/sceneparts/basic/groundplane/groundplane.obj" />
<param type="string" key="up" value="z" /> <!-- to silence warning about missing parameter -->
</filter>
<filter type="scale">
<param type="double" key="scale" value="70" />
</filter>
<filter type="translate">
<param type="vec3" key="offset" value="20.0;0;0" />
</filter>
</part>
<part>
<filter type="objloader">
<param type="string" key="filepath" value="data/sceneparts/toyblocks/cube.obj" />
<param type="string" key="up" value="y" /> <!-- this would be the required for the default export e.g. in Blender -->
</filter>
</part>
<!-- ... -->
</scene>
</document>
Note that survey and scene can also be contained in one single XML file as shown in data/surveys/toyblocks/uls_toyblocks_survey_scene_combo.xml
.
The loader filters are distinguished by their type
. Within each loader filter, a parameter specifying the path to the file has to be specified.
<filter type=“objloader”>
<param type="string" key="filepath" value="data/sceneparts/basic/groundplane/groundplane.obj" />
</filter>
To load multiple files with the exact same settings, the files can be specified with regular expressions using the "efilepath" key. This option is available for the objloader
, the xyzloader
and the detailedVoxels
.
<param type="string" key="efilepath" value="data/sceneparts/toyblocks/.*.obj" />
This way, the geometry from each file will receive a unique incremental ID*. Alternatively, a single custom ID can be specified in the <part>
-tag, which is applied to all geometries loaded with the efilepath
parameter:
<part id="1">
<filter type="objloader">
<param type="string" key="efilepath" value="data/sceneparts/buildings/.*.obj"/>
</filter>
<filter type="rotate">
<param type="rotation" key="rotation">
<rot axis="x" angle_deg="90" />
</param>
</filter>
</part>
HELIOS++
uses either polygon mesh objects or voxels as geometry, which are loaded in different ways.
*All files are loaded to one scenepart and subsequently split into one subpart per file. Origin, rotation and scale information are applied before splitting and thus, each scene part coming from the original one still considers the origin and transformation specifications of the original scene part. This has to be considered when using e.g. pyhelios to transform objects during the simulation. The origin and transformation specifications can easily be reverted with the known specifications and updated.
<filter type=“objloader”>
This loader reads polygon meshes with associated material definitions from a Wavefront Object (.obj) file.
The orientation of the mesh can be specified with the up
parameter within a separate param
-tag. Often, the default value="z"
will be suitable. However, some software (e.g., Blender) exports meshes with the y-axis pointing upwards per default, so here we would specify value="y"
. For a demonstration of this parameter, see data/scenes/arbaro_demo.xml:
<param type="string" key="up" value="y" /> <!-- the default is 'z', but if it is not set explicitly, we will print an info message -->
Within the obj file, the line mtllib file.mat
links to a material file. Multiple materials can be defined in one material file. All faces, which are preceeded by the line usemtl material1
will use material1
, all faces preceeded by usemtl material2
will use material2
and so on. Check out section Materials / Intensity Modelling for more details.
<filter type="geotiffloader">
This loader reads a terrain elevation map in the GeoTIFF format and converts it into a triangle mesh. The centers of the pixels are used as data points. If all points are valid (following the invalid value definition from the GeoTiff header), two triangles are built up: Current point - right neighbor - upper right neighbor and current point - upper neighbor - upper right neighbor:
If any of the three points has an invalid value, the triangle is omitted.
<filter type="xyzloader">
This loader reads an ASCII XYZ point cloud file. It subdivides the space into a grid of cubic cells ("voxels") and checks whether a cell contains at least one point of the point cloud. If this is the case, the cell is defined as "solid" and an axis-aligned bounding box primitive with the extent of the cell is created, providing a surface to be virtually scanned in HELIOS++
.
The separator
parameter defines the separator used in the ASCII file, e.g. space or comma.
<param type="string" key="separator" value=" " />
HELIOS++
expects the columns in the ASCII file to have the following format:
X Y Z Nx Ny Nz
Only X, Y and Z are mandatory. For files with different format, column indices can be given explicitly:
<param type="int" key="normalXIndex" value="6" />
<param type="int" key="normalYIndex" value="7" />
<param type="int" key="normalZIndex" value="8" />
The desired side length of a voxel is specified with voxelSize
.
<param type="double" key="voxelSize" value="0.2" />
Note: If using a scale filter in combination with the xyzloader, voxelSize corresponds to the voxelSize before scaling.
To obtain ray incidence angles for voxels for the calculation of return intensity, different options are provided by HELIOS++
:
If the point cloud does not contain point normals, normals will always be calculated using Singular Value Decomposition (SVD). This is also possible if the ASCII file contains normals by explicitly specifiying
<param type="int" key="estimateNormals" value="1" />
or
<param type="int" key="estimateNormals" value="2" />
In mode 1, all normal computations are performed at once in memory which is working well for small point clouds. Mode 2 handles the computations in separate batches. The batch size is set to 10,000,000 points which means that no more than 10,000,000 points are held in memory when estimating normals. This mode is slower than mode 1 but can handle large point clouds.
For voxels containing less than three points, no normal can be estimated. These voxels are either discarded or they are assigned a defaultNormal
if it is specified as a vector like this:
<param type="vec3" key="defaultNormal" value="0;0;1" />
The default behavior for point clouds with normals is to average the normals of each point within the voxel to derived the voxel normal. As an alternative, the normal of the point closest to the voxel center can be assigned as point normal by setting:
<param type="boolean" key="snapNeighborNormal" value="true" />
<filter type="detailedvoxels">
This loader reads voxel models in a simple ASCII format with .vox extension, inspired by the format used in the software AMAPVox software (Vincent et al. 2017). The primary purpose of DetailedVoxels is to model vegetation with given leaf properties.
VOXEL SPACE
#min_corner: 12.464750289916992 -10.332499504089355 243.5574951171875
#max_corner: 21.312000274658203 -1.6010000705718994 272.84124755859375
#split: 36 35 118
#res:0.25 #nsubvoxel:8 #nrecordmax:0 #fraction-digits:7 #lad_type:Spherical #type:TLS #max_pad:5.0 #build-version:1.4.3
i j k PadBVTotal angleMean bsEntering bsIntercepted bsPotential ground_distance lMeanTotal lgTotal nbEchos nbSampling transmittance attenuation attenuationBiasCorrection
0 0 0 0 86.3137164 0.4989009 0 2.8475497 0.1240837 0.1632028 693.775004 0 4251 1 0 0
0 0 1 0 86.989336 1.011544 0 2.840831 0.3722511 0.1784628 1292.784752 0 7244 1 0 0
0 0 2 0 87.2224845 1.1786434 0 2.835464 0.6204185 0.1828753 1434.1079874 0 7842 1 0 0
0 0 3 0 87.1534196 0.9608315 0 2.8170681 0.8685859 0.1816032 1186.2322972 0 6532 1 0 0
0 0 4 0 87.2968587 0.8746295 0 2.8187793 1.1167532 0.1841085 1201.8604542 0 6528 1 0 0
0 0 5 0 87.1479655 0.9425028 0 2.8363264 1.3649206 0.1747828 1195.6891804 0 6841 1 0 0
The file (as of version 1.4.3) uses space as separator and has six header lines.
- Lines 2 and 3 define the axis aligned bounding box with the xyz coordinates of the minimum and maximum corners (
#min_corner
and#max_corner
). - Line 4 gives the number of voxels in x, y and z direction (
#split
). - Line 5 defines the resolution (
#res
), the leaf angle distribution type (#lad_type
) and the maximum plant area density value (#max_pad
). It can furthermore contain additional information which are not read byHELIOS++
. - Line 6 contains the column names.
-
i
,j
andk
are the voxel indices in x, y and z direction -
PADBVTotal
is the plant area density (m2/m3). This parameter is used by HELIOS++ in thetransmittive
mode to calculate the return and in thescaled
mode to determine the size of each voxel (see next sections) -
bsEntering
is the entering beam surface -
bsIntercepted
is the intercepted beam surface -
bsPotential
is the potential beam surface -
ground_distance
is the distance from voxel center to the ground (if the ground is not set, i.e., no DTM filter used, this value is the height of the voxel relative to a plane with equation Z = 0) -
lMeanTotal
is the mean length of the optical path inside the voxel -
lgTotal
is the length sum of optical path inside the voxel -
nbEchos
is the number of hits inside the voxel -
nbSampling
is the number of (possibly attenuated) pulses entering the voxel -
transmittance
is the estimated voxel transmittance (standardized per one meter optical path length) -
attenuation
is the attenuation coefficient -
attenuationBiasCorrection
is the attenuation coefficient after bias correction
-
More in-depth explanations are given in the AMAPVox 1.0.1 user guide (page 28) and in the AMAPVox GUI tooltips.
All following lines contain the voxel values with each line representing one voxel. Empty voxels (PADBVTotal
= 0 and transmittance
= 1) may or may not be explicitly defined.
There are three modes available for handling ray intersections with DetailedVoxels. The different modes are demonstrated in data\surveys\voxels\als_detailedVoxels_mode_comparison.xml
and data\surveys\voxels\uls_detailedVoxels_mode_comparison.xml
.
Figure: Simulated point clouds using detailedVoxel tree models with different modes, colored by return number. From left to right: fixed size voxels (0.25 m), fixed size voxels (0.05 m), transmittive, scaled, scaled with additional random shift.
1. Transmittive mode (default)
In transmittive mode, voxels are considered to be filled with transmittive turbid medium. Each voxel is filled with randomly distributed infinitely small sized leaf scatterers. Voxels are therefore defined by a leaf area density (
where
If a ray intersects a voxel, the distance before collision
If the distance
2. Scaled mode
In scaled mode, each voxel is considered to be solid (non-transmittive) and of a specific size determined by the leaf area density according to the equation (adapted from AMAPVox OBJ export tool):
where PADBVTotal
and alpha is a scaling factor (default: 0.5). If a ray intersects a scaled voxel, the intersection point is returned.
Scaled mode is activated by passing the value scaled
to intersectionMode
:
<param type="string" key="intersectionMode" value="scaled" />
The scaling factor alpha can be modified via the key intersectionArgument
:
<param type="double" key="intersectionArgument" value="0.3334" />
There is the option to shift voxels randomly within the original voxel resolution to disrupt the regular pattern of the voxels and to achieve more "natural" models using the randomShift
key:
<param type="boolean" key="randomShift" value="true" />
3. Fixed mode
In fixed mode, each voxel is modelled as solid (not light-transmittive) and of the size given by #res
. Only Voxels with transmittance < 1 are considered to be filled. If a ray intersects a filled voxel, the intersection point is returned.
Fixed mode is activated by passing the value fixed
to intersectionMode
:
<param type="string" key="intersectionMode" value="fixed" />
The python script pyhelios/util/voxelizer_write_vox.py can be used to generate a simple .vox file which can be used for this mode. It voxelizes a point cloud with a given resolution and writes it into the HELIOS++
-readable voxel file format.
How to define materials for non-OBJ sceneparts is explained in the Material files section.
Coordinate transformation filters can be passed to every scene geometry in order to translate, rotate or scale the geometry.
Rotations and scaling are always about the origin, i.e. (0,0,0), of the object's coordinate system. The translation transforms the origin of the object coordinate system. This is portrayed in the following schematic:
This filter applies a translation to the geometry which is given in the form of a 3D vector, separated by semicolons. The following tag shifts the geometry in x-direction by 5 units and in y-direction by -12.5 units.
<filter type="translate">
<param type="vec3" key="offset" value="5.0;-12.5;0" />
</filter>
In many cases, objects should be placed on the ground. HELIOS++ can perform this translation automatically with the onGround
-parameter.
<filter type="translate">
<param type="integer" key="onGround" value="-1" />
<param type="vec3" key="offset" value="-120;225;0" />
</filter>
For this parameter to work, an object in the scene has to be labelled as ground in a corresponding material file by inserting the following line:
helios_isGround true
(see Materials / Intensity Modelling).
The onGround
parameter can take on the following values:
-
0
: No usage. -
-1
: Find optimal ground translation. -
1
: Find quick ground translation. -
>1
: Specify a given depth for the search process.
This filter applies a rotation to the geometry scenepart, using the axis-angle representation. The following example performs a rotation of 90° around the x-axis or unit vector (1,0,0).
<filter type="rotate">
<param key="rotation" type="rotation">
<rot angle_deg="90" axis="x"/>
<rot angle_deg="0" axis="y"/>
<rot angle_deg="0" axis="z"/>
</param>
</filter>
This filter scales the geometry by a given factor.
<filter type="scale">
<param type="double" key="scale" value="0.5" />
</filter>
The laser return intensity values are calculated using the laser radar equation.
Currently, for its calculation HELIOS++
takes the following factors into account:
Factor | Description | Provided by | Default |
---|---|---|---|
Average power | Transmitted optical power (watts) | User: averagePower_w in scanner XML
|
4.0 W |
Aperture size | Receiver aperture diameter (meters) | User: receiverDiameter_m in scanner XML
|
0.15 m |
Atmosphere transmission | Visibility (km) | User: atmosphericVisibility_km in scanner XML
|
23.0 km |
System transmission | Energy passed after system inefficiency (dimensionless) | User: opticalEfficiency in scanner XML
|
0.99 |
Beam divergence | Increase of the beam diameter with increasing range (radians) | User: beamDivergence_rad in scanner XML
|
0.0003 rad |
Range | Distance to the target (meters) | HELIOS++ |
- |
Angle of incidence | Angle of incidence to the target (radians) | HELIOS++ |
- |
Area | Area of the target illuminated by the beam (square meters) | HELIOS++ |
- |
Reflectance | Reflectance of the target surface (dimensionless) | User: helios_reflectance in material file (.mtl) or ASTER |
50 |
Specularity | Specularity of the target surface | User: ks and kd in material file (.mtl): |
- |
Specular exponent | Specularity of the target surface | User: Ns in material file (.mtl) |
- |
HELIOS++ reads material properties from wavefront MTL material library files. Following the standard, these files and their materials are linked to mesh faces using the mtllib
and usemtl
statements in the .OBJ file.
For xyzloader
, geotiffloader
, and detailedVoxels
, materials can be specified in the XML file for each scenepart.
The matfile
parameter links to a specific material file, similar to the mtllib
line in .obj files:
<param type="string" key="matfile" value="data/sceneparts/arbaro/tree.mtl" />
The matname
parameter specifies a specific material (here: "leaves") in the material file. It is the equivalent to the usemtl
line in .obj files:
<param type="string" key="matname" value="leaves" />
Furthermore, voxel material also supports uniform randomization. For this, a number of random materials and a random range has to be specified:
<param type="integer" key="randomMaterials" value="5" />
<param type="double" key="randomRange" value="0.1" />
HELIOS-specific parameters
There are three HELIOS
-specific parameters, that can be added to material files by inserting respective lines in the material definitions.
-
helios_reflectance
: This parameter specifies the reflectance of the target surface using values in the range of [0, 100], e.g.helios_reflectance 70.8
. (default: 50.0) -
helios_spectra
: Instead of setting reflectance values of the materials by hand, they can be retrieved from the ECOSTRESS spectral library (formally ASTER spectral library). For each material, this library provides a file specifying its reflectance for different wavelengths in range [0, 100]. HELIOS includes a small set of these spectra in the assets/spectra folder, such as asphalt, grass, wood or gray and red shingles. More spectra can be downloaded from NASA's JPL. The spectra files contained in assets/spectra can be referenced by their name, e.g.helios_spectra grass
. Now HELIOS++ will select the appropriate reflectance for the material given the wavelength of the laser. If the selected wavelength is not specified in the library (as they are discrete values) the reflectance will be interpolated. If no spectra is specified in the .mtl, the reflectance will be set to 50 by default and a warning will be displayed. -
helios_classification
: This parameter can be used to assign a classification to different sceneparts according the ASPRS Standard (see LAS Specification p. 11), e.g.helios_classification 2
for the ground. This classification will appear as an attribute of the respective simulated point reflected from that scenepart. (default: 0) -
helios_isGround
: Boolean parameter, which can have either values "false"/"0" or "true"/"1". If set to "true", geometries with this material are considered ground. This information is used for theonGround
parameters, which can be used to translate sceneparts and platforms. (default: "true")
HELIOS++ intensity is based on Phong's BDRF reflectance model coupled with the lidar-radar equation. The recorded intensity (signal amplitude) is calculated as follows:
- Calculation of the BDRF from the material reflectance
$\rho$ (either set byhelios_reflectance
in the.mat
-File or via ahelios_spectra
and the wavelength of the scanner that is used) and the specularity$\text{spec}$ (defined by the settings ofkd
($k_d$ ),ks
($k_s$ ) and the specular exponentNs
($N_s$ )). The incidence angle$\varphi$ is calculated from the intersection of the ray and the object.
Where
and
and where
- Calculation of the lidar cross section
$\sigma$ using the illuminated target area$A$ following Wagner (2010), Eq. 14 (area illuminated by a sub-ray. It is assumed that each subray either hits the target fully or not at all. Partial hits of sub-rays are treated as full hits in the intensity simulation).
- Calculation of the received intensity
$I$ from the lidar-radar equation including atmospheric attenuation (Carlsson et al., 2001):
Where
with
where
Attribute | Default value | Comment |
---|---|---|
id |
- | REQUIRED |
name |
- |
Attribute | Default value | Comment |
---|---|---|
id |
Incremental hitObjectId according to the order of parts specified in the XML (starting with 0) |
Useful to give custom hitObjectIds or to assign a single ID to a group of objects loaded with the efilepath parameter |
Attribute | Default value | Comment |
---|---|---|
type |
- |
REQUIRED, possible values: "objloader", "xyzloader", "detailedVoxels", "geotiffloader" (geometry loaders; only one per <part> ),"translate", "rotate", "scale" (coordinate transformations) |
Attribute | Default value | Comment |
---|---|---|
key="filepath" |
specific to the geometry loaders, in this case REQUIRED, e.g., <param type="string" key="filepath" value="path/to/geometry" />
|
|
key="efilepath" |
specific to the geometry loaders, e.g. <param type="string" key="efilepath" value="path/to/geometries" /> works with any regular expressions supported by boost |
|
key="up" |
value="z" |
specific to the objloader , defines vertical axis. Must be either "z" (default) or "y" (sometimes required when the exporting software uses the vertical axis as secondary, e.g., with Blender) |
key="separator" |
value=" " |
specific to xyzloader, e.g. <param type="string" key="separator" value="," />
|
key="voxelSize" |
value="1" |
specific to xyzloader, e.g. <param type="double" key="voxelSize" value="0.5" />
|
key="estimateNormals" |
value="0" if file contains normals, value="1" otherwise |
specific to xyzloader, e.g. <param type="int" key="estimateNormals" value="1" /> 0 = do not estimate normals, 1 = regular mode, 2 = batch mode for large point clouds |
key="defaultNormal" |
none (assignDefaultNormal=false) | specific to xyzloader, e.g. <param type="boolean" key="snapNeighborNormal" value="true" />
|
key="normalXIndex" |
value="3" |
specific to xyzloader, e.g. <param type="int" key="normalXIndex" value="3" />
|
key="normalYIndex" |
value="4" |
specific to xyzloader, e.g. <param type="int" key="normalYIndex" value="4" />
|
key="normalZIndex" |
value="5" |
specific to xyzloader, e.g. <param type="int" key="normalZIndex" value="5" />
|
key="intersectionMode" |
value="transmittive" |
specific to detailedVoxels, e.g. <param type="string" key="intersectionMode" value="scaled" /> possible values: "transmittive", "scaled", "fixed" |
key="intersectionArgument" |
value="0.5" |
specific to detailedVoxels scaled mode, e.g. <param type="double" key="intersectionArgument" value="0.3334" /> used to modify the scaling factor alpha |
key="randomShift" |
value="false" |
specific to detailedVoxels scaled mode, e.g. <param type="boolean" key="randomShift" value="true" />
|
key="matfile" |
use "default" material (xyzloader) or "wood" (detailedVoxels)* | specific to xyzloader, geotiffloader and detailedVoxels, e.g. <param type="string" key="matfile" value="data/sceneparts/arbaro/tree.mtl" />
|
key="matname" |
use "default" material (xyzloader) or "wood" (detailedVoxels)* | specific to xyzloader, geotiffloader and detailedVoxels, e.g. <param type="string" key="matname" value="leaves" />
|
key="randomMaterials" |
no randomized materials, use "default" material (xyzloader) or "wood" (detailedVoxels)* |
specific to xyzloader and detailedVoxels, e.g. <param type="integer" key="randomMaterials" value="5" />
|
key="randomRange" |
value="1.0" if randomized materials requested, else no randomized materials, use "default" material (xyzloader) or "wood" (detailedVoxels)* |
specific to xyzloader and detailedVoxels, <param type="double" key="randomRange" value="0.1" />
|
key="offset" |
value="0;0;0" (no translation) |
specific to the translate filter, e.g. <param type="vec3" key="offset" value="5.0;-12.5;0" />
|
key="onGround" |
value="0" (no translation) |
specific to the translate filter, 0 = no translation, -1 = find optimal ground translation, 1 = find quick translation, >1 = specify a given depth for the search process e.g. <param type="integer" key="onGround" value="-1" />
|
key="scale" |
value="1" (no scaling) |
specific to the scale filter, e.g. <param type="double" key="scale" value="0.5" />
|
key="rotation" |
rotations="global" |
specific to the rotate filter, i.e. <param key="rotation" type="rotation" rotations="global"> possible values for rotations : "global", "local"enclosed is one or multiple <rot [...]> tag |
*default material:
newmtl default
Ka 0.0 0.0 0.0
Kd 0.0 0.0 0.0
Ks 0.0 0.0 0.0
Ns 10
helios_classification 0
helios_reflectance 50
helios_isGround true
Attribute | Default value | Comment |
---|---|---|
angle_deg |
||
axis |
possible values: "x", "y" and "z" (upper or lower case spelling) |
Carlsson, T., Steinvall, O., and Letavik, D. "", 2001. https://www.foi.se/rest-api/report/FOI-R--0163--SE
Jutzi, B., and H. Gross. "Normalization Of Lidar Intensity Data Based On Range And Surface Incidence Angle", 2009. https://publica.fraunhofer.de/handle/publica/362664.
North, P.R.J. (1996): Three-dimensional forest light interaction model using a Monte Carlo method. In: IEEE Transactions on Geoscience and Remote Sensing 34(4), pp. 946-956. DOI: 10.1109/36.508411.
Vincent, G., Antin, C., Laurans, M., Heurtebize, J., Durrieu, S., Lavalley, C. & Dauzat, J. (2017): Mapping plant area index of tropical evergreen forest by airborne laser scanning. A cross-validation study using LAI2200 optical sensor. In: Remote Sensing of Environment 198, pp. 254-266. DOI: 10.1016/j.rse.2017.05.034.
Wagner, W. "Radiometric calibration of small-footprint full-waveform airborne laser scanner measurements: Basic physical concepts." ISPRS Journal of Photogrammetry and Remote Sensing 65.6 (2010): 505-513. DOI:10.1016/j.isprsjprs.2010.06.007