twanghcmut's picture
download
raw
2.56 kB
import numpy as np
from scipy.ndimage import binary_erosion, distance_transform_edt
def boundary(mask):
return mask & ~binary_erosion(mask)
class MaskLoss:
def __init__(self, masks, weights):
self.masks = np.asarray(masks, dtype=bool)
self.weights = np.asarray(weights, dtype=float)
if self.masks.ndim != 4 or self.weights.shape != self.masks.shape[:2]:
raise ValueError(
"Masks must be (objects, frames, height, width) with matching weights"
)
if (
not np.isfinite(self.weights).all()
or (self.weights < 0).any()
or not self.weights.any()
):
raise ValueError("Mask weights must be finite, nonnegative and nonzero")
self.boundaries = np.asarray(
[[boundary(mask) for mask in track] for track in self.masks]
)
self.distances = np.asarray(
[
[distance_transform_edt(~edge) for edge in track]
for track in self.boundaries
]
)
self.diagonal = np.linalg.norm(self.masks.shape[-2:])
def __call__(self, predictions):
predictions = np.asarray(predictions, dtype=bool)
if predictions.shape != self.masks.shape:
raise ValueError("Predicted and target mask shapes must match")
values = np.zeros(self.weights.shape)
for object_id, frame in np.argwhere(self.weights > 0):
target, prediction = (
self.masks[object_id, frame],
predictions[object_id, frame],
)
intersection = np.count_nonzero(target & prediction)
union = np.count_nonzero(target | prediction)
overlap = intersection / union if union else 1.0
target_edge, predicted_edge = (
self.boundaries[object_id, frame],
boundary(prediction),
)
if target_edge.any() and predicted_edge.any():
distance = (
self.distances[object_id, frame][predicted_edge].mean()
+ distance_transform_edt(~predicted_edge)[target_edge].mean()
) / (2 * self.diagonal)
else:
distance = float(target_edge.any() != predicted_edge.any())
values[object_id, frame] = 1 - overlap + 0.25 * distance
totals = self.weights.sum(axis=1)
per_object = (values * self.weights).sum(axis=1) / np.maximum(totals, 1e-12)
return float(per_object[totals > 0].mean())

Xet Storage Details

Size:
2.56 kB
·
Xet hash:
2dcc720eb8a2270f96a86b18cda47a7487be18ef69c8db6f1eafe83c83eccaf9

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.