Change default behavior of get_grid

This commit is contained in:
Florent Guiotte 2021-02-16 16:18:00 +01:00
parent ae0308374c
commit a21598eb74
4 changed files with 73 additions and 11 deletions

View File

@ -55,5 +55,42 @@ def bbox(data):
[[xmin, ymin, zmin],
[xmax, ymax, zmax]]
See Also
--------
fit_bbox : Return a bounding box fit on fixed coordinates.
"""
return np.array((np.min(data, axis=0), np.max(data, axis=0)))
def fit_bbox(data, decimals=0):
"""Return a bounding box fit on fixed coordinates.
- Round $x$ and $y$ coordinates to match most orthoimagery tiles.
- Ceil and floor $z$ coordinates to include all the point on the vertical axis.
Parameters
----------
data : ndarray (N, 3)
Bbox or point cloud data of shape (N, 3), i.e. (x,y,z).
decimals : int
The precision for the rounding, ceiling and flooring operations.
Returns
-------
bbox : ndarray
Lower and upper points describing the bounding box such as::
[[xmin, ymin, zmin],
[xmax, ymax, zmax]]
See Also
--------
bbox : Returns a raw bounding box on the data.
"""
bbox = bbox(data)
nbbox = np.round(bbox, decimals)
nbbox[0,2] = np.floor(bbox * 10 ** decimals)[0,2] / 10 ** decimals
nbbox[1,2] = np.ceil(bbox * 10 ** decimals)[1,2] / 10 ** decimals
return nbbox

View File

@ -11,7 +11,7 @@ General functions to transform point clouds to voxels compatible with numpy.
import logging
import numpy as np
import humanize
from .utils import bbox
from .utils import bbox, fit_bbox
log = logging.getLogger(__name__)
@ -38,8 +38,8 @@ def _ui_step(step, spatial):
def get_grid(spatial, step):
'''Return grid bins.
Compute the grid bins of a point cloud or the corresponding bounding box
according to given step (or steps for anisotropic grid).
Compute the grid bins of a point cloud or the corresponding bounding
box according to given step (or steps for anisotropic grid).
Parameters
----------
@ -54,8 +54,26 @@ def get_grid(spatial, step):
Returns
-------
grid : array of array (n,)
Grid of spatial given step. Return three arrays (not necessarily of the
same size) defining the bins of axis `x`, `y` and `z`.
Grid of spatial given step. Return three arrays (not necessarily
of the same size) defining the bins of axis `x`, `y` and `z`.
Notes
-----
The grid is built considering the half-open interval
$[min_of_the_axis, max_of_the_axis)$. If the positions of the points
are directly used as spatial parameter, the points at the upper
limits will be excluded from further processing.
You can define a more precise bounding box to take into account all
the points of your dataset (e.g. by adding a small distance on the
upper limits).
See Also
--------
bbox : Returns the raw bounding box of the point cloud (excluding
points on upper limit).
fit_bbox : Returns a bounding box on rounded coordinates (can
include all the points).
'''
spatial = np.array(spatial)
bb = bbox(spatial)
@ -65,7 +83,7 @@ def get_grid(spatial, step):
for a_min, a_max, a_s in zip(bb[0], bb[1], step):
# Beware of float underflow
if a_s:
bins = np.trunc((a_max - a_min) / a_s).astype(int) + 1
bins = np.trunc((a_max - a_min) / a_s).astype(int)
grid += [np.linspace(a_min, a_min + bins * a_s, bins + 1)]
else:
grid += [np.array((a_min, a_max + 1))]

View File

@ -86,7 +86,14 @@ def test_get_grid(datadir, set_id, step, grid_id):
assert res is not None, 'Test data empty, test function is broken!'
assert len(res) == 3, 'Test data malformed, test function is broken!'
test = vxl.get_grid(spatial, step)
bbox = vxl.bbox(spatial)
try:
bbox[1,:] += step * 1.01
except:
# Workaround for the None on last axis
bbox[1,:] += step[0]
test = vxl.get_grid(bbox, step)
assert test is not None, 'Function did not return anything :('
assert len(test) == 3, 'Function doesn\'t give right number of axis'

View File

@ -1,3 +1,3 @@
1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0
1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0
1.0 11.0
1.0 12.0