Without any parameter tweaks, ODM chooses a good compromise between quality, speed and memory usage. If you want to get higher quality results, you need to tweak some parameters:
*``--orthophoto-resolution`` is the resolution of the orthophoto in cm/pixel. Decrease this value for a higher resolution result.
*``--texturing-data-term`` should be set to `area` in forest areas.
*``--mesh-size`` should be increased to ``300000-600000`` and ``--mesh-octree-depth`` should be increased to ``10-11`` in urban areas to recreate better buildings / roofs.
Camera calibration is a special challenge with commodity cameras. Temperature changes, vibrations, focus, and other factors can affect the derived parameters with substantial effects on resulting data. Automatic or self calibration is possible and desirable with drone flights, but depending on the flight pattern, automatic calibration may not remove all distortion from the resulting products. James and Robson (2014) in their paper `Mitigating systematic error in topographic models derived from UAV and ground‐based image networks <https://onlinelibrary.wiley.com/doi/full/10.1002/esp.3609>`_ address how to minimize the distortion from self-calibration.
..figure:: images/msimbasi_bowling.png
:alt:image of lens distortion effect on bowling of data
*Bowling effect on point cloud over 13,000+ image dataset collected by World Bank Tanzania over the flood prone Msimbasi Basin, Dar es Salaam, Tanzania.*
To mitigate this effect, there are a few options but the simplest are as follows: fly two patterns separated by 20°, and rather than having a nadir (straight down pointing) camera, use one that tilts forward by 5°.
As this approach takes longer than traditional imaging, pilots and teams may apply this technique to a smaller area and use the collected data to optimize future flights. OpenDroneMap can generate a calibration file called cameras.json from a small sample flight. The calibration file can be used for future flights, mitigating the bowling effect without sacrificing efficiency.
Alternatively, the following experimental method can be applied: fly with much lower overlap, but two *crossgrid* flights (sometimes called crosshatch) separated by 20° with a 5° forward facing camera.
* Crossgrid overlap percentages can be lower than parallel flights. To get good 3D results, you will require 68% overlap and sidelap for an equivalent 83% overlap and sidelap.
* To get good 2D and 2.5D (digital elevation model) results, you will require 42% overlap and sidelap for an equivalent 70% overlap and sidelap.
By default ODM does not create digital elevation models (DEMs). To create a digital terrain model, make sure to pass the ``--dtm`` flag. To create a digital surface model, be sure to pass the ``--dsm`` flag.
:alt:image of OpenDroneMap derived digital surface model
:align:center
For DTM generation, a Simple Morphological Filter (smrf) is used to classify points in ground vs. non-ground and only the ground points are used. The ``smrf`` filter can be controlled via several parameters:
*``--smrf-scalar`` scaling value. Increase this parameter for terrains with lots of height variation.
*``--smrf-slope`` slope parameter, which is a measure of "slope tolerance". Increase this parameter for terrains with lots of height variation. Should be set to something higher than 0.1 and not higher than 1.2.
*``--smrf-threshold`` elevation threshold. Set this parameter to the minimum height (in meters) that you expect non-ground objects to be.
*``--smrf-window`` window radius parameter (in meters) that corresponds to the size of the largest feature (building, trees, etc.) to be removed. Should be set to a value higher than 10.
Changing these options can affect the result of DTMs significantly. The best source to read to understand how the parameters affect the output is to read the original paper `An improved simple morphological filter for the terrain classification of airborne LIDAR data <https://www.researchgate.net/publication/258333806_An_Improved_Simple_Morphological_Filter_for_the_Terrain_Classification_of_Airborne_LIDAR_Data>`_ (PDF freely available).
Overall the ``--smrf-threshold`` option has the biggest impact on results.
SMRF is good at avoiding Type I errors (small number of ground points mistakenly classified as non-ground) but only "acceptable" at avoiding Type II errors (large number non-ground points mistakenly classified as ground). This needs to be taken in consideration when generating DTMs that are meant to be used visually, since objects mistaken for ground look like artifacts in the final DTM.
..figure:: images/smrf.png
:alt:image of lens distortion effect on bowling of data
:align:center
Two other important parameters affect DEM generation:
*``--dem-resolution`` which sets the output resolution of the DEM raster (cm/pixel)
*``--dem-gapfill-steps`` which determines the number of progressive DEM layers to use. For urban scenes increasing this value to `4-5` can help produce better interpolation results in the areas that are left empty by the SMRF filter.
Weather conditions modify illumination and thus impact the photography results. Best results are obtained with evenly overcast or clear skies. Also look for low wind speeds that allow the camera to remain stable during the data collection process.
In order to avoid shadows which on one side of the stockpile can obstruct feature detection and lessen the number of resulting points, always prefer the flights during the midday, when the sun is at the nadir so everything is consistently illuminated.
Also ensure that your naked eye horizontal visibility distance is congruent with the planned flight distances for the specific project, so image quality is not adversely impacted by dust, fog, smoke, volcanic ash or pollution.
Flight pattern
===============
Most stockpile measurement jobs does not require a crosshatch pattern or angled gimbal as the resting angle of stockpile materials allows the camera to capture the entire stockpile sides. Only some special cases where erosion or machinery operations causes steep angles on the faces of the stockpile would benefit of the crosshatch flight pattern and angled camera gimbal but consider that these additional recognized features come at a cost, (in field labor and processing time) and the resulting improvements are sometimes negligible.
In most of the cases a lawn mower flight pattern is capable of producing highly accurate stockpile models.
..figure:: images/lawnmower_pattern.png
:alt:a simple lawnmower flight pattern can produce accurate results
Recommended overlap would be between 75% and 80% with a sidelap in the order of 65% to 70%. It is also recommended to slightly increase overlap and sidelap as the flight height is increased.
Flight height
==============
Flight height can be influenced by different camera models, but in a general way and in order to ensure a balance between image quality and flight optimization, it is recommended to be executed at heights 3 to 4 times the tallest stockpile height. So for a 10 meter stockpile, images can be captured at a height of 40 meters.
As the flight height is increased, it is also recommended to increase overlap, so for a 40 meter height flight you can set a 65% sidelap and 75% overlap, but for a planned height of 80 meters a 70% sidelap and 80% overlap allowing features to be recognized and properly processed.
GCPs
=====
To achieve accuracy levels better than 3%, the use of GCP’s is advised. Typically 5 distributed GCP are sufficient to ensure accurate results.
When placing or measuring GCP, equipment accuracy should be greater than the GSD. Survey grade GNSS and total stations are intended to provide the required millimetric accuracy.
A highly accurate model can be achieved using WebODM high resolution predefined settings. Then you can further adjust some parameters as necessary.
If using ODM, these this reference values can help you configure the process settings.
--dsm: true
--dem-resolution 2.0
--orthophoto-resolution 1.0
--feature-quality high
--pc-quality high
Measuring
==========
As almost 50% of the material will be found in the first 20% of the stockpile height, special care should be taken in adequately defining the base plane.
Dialog box will show the message "Computing ..." for a few seconds, and after the computing is finished the volume measurement value will be displayed.
..figure:: images/measurement7.png
:alt:Clic on "Finish measurement" to finish the process
:align:center
If you are using the command line OpenDroneMap you can use the dsm files to measure the stockpile volumes using other programs.
Also consider that once the limits of the stockpile are set in software like `QGis <https://www.qgis.org>`_, you will find there are some ways to determine the base plane. So for isolated stockpiles which boundaries are mostly visible, a linear approach can be used. While for stockpiles set in slopes or in bins, the base plane is better defined by the lowest point.
Creation of a triangulated 3D surface to define the base plane is advised for large stockpiles. This is also valid for stockpiles paced on irregular surfaces.
Expected accuracy
=================
For carefully planned and executed projects, and specially when GSD is less than 1 cm, the expected accuracy should be in the range of 1% to 2%.
The resulting accuracy is comparable to the commercially available photogrammetry software and the obtained using survey grade GNSS equipment.
Since many users employ docker to deploy OpenDroneMap, it can be useful to understand some basic commands in order to interrogate the docker instances when things go wrong, or we are curious about what is happening. Docker is a containerized environment intended, among other things, to make it easier to deploy software independent of the local environment. In this way, it is similar to virtual machines.
A few simple commands can make our docker experience much better.
Using either the `CONTAINER ID` or the name, we can access any logs available on the machine as follows:
::
> docker logs 2518817537ce
This is likely to be unwieldy large, but we can use a pipe `|` character and other tools to extract just what we need from the logs. For example we can move through the log slowly using the `more` command:
::
> docker logs 2518817537ce | more
[INFO] DTM is turned on, automatically turning on point cloud classification
Pressing `Enter` or `Space`, arrow keys or `Page Up` or `Page Down` keys will now help us navigate through the logs. The lower case letter `Q` will let us escape back to the command line.
Sometimes we need to go a little deeper in our exploration of the process for OpenDroneMap. For this, we can get direct command line access to the machines. For this, we can use `docker exec` to execute a `bash` command line shell in the machine of interest as follows:
Docker has a lamentable use of space and by default does not clean up excess data and machines when processes are complete. This can be advantageous if we need to access a process that has since terminated, but carries the burden of using increasing amounts of storage over time. Maciej Łebkowski has an `excellent overview of how to manage excess disk usage in docker <https://lebkowski.name/docker-volumes/>`_.
Activate this function to display camera positions.
You can also click in the camera icon to display single images in a frame on the upper right corner. A click on the image frame toggles into full screen mode.
Within the image frame there are links to download the image and the GeoJSON camera file.
..figure:: images/cameras.png
:alt:Camera locations
:align:center
Textured model
==============
Activate this function to show load the textured model. Depending on the file size and connection speed, it may take several seconds to load.
..figure:: images/texturedmodel.png
:alt:Textured model
:align:center
Appearance
==========
Point budget
------------
For both appearance and performance purposes, the point budget on the scene can be managed. Some old and less capable machines would benefit from a 500,000 point budget while most mid-range specs machine are capable of handling 1 to 2 million point budget.
A 5 to 7 million point budget produces a smooth point cloud 3d model, but may result in a high resource demanding process.
Default point budget value is set to 1,000,000.
Field of view
-------------
In order to control model elements to be included within the scene the field of view can be adjusted. Default value is set to 60 degrees.
..figure:: images/FOV_animation.gif
:alt:Field of view adjustment
:align:center
Eye Dome-lighting
-----------------
The Potree Point Cloud 3d viewer module can implement eye dome-lighting, a lighting model that accentuates the shapes of objects.
Eye Dome-lighting group objects, shade their outlines and enhances depth perception in scientific visualization images. It is useful for recognition and measurement of structures within a model. It can be modified by adjusting Radius, Strength and Opacity.
By default, Eye Dome-Lighting is enabled on Potree 3D viewer, but it can be disabled by clicking on the enable option.
This tool measures the radius of a circle formed by three points.
To start a measurement, click on the circle icon and then click on the desired two points. The process will be automatically ended.
Further information such as Circumference can also be obtained from selecting this element under the scene section.
**Azimuth**
This tool measures the azimuthal angle of a line. This line is formed by two points selected by the user, the angle is measured in degrees, clockwise from 0 to 360 and starting from the geographical north.
To start a measurement, click on the azimuth icon and then click on the desired two points. The process will be automatically ended.
Further information can also be obtained from selecting this element under the scene section.
**Area**
This tool measures the horizontal area formed by a polygon.
To start a measurement, click on the area icon and start clicking on the points forming the desired polygon (three or more). Right click to finish measurement.
Further information can also be obtained from selecting this element under the scene section.
**Volume (cube)**
This tool measures the volume formed by a cube.
To start a measurement, click on the volume (cube) icon and click on the model to place the cube. It is possible relocate, redimension and rotate the cube using the displayed handlers. Right click to finish measurement.
Further information can also be obtained from selecting this element under the scene section.
**Volume (sphere)**
This tool measures the volume formed by a sphere.
To start a measurement, click on the volume (sphere) icon and click on the model to place the sphere. It is possible relocate, redimension and rotate the sphere using the displayed handlers. Right click to finish measurement.
Further information can also be obtained from selecting this element under the scene section.
**Height profile**
This tool creates a height profile formed by a line on the model.
To start a measurement, click on the Height profile icon and then form a line on the model by clicking on the desired points (two or more). Right click to finish measurement.
Further information and options, such as "Show 2d Profile", can also been obtained from selecting this element under the scene section.
This tool creates an annotation label on a highlighted point on the model.
To start a measurement, click on the annotation icon and then click on the desired point. The process will be automatically ended.
To edit the annotation, select this element under the scene section, then edit Title and Description.
**Remove measurements**
This tool removes all measurements on the model.
To remove all measurement, click on the "Remove measurements" icon.
Clipping
---------
..figure:: images/clipping.png
:alt:Tools - Clipping tools
:align:center
Point cloud can be clipped by selecting an area. Clipping options include **None** / **Highlight** / **Inside** / **Outside**
To clip a point cloud, click on the volume clip icon, place the cube on the model and relocate, redimension and rotate to contain the desired area.
Highlight is set by default as the clipping method. If display only the points contained within the cube click on "Inside", otherwise click on "Outside".
To remove the clipping volume or polygons click on the "Remove all measurements" icon.
..figure:: images/clipping_animation.gif
:alt:Tools - Clipping
:align:center
Navigation
-----------
..figure:: images/navigation.png
:alt:Tools - Navigation controls
:align:center
Potree 3D viewer have 4 Navigation controls which define its behavior.
**Earth Control**
Earth control navigated as anchored to the ground. Mouse left button moves the model horizontally, mouse wheel controls zoom and right button orbits the model.
**Fly control**
Fly control moves the camera as in birds eye using the keyboard. Keys "W" and "S" moves forward and backwards, respectively and in the direction of the camera, while "A" and "D" moves left and right respectively. Also, the "R" and "F" keys moves the camera up and down. The mouse left button changes the direction of the camera, mouse wheel controls zoom, and right button moves the camera in the XYZ axis.
The speed for these movements can be controlled using the sliding control.
**Helicopter control**
Helicopter control moves the camera as in an aircraft using the keyboard. Keys "W" and "S" moves forward and backwards, respectively restricted in a horizontal plane, while "A" and "D" moves left and right respectively. Also, the "R" and "F" keys moves the camera up and down. The mouse left button changes the direction of the camera, mouse wheel controls zoom, and right button moves the model in the XY axis.
The speed for these movements can be controlled using the sliding control.
**Orbit Control**
Orbit Control is the default navigation behavior. The mouse left button orbits the model, the wheel controls zoom and the right button moves the model in the XYZ axis.
**Full extent**
Full extent button restores the model view.
**Navigation cube**
Navigation cube displays a wireframe cube containing the model.
**Compass**
Compass button displays a compass on the upper right corner.
**Camera animation**
The camera animation button creates a camera animation path. Position of the camera is defined by the points on the green line while the points in the blue line are the location towards the camera is intended to be facing.
To create an animation, adjust the points for the camera locations and camera direction, then select the camera element under the Scene section to create more point, change animation speed or play the animation.
`Learn to edit <https://github.com/opendronemap/docs#how-to-make-your-first-contribution>`_ and help improve `this page <https://github.com/OpenDroneMap/docs/blob/publish/source/tutorials.rst>`_!
When previously mapped sites need revisited, OpenDroneMap can align multiple versions of a dataset through time by using a prior point cloud or digital elevation model. As the prior point cloud `seems to provide better results <https://community.opendronemap.org/t/tips-to-increase-same-site-temporal-consistency/22161/7>`_, that is the approach we will review here.
#. Process your original data. This step doesn't require a ground control point file, but use one if absolute accuracy is a project requirement
#. Download the Point Cloud from your first processed dataset as an LAZ file type (default). Rename the point cloud to align.laz
#. Include that LAZ file with each of your subsequent processing. If you are using command line ODM, include it in the images directory. If uploading, simply upload with your raw images for processing
You can write a SLURM script to schedule and set up available nodes with NodeODM for the ClusterODM to be wired to if you are on the HPC. Using SLURM will decrease the amount of time and processes needed to set up nodes for ClusterODM each time. This provides an easier way for user to use ODM on the HPC.
SLURM script will be different from cluster to cluster, depending on which nodes in the cluster that you have. However, the main idea is we want to run NodeODM on each node once, and by default, each NodeODM will be running on port 3000. Apptainer will be taking available ports starting from port 3000, so if your node's port 3000 is open, by default NodeODM will be run on that node. After that, we want to run ClusterODM on the head node and connect the running NodeODMs to the ClusterODM. With that, we will have a functional ClusterODM running on HPC.
Unfortunately, SLURM does not handle assigning jobs to the head node. Hence, if we want to run ClusterODM on the head node, we have to run it locally. After that, you can connect to the CLI and wire the NodeODMs to the ClusterODMs. Here is an example following the sample SLURM script:
It is also possible to pre-populate nodes using JSON. If starting ClusterODM from apptainer or docker, the relevant JSON is available at `docker/data/nodes.json`. Contents might look similar to the following:
After finish hosting ClusterODM on the head node and finish wiring it to the NodeODM, you can try tunneling to see if ClusterODM works as expected. Open another shell window in your local machine and tunnel them to the HPC using the following command:
Replace user and hostname with your appropriate username and the hpc address. Basically, this command will tunnel the port of the hpc to your local port. After this, open a browser in your local machine and connect to `http://localhost:10000`. Port 10000 is where ClusterODM's administrative web interface is hosted at. This is what it looks like:
Port 3000 is ClusterODM's proxy. This is the place we assign tasks to ClusterODM. Once again, connect to `http://localhost:3000` with your browser after tunneling. Here, you can Assign Tasks and observe the tasks' processes.
After adding images in this browser, you can press Start Task and see ClusterODM assigning tasks to the nodes you have wired to. Go for a walk and check the progress.
Development and testing of code changes can be difficult. The simplest way to do so is modify the code and rebuild docker images from source, much as documented in the `README for the ODM repository <https://github.com/OpenDroneMap/ODM?tab=readme-ov-file#build-docker-images-from-source>`_.
However, having to do a full docker rebuild for each change is time consuming and wasteful. What might be better is to have a dedicated, long running node that allows us to test out changes in near real time.
#. Fork and clone repository
#. Set up local NodeODM docker instance
#. Modify code
#. Connect to NodeODM instance
#. Install and use changes
Fork and clone repository
-------------------------
First, let's fork the ODM repo, and checkout a new branch locally that will function as our development branch.
docker run -d --restart unless-stopped -p 3000:3000 -v /path/to/cloned/ODM/repository/data:/code opendronemap/nodeodm
Modify code
-----------
For our test today, we will attempt to upgrade Ceres Solver to version 2.2.0. Most external libraries like Ceres can be found in the Superbuild directory. In this case we edit SuperBuild/cmake/External-Ceres.cmake, and set it to use version 2.2.0
Success! Now we can either run ODM directly inside this container, use the NodeODM interface to process data, or connect in with WebODM for additional testing.