// A is the user object associated with each mask (aka a "label")
sclass G22HashedMasks {
record noeq Mask(Image2B image, A label) is IG22Mask {
int hash, count;
public int hashCode() {
if (hash == 0)
hash = (int) hashImage2B(image);
ret hash;
}
public Image2B image() { ret image; }
public A label() { ret label; }
}
new Map masks;
void addRegion(IImageRegion region, A label) {
var mask = new Mask(regionToMaskImage(region), label);
var existingMask = masks.get(mask.hashCode());
if (existingMask != null) {
labels.remove(existingMask.label);
existingMask.label = combineLabels(existingMask.label, mask.label);
mask = existingMask;
} else
masks.put(mask.hashCode(), mask);
ghost_cache = null;
certainty_cache = null;
labels.add(mask.label);
mask.count++;
}
swappable A combineLabels(A a, A b) {
if (a == null) ret b;
if (b == null) ret a;
if (eq(a, b)) ret a;
fail("Label conflict: " + a + " / " + b);
}
L masks() { ret valuesList(masks); }
!include early #1035854 // Masks holder Include
}