Compute Occlusion Between Objects#

When objects overlap in an image, compute which parts are visible and how much is occluded.

Occlusion fraction#

Given an object’s full mask and what’s blocking it:

# Full extent of the object (if nothing was in front)
instance_mask = ...

# Mask of everything in front of this object
occluder_mask = ...

# Visible portion
visible_mask = instance_mask - occluder_mask

# Fraction occluded
if instance_mask.area() > 0:
    occ_fraction = 1 - visible_mask.area() / instance_mask.area()
else:
    occ_fraction = 1.0

Layer multiple objects#

When processing objects sorted by depth (back to front):

objects = sorted(objects, key=lambda o: o.depth, reverse=True)

occluder_mask = RLEMask.zeros(image_shape)

for obj in objects:
    # Visible = full mask minus occluders
    obj.visible_mask = obj.instance_mask - occluder_mask

    # Bounding box of visible portion
    obj.visible_bbox = obj.visible_mask.bbox()

    # This object now occludes things behind it
    occluder_mask |= obj.instance_mask

Check if point is occluded#

point = (x, y)

# Check if point is in the visible region
is_visible = visible_mask[point[1], point[0]]

Occlusion between two specific objects#

# Overlap between object A and B
overlap = mask_a & mask_b

# If A is in front of B, this much of B is hidden by A
b_hidden_by_a = overlap.area()

# Fraction of B occluded by A
b_occ_by_a = b_hidden_by_a / mask_b.area() if mask_b.area() > 0 else 0