// A is the user object associated with each mask (aka a "label"). persistable sclass G22HashedMasks is IG22SimpleMasksHolder { record noeq Mask(Image2B image) is IG22Mask { settable A label; int hash; public bool equals(O o) { if (o cast G22HashedMasks.Mask) ret hashCode() == o.hashCode() && binaryImagesIdentical(image, o.image); false; } public int hashCode() { if (hash == 0) hash = (int) hashImage2B(image); ret hash; } public Image2B image() { ret image; } } new CompactHashSet masks; // creating a sub-holder *(L> masks) { assertNempty(masks); maskSize(imageSize(first(masks).image())); fOr (mask : masks) this.masks.add(mask); } // same with pre-calculated ghost *(L> masks, G22GhostImage ghost) { this(masks); ghost_cache = ghost; } void addRegion(IImageRegion region, A label) { addRegion(region, ll(label)); } void addRegion(IImageRegion region, A label) { if (empty(labels)) ret; var mask = new Mask(regionToMaskImage(region)); var existingMask = masks.find(mask); if (existingMask != null) { mask = existingMask; mask.label = combineLabels(mask.label, label); } else { mask.label = label; masks.add(mask); } ghost_cache = null; certainty_cache = null; //this.labels.addAll(labels); } public L masks() { ret asList(masks); } /*public LPair maskImagesWithLabels() { ret map(masks(), mask -> pair(mask.image, mask.labels)); }*/ !include early #1035854 // Masks holder Include }