This repository has been archived by the owner on Mar 30, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
las2vola.py
executable file
·121 lines (98 loc) · 3.91 KB
/
las2vola.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/usr/bin/env python3
"""
Las2vola: Converts Las files into VOLA format.
The ISPRS las format is the standard for LIDAR devices and stores information
on the points obtained. This parser uses the las information
for the nbit per voxel representation. The data stored is: color, height,
number of returns, intensity and classification
@author Jonathan Byrne & Anton Shmatov
@copyright 2018 Intel Ltd (see LICENSE file).
"""
from __future__ import print_function
import glob
import os
import numpy as np
import binutils as bu
from laspy import file as lasfile
from laspy.util import LaspyException
from volatree import VolaTree
def main():
"""Read the file, build the tree. Write a Binary."""
start_time = bu.timer()
parser = bu.parser_args("*.las / *.laz")
args = parser.parse_args()
# Parse directories or filenames, whichever you want!
if os.path.isdir(args.input):
filenames = glob.glob(os.path.join(args.input, '*.laz'))
filenames.extend(glob.glob(os.path.join(args.input, '*.las')))
else:
filenames = glob.glob(args.input)
print("processing: ", ' '.join(filenames))
for filename in filenames:
if args.dense:
outfilename = bu.sub(filename, "dvol")
else:
outfilename = bu.sub(filename, "vol")
if os.path.isfile(outfilename):
print("File already exists!")
continue
print("converting", filename, "to", outfilename)
bbox, points, pointsdata = parse_las(filename, args.nbits)
# work out how many chunks are required for the data
if args.nbits:
print("nbits set, adding metadata to occupancy grid")
div, mod = divmod(len(pointsdata[0]), 8)
if mod > 0:
nbits = div + 1
else:
nbits = div
else:
print("Only occupancy data being set! Use -n flag to add metadata")
nbits = 0
if len(points) > 0:
volatree = VolaTree(args.depth, bbox, args.crs,
args.dense, nbits)
volatree.cubify(points, pointsdata)
volatree.writebin(outfilename)
bu.print_ratio(filename, outfilename)
else:
print("The las file is empty!")
bu.timer(start_time)
def parse_las(filename, nbits):
"""Read las format point data and return header and points."""
pointfile = lasfile.File(filename, mode='r')
header = pointfile.header
maxheight = header.max[2]
points = np.array((pointfile.x, pointfile.y, pointfile.z)).transpose() # get all points, change matrix orientation
pointsdata = np.zeros((len(pointfile), 7), dtype=np.int)
if nbits > 0: # if want to set other data, find in matrices
try:
red = pointfile.red
except LaspyException:
red = [0] * len(points)
try:
green = pointfile.green
except LaspyException:
green = [0] * len(points)
try:
blue = pointfile.blue
except LaspyException:
blue = [0] * len(points)
coldata = np.int64(np.array([red, green, blue]).transpose() / 256)
scaleddata = np.array([pointfile.get_z(), pointfile.get_num_returns(),
pointfile.intensity, pointfile.raw_classification], dtype='int64').transpose()
min = np.array([0, 1, 0, 0])
max = np.array([maxheight, 7, 1000, 31])
normdata = np.int64(bu.normalize_np(scaleddata, min, max) * 255)
coldata[(coldata[:, 0] == 0) & (coldata[:, 1] == 0) &
(coldata[:, 2] == 0)] = 200 # if all three colours are 0, set to 200
pointsdata = np.concatenate([coldata, normdata], axis=1)
if len(points) == 0:
return [], [], None
bbox = [points.min(axis=0).tolist(), points.max(axis=0).tolist()]
if nbits:
return bbox, points, pointsdata
else:
return bbox, points, None
if __name__ == '__main__':
main()