Introduction

This tutorial demonstrates how to automate photogrammetric correction of nadir and oblique digital aerial imagery, and generate point cloud and 3D mesh products using the ArcGIS API for Python. In this workflow, you will process a collection of multi-camera digital aerial images through the complete reality mapping pipeline, including:

  • Creating a project and mission
  • Performing block adjustment
  • Generating products

The dataset for this tutorial was provided by Vexcel Imaging, and is comprised of 64 nadir and 183 oblique, digital aerial images covering a section of Hollywood, California. The required frames and cameras table needed to support the block adjustment process is also provided. The path in each of the entries of the Raster column of the frame table need to be updated to the correct path you save the data on your computer. We recommend using a UNC path or datastore path.

Getting Started

Reality mapping capability through ArcGIS API for Python requires ArcGIS Enterprise federated with a Reality Server license. See the configuration instruction for setup details.

Once your environment is configured, import the required class and module:

  • GIS class: Represents the organizational deployment and accesses classes to manage content, users, and groups

  • arcgis.raster.realitymapping submodule provides the functionality to automate reality mapping tasks in the server environment. The reality mapping module is available with ArcGIS API for Python (version >= 2.4.2)

from arcgis.gis import GIS
from arcgis.raster import realitymapping

Establish a connection to your ArcGIS Enterprise portal and verify that reality mapping is supported in your environment.

note: Change credentials to match your organization credentials.

# connect to GIS
gis = GIS(
    url= "https://yourportal.domain.com/portal",
    username= "your username",
    password= "your password"
)

# confirm that reality mapping is supported
realitymapping.is_supported(gis)

Step 1: Create a Project

The first step is to create a reality mapping project using the Project class of the reality mapping module. For this example, we are using oblique digital aerial data, so we set the sensor_type and scenario_type accordingly.

project = realitymapping.Project(
    project="RMDigitalAerial3Dz", 
    sensor_type = "AerialDigital", 
    scenario_type= "AerialOblique"
)
project

A project is a top-level workspace for managing reality mapping activities. When a project is initialized, both a new portal folder and a reality mapping project item inside that folder are created. The project [item](/python/latest/api-reference/arcgis.gis.toc.html#item contains the basic information (e.g. project name, group name, workspace name, etc.) that defines a reality mapping project. All related image services and products generated in subsequent steps will be stored in the project folder.

# Project item id
project.item.itemid
'6879e67fe5fc48a985813447aa8b3970'

Step 2: Create a Mission

The next step is to create a mission. It contains all related imagery and the resulting processed data products for managing a single data capture session. A mission also uses an image collection for the source rasters. So we need to first define the type, properties and path of the source rasters using the ImageSource class.

# Create an image source of Frame Camera type
DA_src = realitymapping.ImageSource("Frame Camera")
# Define camera table and dem
DA_src.raster_type.camera_info = r"C:\SampleData\RM_DigitalAerial_Tutorial_3D\Nadir_Oblique_FramesCam_UNC.csv"
DA_src.raster_type.dem = r"C:\SampleData\RM_DigitalAerial_Tutorial_3D\DEM\DEM_USGS_1m.tif"
# Define the source rasters' path
DA_src.input_data = r"C:\SampleData\RM_DigitalAerial_Tutorial_3D\Nadir_Oblique_FramesCam_UNC.csv"

Other parameters specific to the digital aerial raster type we just created can be defined similarly to the camera_info and dem parameters in the cell above. To see the possible attributes, use the attributes property of the raster_type instance.

DA_src.raster_type.attributes
{'name': 'Frame Camera',
 'camera_info': 'C:\\SampleData\\RM_DigitalAerial_Tutorial_3D\\Nadir_Oblique_FramesCam_UNC.csv',
 'processing_template': None,
 'dem': 'C:\\SampleData\\RM_DigitalAerial_Tutorial_3D\\DEM\\DEM_USGS_1m.tif',
 'averagezdem': None,
 'constant_z': None,
 'zfactor': None,
 'zoffset': None,
 'correct_geoid': None,
 'estimate_flight_height': None,
 'is_altitude_flight_height': None,
 'minimum_flight_height': None,
 'stretch_type': None,
 'scale_factor': None,
 'valid_range': None}

Now we can create mission using the image source object.

mission = project.create_mission(
            image_sources = DA_src,
            out_sr = {"wkid": 6423, "vcsWkid": 5703} # NAD 1983 California/NAVD88
) 
# check the number of images in the image collection
print(mission.image_count)

# Show specifc image in the collection
mission.image_collection.layers[0].filter_by("OBJECTID=1")

You have just created a image collection for multi-camera digital aerial rasters using Frame Table file. At this point, your imagery is organized but not yet geometrically adjusted. The next step is to perform block adjustment.

Step 3: Perform Adjustment

Block adjustment involves using tie points to calculate the exterior orientation for each each image such that they are consistent with neighboring images (Relative orientation). A more refined adjustment can then be performed using Ground Control Points (GCP). Read more about adjustment here.

3.1 Compute Initial Block Adjustment

For this tutorial, you will perform adjustment for the mission created using compute_sensor_model() method. The compute_sensor_model() method computes block adjustment for the image collection and applies the frame transform to the images based on the raster type information used when creating the image collection. It also generates the control points feature class, solution table, solution points feature class, and flight path feature class.

note: These feature classes and tables will be saved in raster store and will not be created in the ArcGIS Enterprise as separated items.

mission.compute_sensor_model(location_accuracy= "Medium")
mission.generate_report()

Confirm that everything looks goods for the quality check of the adjustment report, except for the warning that Ground Control Points and Check Points are not used in the adjustment.

Step 4: Get Results

The final step after block adjustment is to generate products. The reconstruct_surface() method can generate one or multiple reality mapping products from adjusted imagery. In this tutorial, You will create point clouds and 3D mesh.

products_3d = mission.reconstruct_surface(
                output_products= ["POINT_CLOUD", "MESH"],
                scenario= "AerialOblique", 
                quality= "Ultra"
)

Conclusion

You've successfully completed a reality mapping workflow for digital aerial imagery using the ArcGIS API for Python. In this tutorial, you:

  • Created a reality mapping project and mission for nadir and oblique digital aerial imagery.
  • Performed block adjustment to geometrically correct your imagery collection.
  • Generated point clouds and 3D Mesh products.

See the following guides to see how the same principles and methods demonstrated here can be adapted for other raster types:

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.