Add rasterize-lidar tool

This commit is contained in:
Florent Guiotte 2021-02-18 16:29:14 +01:00
parent 74be7c1a56
commit a370d17dd5
3 changed files with 130 additions and 1 deletions

View File

@ -208,7 +208,7 @@ def rasterize(pc_file, feature='elevation', resolution=1.,
vxl = bin(grid, pc.spatial, fval, bin_method)
squash_method = squash_method if isinstance(squash_method, tuple) else (squash_method,)
squash_method = squash_method if not isinstance(squash_method, str) else (squash_method,)
rasters = []
for s in squash_method:

30
idefix/tools/config.json Normal file
View File

@ -0,0 +1,30 @@
{
"global": {
"resolution": 1,
"interpolation": "idw",
"out_dir": "./results"
},
"rasters": [
{
"feature": "elevation",
"bin_structure": "voxel",
"bin_method": "mean",
"squash_method": ["top", "bottom", "std"]
},
{
"feature": "elevation",
"bin_structure": "pixel",
"bin_method": "mean"
},
{
"bin_structure": "pixel",
"bin_method": "density"
},
{
"feature": "num_returns",
"bin_structure": "pixel",
"bin_method": "mode"
}
]
}

99
idefix/tools/rasterize-lidar.py Executable file
View File

@ -0,0 +1,99 @@
#!/usr/bin/env python
# file rasterize-lidar.py
# author Florent Guiotte <florent.guiotte@irisa.fr>
# version 0.0
# date 18 févr. 2021
"""Create raster of LiDAR features.
Use npz point clouds from Idefix.
"""
import json
import argparse
from multiprocessing import Pool
from tqdm.auto import tqdm
from pathlib import Path
import idefix as ix
parser = argparse.ArgumentParser(description='Compute features rasters from LiDAR point cloud.',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
The config file can contain any parameters of the
idefix.helpers.rasterize function in a json file.
You can define 'global' parameters (for all the rasters) and raster
specific parameters in a list 'rasters'.
See the following `config.json` example file:
{
"global": {
"resolution": 5,
"interpolation": "idw",
"out_dir": "./results"
},
"rasters": [
{
"feature": "elevation",
"bin_structure": "voxel",
"bin_method": "mean",
"squash_method": ["top", "bottom", "std"]
},
{
"feature": "elevation",
"bin_structure": "pixel",
"bin_method": "mean"
},
{
"bin_structure": "pixel",
"bin_method": "density"
},
{
"feature": "num_returns",
"bin_structure": "pixel",
"bin_method": "mode"
}
]
}
""")
parser.add_argument('-c', '--config', type=str, help='json file to setup the rasterization processes', dest='c')
parser.add_argument('-n', '--nprocess', type=int, help='number of child processes to use', default=1, dest='n')
parser.add_argument('in_dir', type=str, help='the path to the point cloud directory')
parser.add_argument('out_dir', type=str, help='path to output raster results')
args = parser.parse_args()
def _map_rasterize(kwargs):
return ix.helpers.rasterize(**kwargs)
def main():
in_dir = Path(args.in_dir)
out_dir = Path(args.out_dir)
out_dir.mkdir(exist_ok=True)
pc_files = list(in_dir.glob('*.npz'))
config = {'global': {'out_dir': out_dir}}
config |= json.load(open(args.c)) if args.c else {}
globalc = config['global']
rasters = config['rasters'] if 'rasters' in config else [{}]
queue = []
for pc_file in pc_files:
for raster in rasters:
job = globalc.copy()
job |= raster
job |= {'pc_file': pc_file}
queue += [job]
pool = Pool(processes=args.n)
for _ in tqdm(pool.imap_unordered(_map_rasterize, queue), total=len(queue)):
pass
if __name__ == '__main__':
main()