Skip to content

Commit

Permalink
Merge pull request #111 from Visual-Behavior/add-node-api
Browse files Browse the repository at this point in the history
Augmented tensor: labels renamed by Child + default args when adding one node
  • Loading branch information
thibo73800 authored Oct 19, 2021
2 parents 3434bdf + 3acd879 commit 0831533
Show file tree
Hide file tree
Showing 11 changed files with 275 additions and 266 deletions.
38 changes: 19 additions & 19 deletions aloscene/bounding_boxes_2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def __new__(
tensor = super().__new__(cls, x, *args, names=names, **kwargs)

# Add label
tensor.add_label("labels", labels, align_dim=["N"], mergeable=True)
tensor.add_child("labels", labels, align_dim=["N"], mergeable=True)

if boxes_format not in BoundingBoxes2D.FORMATS:
raise Exception(
Expand Down Expand Up @@ -139,7 +139,7 @@ def append_labels(self, labels: Labels, name: str = None):
>>> boxes2d.labels["set1"]
>>> boxes2d.labels["set2"]
"""
self._append_label("labels", labels, name)
self._append_child("labels", labels, name)

def xcyc(self) -> BoundingBoxes2D:
"""Get a new BoundingBoxes2D Tensor with boxes following this format:
Expand All @@ -156,17 +156,17 @@ def xcyc(self) -> BoundingBoxes2D:
return tensor
elif tensor.boxes_format == "xyxy":
# Convert from xyxy to xcyc
labels = tensor.drop_labels()
labels = tensor.drop_children()
xcyc_boxes = torch.cat(
[tensor[:, :2] + ((tensor[:, 2:] - tensor[:, :2]) / 2), (tensor[:, 2:] - tensor[:, :2])], dim=1
)
xcyc_boxes.boxes_format = "xcyc"
xcyc_boxes.set_labels(labels)
tensor.set_labels(labels)
xcyc_boxes.set_children(labels)
tensor.set_children(labels)
return xcyc_boxes
elif tensor.boxes_format == "yxyx":
# Convert from yxyx to xcyc
labels = tensor.drop_labels()
labels = tensor.drop_children()
tensor = tensor.rename_(None)
xcyc_boxes = torch.cat(
[
Expand All @@ -178,8 +178,8 @@ def xcyc(self) -> BoundingBoxes2D:
tensor.reset_names()
xcyc_boxes.reset_names()
xcyc_boxes.boxes_format = "xcyc"
xcyc_boxes.set_labels(labels)
tensor.set_labels(labels)
xcyc_boxes.set_children(labels)
tensor.set_children(labels)
return xcyc_boxes
else:
raise Exception(f"BoundingBoxes2D:Do not know mapping from {tensor.boxes_format} to xcyc")
Expand All @@ -196,24 +196,24 @@ def xyxy(self) -> BoundingBoxes2D:
tensor = self.clone()

if tensor.boxes_format == "xcyc":
labels = tensor.drop_labels()
labels = tensor.drop_children()
# Convert from xcyc to xyxy
n_tensor = torch.cat([tensor[:, :2] - (tensor[:, 2:] / 2), tensor[:, :2] + (tensor[:, 2:] / 2)], dim=1,)
n_tensor.boxes_format = "xyxy"
n_tensor.set_labels(labels)
n_tensor.set_children(labels)
return n_tensor
elif tensor.boxes_format == "xyxy":
return tensor
elif tensor.boxes_format == "yxyx":
labels = tensor.drop_labels()
labels = tensor.drop_children()
tensor.rename_(None)
# Convert from yxyx to xyxy
n_tensor = torch.cat([tensor[:, :2].flip([1]), tensor[:, 2:].flip([1])], dim=1,)
tensor.reset_names()
n_tensor.reset_names()
n_tensor.boxes_format = "xyxy"
n_tensor.set_labels(labels)
tensor.set_labels(labels)
n_tensor.set_children(labels)
tensor.set_children(labels)
return n_tensor
else:
raise Exception(f"BoundingBoxes2D:Do not know mapping from {tensor.boxes_format} to xyxy")
Expand All @@ -230,7 +230,7 @@ def yxyx(self) -> BoundingBoxes2D:
tensor = self.clone()

if tensor.boxes_format == "xcyc":
labels = tensor.drop_labels()
labels = tensor.drop_children()
tensor.rename_(None)
# Convert from xcyc to yxyx
yxyx_boxes = torch.cat(
Expand All @@ -243,19 +243,19 @@ def yxyx(self) -> BoundingBoxes2D:
yxyx_boxes.reset_names()
tensor.reset_names()
yxyx_boxes.boxes_format = "yxyx"
yxyx_boxes.set_labels(labels)
tensor.set_labels(labels)
yxyx_boxes.set_children(labels)
tensor.set_children(labels)
return yxyx_boxes
elif tensor.boxes_format == "xyxy":
labels = tensor.drop_labels()
labels = tensor.drop_children()
tensor.rename_(None)
# Convert from xyxy to yxyx
yxyx_boxes = torch.cat([tensor[:, :2].flip([1]), tensor[:, 2:].flip([1])], dim=1,)
yxyx_boxes.reset_names()
tensor.reset_names()
yxyx_boxes.boxes_format = "yxyx"
yxyx_boxes.set_labels(labels)
tensor.set_labels(labels)
yxyx_boxes.set_children(labels)
tensor.set_children(labels)
return yxyx_boxes
elif tensor.boxes_format == "yxyx":
return tensor
Expand Down
2 changes: 1 addition & 1 deletion aloscene/bounding_boxes_3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class BoundingBoxes3D(aloscene.tensors.AugmentedTensor):
def __new__(cls, x, labels: Union[dict, Labels] = None, names=("N", None), *args, **kwargs):
tensor = super().__new__(cls, x, *args, names=names, **kwargs)
assert tensor.shape[-1] == 7
tensor.add_label("labels", labels, align_dim=["N"], mergeable=True)
tensor.add_child("labels", labels, align_dim=["N"], mergeable=True)
return tensor

def __init__(self, x, *args, **kwargs):
Expand Down
8 changes: 4 additions & 4 deletions aloscene/disparity.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def __new__(
x = load_disp(x, png_negate)
names = ("C", "H", "W")
tensor = super().__new__(cls, x, *args, names=names, **kwargs)
tensor.add_label("occlusion", occlusion, align_dim=["B", "T"], mergeable=True)
tensor.add_child("occlusion", occlusion, align_dim=["B", "T"], mergeable=True)
tensor.add_property("disp_format", disp_format)
tensor.add_property("camera_side", camera_side)
return tensor
Expand All @@ -65,7 +65,7 @@ def append_occlusion(self, occlusion: Mask, name: str = None):
If none, the occlusion mask will be attached without name (if possible). Otherwise if no other unnamed
occlusion mask are attached to the frame, the mask will be added to the set of mask.
"""
self._append_label("occlusion", occlusion, name)
self._append_child("occlusion", occlusion, name)

def __get_view__(self, min_disp=None, max_disp=None, cmap="nipy_spectral", reverse=False):
assert all(dim not in self.names for dim in ["B", "T"]), "disparity should not have batch or time dimension"
Expand Down Expand Up @@ -99,9 +99,9 @@ def _resize(self, size, **kwargs):
W_new = disp_resized.W
# rescale disparity
sl_x = disp_resized.get_slices({"C": 0})
labels = disp_resized.drop_labels()
labels = disp_resized.drop_children()
disp_resized[sl_x] = disp_resized[sl_x] * W_new / W_old
disp_resized.set_labels(labels)
disp_resized.set_children(labels)
return disp_resized

def _hflip(self, **kwargs):
Expand Down
16 changes: 8 additions & 8 deletions aloscene/flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def __new__(cls, x, occlusion: Mask = None, *args, names=("C", "H", "W"), **kwar
x = load_flow(x)
names = ("C", "H", "W")
tensor = super().__new__(cls, x, *args, names=names, **kwargs)
tensor.add_label("occlusion", occlusion, align_dim=["B", "T"], mergeable=True)
tensor.add_child("occlusion", occlusion, align_dim=["B", "T"], mergeable=True)
return tensor

def __init__(self, x, *args, **kwargs):
Expand All @@ -40,7 +40,7 @@ def append_occlusion(self, occlusion: Mask, name: str = None):
If none, the occlusion mask will be attached without name (if possible). Otherwise if no other unnamed
occlusion mask are attached to the frame, the mask will be added to the set of mask.
"""
self._append_label("occlusion", occlusion, name)
self._append_child("occlusion", occlusion, name)

def __get_view__(self, clip_flow=None, convert_to_bgr=False, magnitude_max=None):
assert all(dim not in self.names for dim in ["B", "T"]), "flow should not have batch or time dimension"
Expand Down Expand Up @@ -68,10 +68,10 @@ def _resize(self, size, **kwargs):
# scale flow coordinates because they are expressed in pixel units
sl_x = flow_resized.get_slices({"C": 0}) # slice for x coord. of flow vector
sl_y = flow_resized.get_slices({"C": 1}) # slice for y coord. of flow vector
labels = flow_resized.drop_labels()
labels = flow_resized.drop_children()
flow_resized[sl_x] = flow_resized[sl_x] * W_new / W_old
flow_resized[sl_y] = flow_resized[sl_y] * H_new / H_old
flow_resized.set_labels(labels)
flow_resized.set_children(labels)
return flow_resized

def _hflip(self, **kwargs):
Expand All @@ -84,10 +84,10 @@ def _hflip(self, **kwargs):
"""
flow_flipped = super()._hflip(**kwargs)
# invert x axis of flow vector
labels = flow_flipped.drop_labels()
labels = flow_flipped.drop_children()
sl_x = flow_flipped.get_slices({"C": 0})
flow_flipped[sl_x] = -1 * flow_flipped[sl_x]
flow_flipped.set_labels(labels)
flow_flipped.set_children(labels)
return flow_flipped

def _vflip(self, **kwargs):
Expand All @@ -100,8 +100,8 @@ def _vflip(self, **kwargs):
"""
flow_flipped = super()._vflip(**kwargs)
# invert y axis of flow vector
labels = flow_flipped.drop_labels()
labels = flow_flipped.drop_children()
sl_y = flow_flipped.get_slices({"C": 1})
flow_flipped[sl_y] = -1 * flow_flipped[sl_y]
flow_flipped.set_labels(labels)
flow_flipped.set_children(labels)
return flow_flipped
30 changes: 15 additions & 15 deletions aloscene/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,13 @@ def __new__(
tensor = super().__new__(cls, x, *args, names=names, **kwargs)

# Add label
tensor.add_label("points2d", points2d, align_dim=["B", "T"], mergeable=False)
tensor.add_label("boxes2d", boxes2d, align_dim=["B", "T"], mergeable=False)
tensor.add_label("boxes3d", boxes3d, align_dim=["B", "T"], mergeable=False)
tensor.add_label("flow", flow, align_dim=["B", "T"], mergeable=False)
tensor.add_label("disparity", disparity, align_dim=["B", "T"], mergeable=True)
tensor.add_label("segmentation", segmentation, align_dim=["B", "T"], mergeable=False)
tensor.add_label("labels", labels, align_dim=["B", "T"], mergeable=True)
tensor.add_child("points2d", points2d, align_dim=["B", "T"], mergeable=False)
tensor.add_child("boxes2d", boxes2d, align_dim=["B", "T"], mergeable=False)
tensor.add_child("boxes3d", boxes3d, align_dim=["B", "T"], mergeable=False)
tensor.add_child("flow", flow, align_dim=["B", "T"], mergeable=False)
tensor.add_child("disparity", disparity, align_dim=["B", "T"], mergeable=True)
tensor.add_child("segmentation", segmentation, align_dim=["B", "T"], mergeable=False)
tensor.add_child("labels", labels, align_dim=["B", "T"], mergeable=True)

# Add other tensor property
tensor.add_property("normalization", normalization)
Expand Down Expand Up @@ -147,7 +147,7 @@ def append_labels(self, labels: Labels, name: str = None):
>> labels = aloscene.Labels([42])
>> frame.append_labels(labels)
"""
self._append_label("labels", labels, name)
self._append_child("labels", labels, name)

def append_boxes2d(self, boxes: BoundingBoxes2D, name: str = None):
"""Attach a set of BoundingBoxes2D to the frame.
Expand All @@ -172,7 +172,7 @@ def append_boxes2d(self, boxes: BoundingBoxes2D, name: str = None):
>>> boxes2d = aloscene.BoundingBoxes2D([[0.5, 0.5, 0.5, 0.5]], boxes_format="xcyc", absolute=False)
>>> frame.append_boxes2d(boxes2d, "boxes_set")
"""
self._append_label("boxes2d", boxes, name)
self._append_child("boxes2d", boxes, name)

def append_points2d(self, points: Points2D, name: str = None):
"""Attach a set of points to the frame.
Expand All @@ -185,7 +185,7 @@ def append_points2d(self, points: Points2D, name: str = None):
If None, the points will be attached without name (if possible). Otherwise if no other unnamed
points are attached to the frame, the points will be added to the set of points.
"""
self._append_label("points2d", points, name)
self._append_child("points2d", points, name)

def append_boxes3d(self, boxes_3d: BoundingBoxes3D, name: str = None):
"""Attach BoundingBoxes3D to the frame
Expand All @@ -209,7 +209,7 @@ def append_boxes3d(self, boxes_3d: BoundingBoxes3D, name: str = None):
>>> We append to boxes3D twice because the frame has a temporal dimension (T=2)
>>> frame.append_boxes3d([boxes3d, boxes3d], "my_set")
"""
self._append_label("boxes3d", boxes_3d, name)
self._append_child("boxes3d", boxes_3d, name)

def append_flow(self, flow, name=None):
"""Attach a flow to the frame.
Expand All @@ -228,7 +228,7 @@ def append_flow(self, flow, name=None):
>>> flow = aloscene.Flow(np.zeros((2, frame.H, frame.W)))
>>> frame.append_flow(flow)
"""
self._append_label("flow", flow, name)
self._append_child("flow", flow, name)

def append_disparity(self, disparity, name=None):
"""Attach a disparity map to the frame.
Expand All @@ -247,7 +247,7 @@ def append_disparity(self, disparity, name=None):
>>> disparity = aloscene.Disparity(np.zeros((1, frame.H, frame.W)))
>>> frame.append_disparity(disparity)
"""
self._append_label("disparity", disparity, name)
self._append_child("disparity", disparity, name)

def append_segmentation(self, segmentation: Mask, name: str = None):
"""Attach a segmentation to the frame.
Expand All @@ -261,7 +261,7 @@ def append_segmentation(self, segmentation: Mask, name: str = None):
If none, the mask will be attached without name (if possible). Otherwise if no other unnamed
mask are attached to the frame, the mask will be added to the set of mask.
"""
self._append_label("segmentation", segmentation, name)
self._append_child("segmentation", segmentation, name)

@staticmethod
def _get_mean_std_tensor(shape, names, mean_std: tuple, device="cpu"):
Expand Down Expand Up @@ -485,7 +485,7 @@ def _pad(self, offset_y: tuple, offset_x: tuple, value=0, **kwargs):

# Create a new frame with the same parameters and set back a copy of the previous labels
n_tensor = type(self)(n_tensor, normalization=self.normalization, mean_std=self.mean_std, names=self.names)
n_tensor.set_labels(self.clone().get_labels())
n_tensor.set_children(self.clone().get_children())
return n_tensor
else:
raise Exception("This normalziation {} is not handle by the frame _pad method".format(self.normalization))
Expand Down
2 changes: 1 addition & 1 deletion aloscene/labels.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def __new__(

if scores is not None:
assert scores.shape == tensor.shape
tensor.add_label("scores", scores, align_dim=["N"], mergeable=True)
tensor.add_child("scores", scores, align_dim=["N"], mergeable=True)

return tensor

Expand Down
8 changes: 4 additions & 4 deletions aloscene/mask.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def __new__(cls, x, labels: Union[dict, Labels] = None, *args, **kwargs):
x = load_mask(x)
kwargs["names"] = ("N", "H", "W")
tensor = super().__new__(cls, x, *args, **kwargs)
tensor.add_label("labels", labels, align_dim=["N"], mergeable=True)
tensor.add_child("labels", labels, align_dim=["N"], mergeable=True)
return tensor

def append_labels(self, labels: Labels, name: str = None):
Expand All @@ -43,7 +43,7 @@ def append_labels(self, labels: Labels, name: str = None):
If none, the label will be attached without name (if possible). Otherwise if no other unnamed
labels are attached to the frame, the labels will be added to the set of labels.
"""
self._append_label("labels", labels, name)
self._append_child("labels", labels, name)

def iou_with(self, mask2) -> torch.Tensor:
""" IoU calculation between mask2 and itself
Expand Down Expand Up @@ -172,7 +172,7 @@ def mask2id(self, labels_set: str = None, return_ann: bool = False, return_cats:
frame = self.cpu().rename(None).permute([1, 2, 0]).detach().contiguous().numpy()

# Try to retrieve the associated label ID (if any)
labels = self._get_set_labels(labels_set=labels_set)
labels = self._get_set_children(labels_set=labels_set)
annotations = []
if hasattr(self, "labels") and self.labels is not None and len(labels) > 0:
assert len(labels) == len(self) # Required to make panoptic view
Expand Down Expand Up @@ -201,7 +201,7 @@ def mask2id(self, labels_set: str = None, return_ann: bool = False, return_cats:
return frame, annotations
return frame

def _get_set_labels(self, labels_set: str = None):
def _get_set_children(self, labels_set: str = None):
if not (labels_set is None or isinstance(self.labels, dict)):
raise Exception(
f"Trying to display a set of labels ({labels_set}) while masks do not have multiple set of labels"
Expand Down
4 changes: 2 additions & 2 deletions aloscene/oriented_boxes_2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def __new__(

assert x.shape[-1] == 5, "The last dimension should be [x, y, w, h, theta]"
# Add label
tensor.add_label("labels", labels, align_dim=["N"], mergeable=True)
tensor.add_child("labels", labels, align_dim=["N"], mergeable=True)

tensor.add_property("absolute", absolute)
tensor.add_property("frame_size", frame_size)
Expand Down Expand Up @@ -64,7 +64,7 @@ def append_labels(self, labels: Labels, name: str = None):
If none, the label will be attached without name (if possible). Otherwise if no other unnamed
labels are attached to the frame, the labels will be added to the set of labels.
"""
self._append_label("labels", labels, name)
self._append_child("labels", labels, name)

def corners(self) -> torch.Tensor:
"""Get corners in x, y coordinates
Expand Down
4 changes: 2 additions & 2 deletions aloscene/points_2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def __new__(
tensor = super().__new__(cls, x, *args, names=names, **kwargs)

# Add label
tensor.add_label("labels", labels, align_dim=["N"], mergeable=True)
tensor.add_child("labels", labels, align_dim=["N"], mergeable=True)

tensor.add_property("points_format", points_format)
tensor.add_property("absolute", absolute)
Expand Down Expand Up @@ -143,7 +143,7 @@ def append_labels(self, labels: Labels, name: str = None):
>>> pts2d.labels["set1"]
>>> pts2d.labels["set2"]
"""
self._append_label("labels", labels, name)
self._append_child("labels", labels, name)

def xy(self) -> Points2D:
"""Get a new Point2d Tensor with points following this format:
Expand Down
Loading

0 comments on commit 0831533

Please sign in to comment.