What Is E57?
E57 is an open file format standard for storing data produced by 3D imaging systems — terrestrial laser scanners, handheld structured light scanners, photogrammetric systems, and airborne LiDAR. Published by ASTM International as ASTM E2807-11, E57 was developed to address a critical gap in the 3D scanning industry: every scanner manufacturer had its own proprietary format, making data exchange between software platforms painful and error-prone.
Unlike LAS (which focuses on airborne LiDAR point attributes), E57 is designed for multi-scan registration workflows — it can store multiple scan positions within a single file, associate panoramic color photographs with each scan, and preserve the original scanner coordinate system alongside global registered coordinates.
E57 File Structure
An E57 file has a hybrid structure combining XML metadata with compact binary point data:
E57 File
├── XML Header (UTF-8, uncompressed)
│ ├── e57Root
│ │ ├── formatName = "ASTM E57 3D Imaging Data File"
│ │ ├── guid = "{3F2504E0-4F89-11D3-9A0C-0305E82C3301}"
│ │ ├── versionMajor = 1
│ │ ├── versionMinor = 0
│ │ ├── data3D (array of scan positions)
│ │ │ ├── [0] Scan from tripod position A
│ │ │ │ ├── guid, name, description
│ │ │ │ ├── pose (rotation + translation matrix)
│ │ │ │ ├── acquisitionStart / acquisitionEnd (ISO 8601)
│ │ │ │ ├── sensorVendor, sensorModel, sensorSerialNumber
│ │ │ │ ├── pointCount = 12,847,332
│ │ │ │ └── points → (binary section offset)
│ │ │ └── [1] Scan from tripod position B
│ │ └── images2D (optional panoramic photos)
│ │ └── [0] spherical panoramic image
│ │ ├── guid, name
│ │ └── sphericalRepresentation → (binary blob)
└── Binary Sections (CompressedVector pages)
├── Point data: cartesian XYZ + intensity + RGB + returnIndex
└── Image data: JPEG or PNG blobs
The XML header is always at byte offset 0 of the file, begins with the magic bytes ASTM-E57 in the first 8 bytes of the file header structure, and specifies exact byte offsets into the binary sections for each data block.
Point Data Attributes
Each scan's point cloud can carry a rich set of per-point attributes:
| Attribute | Type | Description |
|---|---|---|
cartesianX, Y, Z |
float64 | Coordinates in scanner or world frame |
sphericalRange |
float64 | Distance from scanner origin (meters) |
sphericalAzimuth |
float64 | Horizontal angle (radians) |
sphericalElevation |
float64 | Vertical angle (radians) |
intensity |
float32 | Laser return intensity (normalized 0–1) |
colorRed, Green, Blue |
uint8 | RGB color (from scanner camera or baked texture) |
returnIndex |
uint8 | Which return (1st, 2nd, last) for multi-return scanners |
timeStamp |
float64 | GPS time of point acquisition |
rowIndex, columnIndex |
int32 | Grid position for structured (panoramic) scans |
isInvalidData |
bool | Marks failed range returns |
The rowIndex/columnIndex attributes are significant: terrestrial scanners produce structured point clouds — every point corresponds to a specific angular position in a regular grid, preserving neighborhood relationships. This is in contrast to airborne LiDAR, where point ordering is often strip-based and unstructured.
Scan Registration and Pose
One of E57's most important features is storing the registration pose — the rigid body transformation (rotation + translation) that maps each scan from its local scanner coordinate system to the global project coordinate system:
<pose type="Structure">
<rotation type="Structure">
<w type="Float">0.9999247</w>
<x type="Float">0.0000000</x>
<y type="Float">0.0122715</y>
<z type="Float">0.0000000</z>
</rotation>
<translation type="Structure">
<x type="Float">15.243</x>
<y type="Float">-3.891</y>
<z type="Float">0.000</z>
</translation>
</pose>
The rotation is stored as a unit quaternion (w, x, y, z). This allows E57-aware software to automatically assemble multi-scan surveys into a coherent registered point cloud without requiring the user to manually align scans.
Reading E57 with Python (pye57)
pye57 wraps the libE57Format C++ library:
import pye57
import numpy as np
# Open an E57 file
e57 = pye57.E57("building_scan.e57")
# Inspect the file header
header = e57.get_header(0) # scan index 0
print(f"Scan name: {header.name}")
print(f"Point count: {header.point_count}")
print(f"Sensor: {header.sensor_vendor} {header.sensor_model}")
# Read points from scan 0
data = e57.read_scan(0, ignore_missing_fields=True)
xyz = np.column_stack([data["cartesianX"],
data["cartesianY"],
data["cartesianZ"]])
print(f"Point cloud shape: {xyz.shape}") # (N, 3)
# Access intensity if present
if "intensity" in data:
intensity = data["intensity"] # normalized float array
# Access color if present
if "colorRed" in data:
rgb = np.column_stack([data["colorRed"],
data["colorGreen"],
data["colorBlue"]])
# Read ALL scans and merge
all_scans = []
for i in range(e57.scan_count):
scan_data = e57.read_scan(i, ignore_missing_fields=True)
pts = np.column_stack([scan_data["cartesianX"],
scan_data["cartesianY"],
scan_data["cartesianZ"]])
all_scans.append(pts)
merged = np.vstack(all_scans)
print(f"Total points across all scans: {len(merged):,}")
Processing E57 with PDAL
PDAL (Point Data Abstraction Library) provides a powerful pipeline interface for E57:
{
"pipeline": [
{
"type": "readers.e57",
"filename": "building_scan.e57",
"scan_index": 0
},
{
"type": "filters.voxeldownsize",
"cell": 0.02
},
{
"type": "writers.las",
"filename": "building_scan_downsampled.las",
"minor_version": 4,
"dataformat_id": 6
}
]
}
pdal pipeline e57_to_las.json
PDAL can read all scans from an E57 file, apply spatial filters (ground classification, statistical outlier removal, voxel downsampling), and write to LAS, LAZ, PLY, or any other supported format.
E57 vs LAS: Choosing the Right Format
| Feature | E57 | LAS/LAZ |
|---|---|---|
| Standard body | ASTM | ASPRS |
| Multiple scans in one file | Yes | No (one file per scan) |
| Embedded panoramic images | Yes | No |
| Scan registration/pose | Built-in | External sidecar files |
| Primary use | Terrestrial/indoor scanning | Airborne LiDAR, geospatial |
| GIS software support | Limited | Excellent |
| Python ecosystem | pye57 | laspy, PDAL |
| Compression | Internal page compression | LAZ (open, excellent ratio) |
| Max point attributes | Flexible schema | Fixed header + VLRS |
E57 is the natural choice when:
- Working with data from FARO, Leica, Matterport, or other terrestrial scanners
- Multi-scan registration and panoramic photos need to be preserved together
- The workflow stays within scanning software (Autodesk ReCap, FARO SCENE, Leica Cyclone)
LAS/LAZ is the natural choice when:
- Working with airborne LiDAR deliverables from survey contractors
- Ingesting data into GIS workflows (QGIS, ArcGIS Pro, PDAL pipelines)
- Sharing with geospatial professionals who expect LAS classification codes
Hardware Sources
Modern scanners that produce E57 natively or via export:
- Leica BLK360 / BLK2GO — compact handheld/tripod scanner, built-in HDR panoramic camera
- FARO Focus Premium/Core — high-speed phase-based scanner, up to 976,000 pts/sec
- Trimble TX8 — long-range time-of-flight, up to 1 million pts/sec
- Matterport Pro3 — consumer-grade hybrid LiDAR + photogrammetry, exports E57 and OBJ
- NavVis VLX / M6 — wearable SLAM scanner for large indoor spaces
Typical File Sizes
| Scan Type | Points | E57 Size |
|---|---|---|
| Small room, 5mm resolution | ~5 million | ~200 MB |
| Single building floor | ~50 million | ~1.5 GB |
| Full building survey (10+ scans) | ~500 million | ~15 GB |
| Large outdoor infrastructure | ~2 billion | ~60 GB |
The embedded JPEG panoramas add 5–20 MB per scan position.
Related conversions
Frequent conversions across the catalogue: