From b8a3963e0c51a93454ce9b6ba5d67cee0f1e43d9 Mon Sep 17 00:00:00 2001 From: Taha Date: Mon, 21 Mar 2022 17:01:20 +0100 Subject: [PATCH 01/16] add depth absolute/inverse encoding --- aloscene/depth.py | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/aloscene/depth.py b/aloscene/depth.py index 75107971..2cb283a2 100644 --- a/aloscene/depth.py +++ b/aloscene/depth.py @@ -1,6 +1,8 @@ +from logging import warning import matplotlib +from matplotlib.pyplot import sca import torch - +import warnings import aloscene from aloscene import Mask from aloscene.renderer import View @@ -22,18 +24,55 @@ class Depth(aloscene.tensors.SpatialAugmentedTensor): """ @staticmethod - def __new__(cls, x, occlusion: Mask = None, *args, names=("C", "H", "W"), **kwargs): + def __new__( + cls, + x, + occlusion: Mask = None, + is_inverse=False, + scale=None, + shift=None, + *args, + names=("C", "H", "W"), + **kwargs): + if is_inverse and not (shift and scale): + raise AttributeError('inversed depth requires shift and scale arguments') if isinstance(x, str): x = load_depth(x) names = ("C", "H", "W") tensor = super().__new__(cls, x, *args, names=names, **kwargs) tensor.add_child("occlusion", occlusion, align_dim=["B", "T"], mergeable=True) - + tensor.add_property('_scale', scale) + tensor.add_property('_shift', shift) + tensor.add_property('_is_inverse', is_inverse) return tensor def __init__(self, x, *args, **kwargs): super().__init__(x) + def encode_inverse(self, scale: float, shift: float): + """Shift and scales the depth values""" + depth = self.detach().cpu() + if depth._is_inverse: + depth = self.encode_absolute() + depth.add_property('_scale', scale) + depth.add_property('_shift', shift) + depth.add_property('_is_inverse', True) + depth = depth * scale + shift + return 1 / depth + + def encode_absolute(self): + """Undo inverse encoding""" + depth = self.detach().cpu() + if not depth._is_inverse: + warnings.warn('depth already encoded in absolute mode') + return depth + depth = 1 / depth + depth = depth / self.scale - self.shift + depth.add_property('_scale', None) + depth.add_property('_shift', None) + depth.add_property('_is_inverse', False) + return depth + def append_occlusion(self, occlusion: Mask, name: str = None): """Attach an occlusion mask to the depth tensor. From 7471160e0cb97727090215b40f356b2cef62c386 Mon Sep 17 00:00:00 2001 From: Taha Date: Mon, 21 Mar 2022 17:02:29 +0100 Subject: [PATCH 02/16] add squeezed numpy conversion --- aloscene/tensors/augmented_tensor.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/aloscene/tensors/augmented_tensor.py b/aloscene/tensors/augmented_tensor.py index b98a5676..47c1e4ae 100644 --- a/aloscene/tensors/augmented_tensor.py +++ b/aloscene/tensors/augmented_tensor.py @@ -1,7 +1,7 @@ -import aloscene import torch -from typing import * import inspect +import numpy as np +from typing import * class AugmentedTensor(torch.Tensor): @@ -699,6 +699,10 @@ def as_tensor(self): n_tensor.__class__ = torch.Tensor n_tensor.rename_(None) return n_tensor + + def to_squeezed_numpy(self): + """Returns squeezed numpy array""" + return self.squeeze().cpu().detach().numpy().astype(np.float16) def __repr__(self): _str = self.as_tensor().__repr__() From 9c0e3e5a5bbcf3e3f2d46295de430fed55164d5d Mon Sep 17 00:00:00 2001 From: Taha Date: Tue, 22 Mar 2022 10:46:35 +0100 Subject: [PATCH 03/16] change shift and scale to optional --- aloscene/depth.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/aloscene/depth.py b/aloscene/depth.py index 2cb283a2..78aa9f9f 100644 --- a/aloscene/depth.py +++ b/aloscene/depth.py @@ -49,7 +49,10 @@ def __new__( def __init__(self, x, *args, **kwargs): super().__init__(x) - def encode_inverse(self, scale: float, shift: float): + def encode_inverse( + self, + scale: float = 1, + shift: float = 0): """Shift and scales the depth values""" depth = self.detach().cpu() if depth._is_inverse: From 598a492d760fcf4f6b7750c992a0987f13285756 Mon Sep 17 00:00:00 2001 From: Taha Date: Tue, 22 Mar 2022 10:50:37 +0100 Subject: [PATCH 04/16] undo detach and cpu in depth inversion --- aloscene/depth.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aloscene/depth.py b/aloscene/depth.py index 78aa9f9f..7ab969a1 100644 --- a/aloscene/depth.py +++ b/aloscene/depth.py @@ -54,7 +54,7 @@ def encode_inverse( scale: float = 1, shift: float = 0): """Shift and scales the depth values""" - depth = self.detach().cpu() + depth = self if depth._is_inverse: depth = self.encode_absolute() depth.add_property('_scale', scale) @@ -65,7 +65,7 @@ def encode_inverse( def encode_absolute(self): """Undo inverse encoding""" - depth = self.detach().cpu() + depth = self if not depth._is_inverse: warnings.warn('depth already encoded in absolute mode') return depth From b54c6e774aa0f0ea4735d003f89bf8993e2f1a17 Mon Sep 17 00:00:00 2001 From: Taha Date: Tue, 22 Mar 2022 11:28:02 +0100 Subject: [PATCH 05/16] add encoding methods docstrings --- aloscene/depth.py | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/aloscene/depth.py b/aloscene/depth.py index 7ab969a1..d1d811b7 100644 --- a/aloscene/depth.py +++ b/aloscene/depth.py @@ -49,11 +49,25 @@ def __new__( def __init__(self, x, *args, **kwargs): super().__init__(x) - def encode_inverse( - self, - scale: float = 1, - shift: float = 0): - """Shift and scales the depth values""" + def encode_inverse(self, scale=1, shift=0): + """Scales and shifts the inverse depth + + Parameters + ---------- + scale: (: float) + Multiplication factor. Default is 1. + + shift: (: float) + Addition intercept. Default is 0. + + Exemples + ------- + >>> # Create a non inverted depth + >>> depth = aloscene.Depth(np.random.normal((1, 20, 20))) + >>> inverted_depth = depth.encode_inverse(scale=0.03, shift=1) + >>> depth.is_inverse, inverted_depth.is_inverse + >>> False, True + """ depth = self if depth._is_inverse: depth = self.encode_absolute() @@ -64,7 +78,16 @@ def encode_inverse( return 1 / depth def encode_absolute(self): - """Undo inverse encoding""" + """Encodes inverted depth to absolute depth + + Exemples + -------- + >>> # Create an already inverted depth + >>> invert_depth = aloscene.Depth(np.random.normal((1, 20, 20)), scale=0.5, shift=1) + >>> depth = depth.encode_absolute(scale=0.03, shift=1) + >>> depth.is_inverse, inverted_depth.is_inverse + >>> False, True + """ depth = self if not depth._is_inverse: warnings.warn('depth already encoded in absolute mode') From c540f3ab1aaa0c95ebf046f8908d3fc5c1246484 Mon Sep 17 00:00:00 2001 From: Taha Date: Tue, 22 Mar 2022 11:29:54 +0100 Subject: [PATCH 06/16] switch scale and shift to public --- aloscene/depth.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/aloscene/depth.py b/aloscene/depth.py index d1d811b7..bbda2188 100644 --- a/aloscene/depth.py +++ b/aloscene/depth.py @@ -41,9 +41,9 @@ def __new__( names = ("C", "H", "W") tensor = super().__new__(cls, x, *args, names=names, **kwargs) tensor.add_child("occlusion", occlusion, align_dim=["B", "T"], mergeable=True) - tensor.add_property('_scale', scale) - tensor.add_property('_shift', shift) - tensor.add_property('_is_inverse', is_inverse) + tensor.add_property('scale', scale) + tensor.add_property('shift', shift) + tensor.add_property('is_inverse', is_inverse) return tensor def __init__(self, x, *args, **kwargs): @@ -71,9 +71,9 @@ def encode_inverse(self, scale=1, shift=0): depth = self if depth._is_inverse: depth = self.encode_absolute() - depth.add_property('_scale', scale) - depth.add_property('_shift', shift) - depth.add_property('_is_inverse', True) + depth.add_property('scale', scale) + depth.add_property('shift', shift) + depth.add_property('is_inverse', True) depth = depth * scale + shift return 1 / depth From 3c2bb5963e5515eb6d09795eb1e6d3afa73e719b Mon Sep 17 00:00:00 2001 From: Taha Date: Tue, 22 Mar 2022 12:06:31 +0100 Subject: [PATCH 07/16] add Depth docstring --- aloscene/depth.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/aloscene/depth.py b/aloscene/depth.py index bbda2188..c70d646f 100644 --- a/aloscene/depth.py +++ b/aloscene/depth.py @@ -21,6 +21,12 @@ class Depth(aloscene.tensors.SpatialAugmentedTensor): loaded Depth tensor or path to the Depth file from which Depth will be loaded. occlusion : aloscene.Mask Occlusion mask for this Depth map. Default value : None. + is_inverse: bool + Either the depth is already or not inverted. + scale: float + Scale used to to shift depth. Pass this argument only if is_inverse is set to True + shift: float + Intercept used to shift depth. Pass this argument only if is_inverse is set to True """ @staticmethod From 9b943877b465a882c9d5cda123bfdd813fea18f1 Mon Sep 17 00:00:00 2001 From: Taha Date: Tue, 22 Mar 2022 12:10:40 +0100 Subject: [PATCH 08/16] change as_numpy conversion order --- aloscene/tensors/augmented_tensor.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/aloscene/tensors/augmented_tensor.py b/aloscene/tensors/augmented_tensor.py index 47c1e4ae..e7e7c2b8 100644 --- a/aloscene/tensors/augmented_tensor.py +++ b/aloscene/tensors/augmented_tensor.py @@ -700,9 +700,10 @@ def as_tensor(self): n_tensor.rename_(None) return n_tensor - def to_squeezed_numpy(self): + def as_numpy(self, dtype=np.float16): """Returns squeezed numpy array""" - return self.squeeze().cpu().detach().numpy().astype(np.float16) + tensor = self + return np.squeeze(tensor.detach().cpu().numpy()).astype(dtype) def __repr__(self): _str = self.as_tensor().__repr__() From e7447d046166289e22c2fd79d9aece706c185208 Mon Sep 17 00:00:00 2001 From: Taha Date: Tue, 22 Mar 2022 12:53:51 +0100 Subject: [PATCH 09/16] replace add_property with value set --- aloscene/depth.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/aloscene/depth.py b/aloscene/depth.py index c70d646f..dfc52a42 100644 --- a/aloscene/depth.py +++ b/aloscene/depth.py @@ -77,9 +77,9 @@ def encode_inverse(self, scale=1, shift=0): depth = self if depth._is_inverse: depth = self.encode_absolute() - depth.add_property('scale', scale) - depth.add_property('shift', shift) - depth.add_property('is_inverse', True) + depth.scale = scale + depth.shift = shift + depth.is_inverse = True depth = depth * scale + shift return 1 / depth @@ -100,9 +100,9 @@ def encode_absolute(self): return depth depth = 1 / depth depth = depth / self.scale - self.shift - depth.add_property('_scale', None) - depth.add_property('_shift', None) - depth.add_property('_is_inverse', False) + depth.scale = None + depth.shift = None + depth.is_inverse = False return depth def append_occlusion(self, occlusion: Mask, name: str = None): From 715045afb0de606e7b99cc2e340b813984703055 Mon Sep 17 00:00:00 2001 From: Taha Date: Wed, 23 Mar 2022 09:33:51 +0100 Subject: [PATCH 10/16] add as_numpy docstring --- aloscene/tensors/augmented_tensor.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/aloscene/tensors/augmented_tensor.py b/aloscene/tensors/augmented_tensor.py index e7e7c2b8..058ab26c 100644 --- a/aloscene/tensors/augmented_tensor.py +++ b/aloscene/tensors/augmented_tensor.py @@ -701,7 +701,13 @@ def as_tensor(self): return n_tensor def as_numpy(self, dtype=np.float16): - """Returns squeezed numpy array""" + """Returns squeezed numpy array + + Parameters + ---------- + dtype: (: np.dtype) + The output dtype. Default np.float16. + """ tensor = self return np.squeeze(tensor.detach().cpu().numpy()).astype(dtype) From 2cd0fdc3764e26c31ecd7a80c4eb24e8e4dc9d94 Mon Sep 17 00:00:00 2001 From: Taha Date: Wed, 23 Mar 2022 09:35:27 +0100 Subject: [PATCH 11/16] fix: inverse shift and scale order --- aloscene/depth.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aloscene/depth.py b/aloscene/depth.py index dfc52a42..f7b634fe 100644 --- a/aloscene/depth.py +++ b/aloscene/depth.py @@ -75,7 +75,7 @@ def encode_inverse(self, scale=1, shift=0): >>> False, True """ depth = self - if depth._is_inverse: + if depth.is_inverse: depth = self.encode_absolute() depth.scale = scale depth.shift = shift @@ -95,11 +95,11 @@ def encode_absolute(self): >>> False, True """ depth = self - if not depth._is_inverse: + if not depth.is_inverse: warnings.warn('depth already encoded in absolute mode') return depth depth = 1 / depth - depth = depth / self.scale - self.shift + depth = (depth - self.shift) / self.scale depth.scale = None depth.shift = None depth.is_inverse = False From 4d089de8867fa35cca4649f8e81faa3104f188e3 Mon Sep 17 00:00:00 2001 From: Taha Date: Wed, 23 Mar 2022 10:12:26 +0100 Subject: [PATCH 12/16] remove squeeze from as_numpy --- aloscene/tensors/augmented_tensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aloscene/tensors/augmented_tensor.py b/aloscene/tensors/augmented_tensor.py index 058ab26c..a19b3a53 100644 --- a/aloscene/tensors/augmented_tensor.py +++ b/aloscene/tensors/augmented_tensor.py @@ -709,7 +709,7 @@ def as_numpy(self, dtype=np.float16): The output dtype. Default np.float16. """ tensor = self - return np.squeeze(tensor.detach().cpu().numpy()).astype(dtype) + return tensor.detach().cpu().numpy().astype(dtype) def __repr__(self): _str = self.as_tensor().__repr__() From 6a47f463aa1786f03d2d51ea54ae4977b24305ea Mon Sep 17 00:00:00 2001 From: Taha Date: Wed, 23 Mar 2022 14:57:27 +0100 Subject: [PATCH 13/16] refactor: switch invert encoding with absolute --- aloscene/depth.py | 89 ++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/aloscene/depth.py b/aloscene/depth.py index f7b634fe..d3a75f6d 100644 --- a/aloscene/depth.py +++ b/aloscene/depth.py @@ -1,4 +1,5 @@ from logging import warning +from shutil import ExecError import matplotlib from matplotlib.pyplot import sca import torch @@ -21,12 +22,12 @@ class Depth(aloscene.tensors.SpatialAugmentedTensor): loaded Depth tensor or path to the Depth file from which Depth will be loaded. occlusion : aloscene.Mask Occlusion mask for this Depth map. Default value : None. - is_inverse: bool - Either the depth is already or not inverted. + is_bsolute: bool + Either depth values refer to real values or shifted and scaled ones. scale: float - Scale used to to shift depth. Pass this argument only if is_inverse is set to True + Scale used to to shift depth. Pass this argument only if is_bsolute is set to True shift: float - Intercept used to shift depth. Pass this argument only if is_inverse is set to True + Intercept used to shift depth. Pass this argument only if is_bsolute is set to True """ @staticmethod @@ -34,14 +35,16 @@ def __new__( cls, x, occlusion: Mask = None, - is_inverse=False, + is_absolute=False, scale=None, shift=None, *args, names=("C", "H", "W"), **kwargs): - if is_inverse and not (shift and scale): - raise AttributeError('inversed depth requires shift and scale arguments') + if is_absolute and not (shift and scale): + raise AttributeError('absolute depth requires shift and scale arguments') + if not is_absolute and (shift or scale): + raise AttributeError('depth not in inverse state, can not pass scale or shift') if isinstance(x, str): x = load_depth(x) names = ("C", "H", "W") @@ -49,14 +52,35 @@ def __new__( tensor.add_child("occlusion", occlusion, align_dim=["B", "T"], mergeable=True) tensor.add_property('scale', scale) tensor.add_property('shift', shift) - tensor.add_property('is_inverse', is_inverse) + tensor.add_property('is_absolute', is_absolute) return tensor def __init__(self, x, *args, **kwargs): super().__init__(x) - def encode_inverse(self, scale=1, shift=0): - """Scales and shifts the inverse depth + def encode_inverse(self): + """Undo encode_absolute rtansformation + + Exemples + ------- + >>> not_absolute_depth = Depth(torch.ones((1, 1, 1)), is_absolute=False) + >>> absolute_depth = not_absolute_depth.encode_absolute() + >>> undo_depth = absolute_depth.encode_inverse() + >>> (undo_depth == not_absolute_depth).item() + >>> True + """ + depth = self.clone() + if not depth.is_absolute: + raise ExecError('can not inverse depth, already inversed') + depth = 1 / depth + depth = (depth - depth.shift) / depth.scale + depth.scale = None + depth.shift = None + depth.is_absolute = False + return depth + + def encode_absolute(self, scale=1, shift=0): + """Transforms inverted depth to absolute depth Parameters ---------- @@ -65,45 +89,22 @@ def encode_inverse(self, scale=1, shift=0): shift: (: float) Addition intercept. Default is 0. - + Exemples - ------- - >>> # Create a non inverted depth - >>> depth = aloscene.Depth(np.random.normal((1, 20, 20))) - >>> inverted_depth = depth.encode_inverse(scale=0.03, shift=1) - >>> depth.is_inverse, inverted_depth.is_inverse - >>> False, True + -------- + >>> not_absolute_depth = Depth(torch.ones((1, 20, 20)), is_absolute=False) + >>> absolute_depth = not_absolute_depth.encode_absolute() + >>> absolute_depth.is_absolute, not_absolute_depth.is_absolute + >>> True, False """ - depth = self - if depth.is_inverse: - depth = self.encode_absolute() + depth = self.clone() + if depth.is_absolute: + raise ExecError('depth already in absolute state, call encode_inverse first') + depth = depth * scale + shift depth.scale = scale depth.shift = shift - depth.is_inverse = True - depth = depth * scale + shift + depth.is_absolute = True return 1 / depth - - def encode_absolute(self): - """Encodes inverted depth to absolute depth - - Exemples - -------- - >>> # Create an already inverted depth - >>> invert_depth = aloscene.Depth(np.random.normal((1, 20, 20)), scale=0.5, shift=1) - >>> depth = depth.encode_absolute(scale=0.03, shift=1) - >>> depth.is_inverse, inverted_depth.is_inverse - >>> False, True - """ - depth = self - if not depth.is_inverse: - warnings.warn('depth already encoded in absolute mode') - return depth - depth = 1 / depth - depth = (depth - self.shift) / self.scale - depth.scale = None - depth.shift = None - depth.is_inverse = False - return depth def append_occlusion(self, occlusion: Mask, name: str = None): """Attach an occlusion mask to the depth tensor. From 1f488dba825c1e43bf752b361c03b59cb37958e0 Mon Sep 17 00:00:00 2001 From: Taha Date: Thu, 24 Mar 2022 09:18:25 +0100 Subject: [PATCH 14/16] remove clone redundancy --- aloscene/depth.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aloscene/depth.py b/aloscene/depth.py index d3a75f6d..27a50d4b 100644 --- a/aloscene/depth.py +++ b/aloscene/depth.py @@ -69,7 +69,7 @@ def encode_inverse(self): >>> (undo_depth == not_absolute_depth).item() >>> True """ - depth = self.clone() + depth = self if not depth.is_absolute: raise ExecError('can not inverse depth, already inversed') depth = 1 / depth @@ -97,7 +97,7 @@ def encode_absolute(self, scale=1, shift=0): >>> absolute_depth.is_absolute, not_absolute_depth.is_absolute >>> True, False """ - depth = self.clone() + depth = self if depth.is_absolute: raise ExecError('depth already in absolute state, call encode_inverse first') depth = depth * scale + shift From 6621664bb93c16bab6112b41dd2e4dbb9a18f8a7 Mon Sep 17 00:00:00 2001 From: Taha Date: Thu, 24 Mar 2022 10:00:43 +0100 Subject: [PATCH 15/16] fix: division by zero error --- aloscene/depth.py | 1 + 1 file changed, 1 insertion(+) diff --git a/aloscene/depth.py b/aloscene/depth.py index 27a50d4b..690eeec8 100644 --- a/aloscene/depth.py +++ b/aloscene/depth.py @@ -101,6 +101,7 @@ def encode_absolute(self, scale=1, shift=0): if depth.is_absolute: raise ExecError('depth already in absolute state, call encode_inverse first') depth = depth * scale + shift + depth[depth < 1e-8] = 1e-8 depth.scale = scale depth.shift = shift depth.is_absolute = True From eb480893503238c70a83a3ab968be4c8aa63e427 Mon Sep 17 00:00:00 2001 From: Taha Date: Thu, 24 Mar 2022 11:29:04 +0100 Subject: [PATCH 16/16] fix: adapt masking to Depth --- aloscene/depth.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/aloscene/depth.py b/aloscene/depth.py index 690eeec8..c942a5ae 100644 --- a/aloscene/depth.py +++ b/aloscene/depth.py @@ -59,7 +59,7 @@ def __init__(self, x, *args, **kwargs): super().__init__(x) def encode_inverse(self): - """Undo encode_absolute rtansformation + """Undo encode_absolute tansformation Exemples ------- @@ -97,15 +97,15 @@ def encode_absolute(self, scale=1, shift=0): >>> absolute_depth.is_absolute, not_absolute_depth.is_absolute >>> True, False """ - depth = self + depth, names = self.rename(None), self.names if depth.is_absolute: raise ExecError('depth already in absolute state, call encode_inverse first') depth = depth * scale + shift - depth[depth < 1e-8] = 1e-8 + depth[torch.unsqueeze(depth < 1e-8, dim=0)] = 1e-8 depth.scale = scale depth.shift = shift depth.is_absolute = True - return 1 / depth + return (1 / depth).rename(*names) def append_occlusion(self, occlusion: Mask, name: str = None): """Attach an occlusion mask to the depth tensor.