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], [[xmin, ymin, zmin],
[xmax, ymax, zmax]] [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))) 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 logging
import numpy as np import numpy as np
import humanize import humanize
from .utils import bbox from .utils import bbox, fit_bbox
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -38,8 +38,8 @@ def _ui_step(step, spatial):
def get_grid(spatial, step): def get_grid(spatial, step):
'''Return grid bins. '''Return grid bins.
Compute the grid bins of a point cloud or the corresponding bounding box Compute the grid bins of a point cloud or the corresponding bounding
according to given step (or steps for anisotropic grid). box according to given step (or steps for anisotropic grid).
Parameters Parameters
---------- ----------
@ -54,8 +54,26 @@ def get_grid(spatial, step):
Returns Returns
------- -------
grid : array of array (n,) grid : array of array (n,)
Grid of spatial given step. Return three arrays (not necessarily of the Grid of spatial given step. Return three arrays (not necessarily
same size) defining the bins of axis `x`, `y` and `z`. 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) spatial = np.array(spatial)
bb = bbox(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): for a_min, a_max, a_s in zip(bb[0], bb[1], step):
# Beware of float underflow # Beware of float underflow
if a_s: 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)] grid += [np.linspace(a_min, a_min + bins * a_s, bins + 1)]
else: else:
grid += [np.array((a_min, a_max + 1))] 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 res is not None, 'Test data empty, test function is broken!'
assert len(res) == 3, 'Test data malformed, 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 test is not None, 'Function did not return anything :('
assert len(test) == 3, 'Function doesn\'t give right number of axis' 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 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