From 8abd806d7abba0978fc617d16c03e122659dffe5 Mon Sep 17 00:00:00 2001 From: brimoor Date: Fri, 24 May 2024 18:57:57 -0400 Subject: [PATCH] adding padding option --- fiftyone/utils/utils3d.py | 40 +++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/fiftyone/utils/utils3d.py b/fiftyone/utils/utils3d.py index 388f092033..4e252bb373 100644 --- a/fiftyone/utils/utils3d.py +++ b/fiftyone/utils/utils3d.py @@ -535,6 +535,7 @@ def compute_orthographic_projection_images( subsampling_rate=None, projection_normal=None, bounds=None, + padding=None, skip_failures=False, progress=None, ): @@ -600,6 +601,11 @@ def compute_orthographic_projection_images( to generate each map. Either element of the tuple or any/all of its values can be None, in which case a tight crop of the point cloud along the missing dimension(s) are used + padding (None): a relative padding(s) in ``[0, 1]]`` to apply to the + field of view bounds prior to projection. Can either be a single + value to apply in all directions or a ``[padx, pady, padz]``. For + example, pass ``padding=0.05`` with no ``bounds`` to project onto + a tight crop of each point cloud with 5% padding around it skip_failures (False): whether to gracefully continue without raising an error if a projection fails progress (None): whether to render a progress bar (True/False), use the @@ -647,6 +653,7 @@ def compute_orthographic_projection_images( subsampling_rate=subsampling_rate, projection_normal=projection_normal, bounds=bounds, + padding=padding, ) except Exception as e: if not skip_failures: @@ -680,6 +687,7 @@ def compute_orthographic_projection_image( subsampling_rate=None, projection_normal=None, bounds=None, + padding=None, ): """Generates an orthographic projection image for the given PCD file onto the specified plane (default xy plane). @@ -714,6 +722,11 @@ def compute_orthographic_projection_image( the projected plane. Either element of the tuple or any/all of its values can be None, in which case a tight crop of the point cloud along the missing dimension(s) are used + padding (None): a relative padding(s) in ``[0, 1]]`` to apply to the + field of view bounds prior to projection. Can either be a single + value to apply in all directions or a ``[padx, pady, padz]``. For + example, pass ``padding=0.05`` with no ``bounds`` to project onto + a tight crop of the point cloud with 5% padding around it Returns: a tuple of @@ -731,6 +744,7 @@ def compute_orthographic_projection_image( filepath, size=size, bounds=bounds, + padding=padding, projection_normal=projection_normal, subsampling_rate=subsampling_rate, ) @@ -828,6 +842,7 @@ def _parse_point_cloud( filepath, size=None, bounds=None, + padding=None, projection_normal=None, subsampling_rate=None, ): @@ -876,19 +891,24 @@ def _parse_point_cloud( _max_bound = pc.get_max_bound() max_bound = _fill_none(max_bound, _max_bound) + min_bound = np.asarray(min_bound, dtype=float) + max_bound = np.asarray(max_bound, dtype=float) + + if padding is not None: + pad = 0.5 * np.asarray(padding) * (max_bound - min_bound) + min_bound -= pad + max_bound += pad + # Ensure bbox will not have 0 volume by adding a small value if max_bound - # and min_bound are close to each other - delta = np.isclose( - np.asarray(max_bound) - np.asarray(min_bound), 0 - ) * np.repeat(0.000001, 3) - max_bound += delta + # and min_bound are close to each other + max_bound += 1e-6 * np.isclose(max_bound - min_bound, 0) bbox = o3d.geometry.AxisAlignedBoundingBox( min_bound=min_bound, max_bound=max_bound ) - # crop bounds and translate so that min bound is at the origin - pc = pc.crop(bbox).translate((-min_bound[0], -min_bound[1], -min_bound[2])) + # Crop bounds and translate so that min bound is at the origin + pc = pc.crop(bbox).translate(-min_bound) if subsampling_rate is not None and subsampling_rate > 0: pc = pc.uniform_down_sample(subsampling_rate) @@ -902,9 +922,9 @@ def _parse_point_cloud( width, height = None, None metadata = OrthographicProjectionMetadata( - min_bound=min_bound, - max_bound=max_bound, - normal=projection_normal, + min_bound=list(min_bound), + max_bound=list(max_bound), + normal=list(projection_normal), width=width, height=height, )