From fdff080f7c9f4c8f89c6bc9e43cd356a3eaa8af3 Mon Sep 17 00:00:00 2001 From: Mark Lieberman Date: Thu, 31 Jul 2025 18:44:33 -0400 Subject: [PATCH] Bounding box improvements --- js/Segments.js | 7 +++++-- js/element/BBoxElement.js | 34 ++++++++++++++++++++++++-------- js/element/BBoxOverlayElement.js | 11 +++++++++-- js/styles.css | 6 +++--- liebs_picker.py | 10 +++++++++- 5 files changed, 52 insertions(+), 16 deletions(-) diff --git a/js/Segments.js b/js/Segments.js index 1fa8faf..679187b 100644 --- a/js/Segments.js +++ b/js/Segments.js @@ -19,12 +19,15 @@ export class Segments extends EventTarget { } } - nextLabel(segn) { + nextLabel(segn, offset = 1) { const labels = this.labels[segn]; // Get the index of the next label in the list of options. let index = labels.indexOf(this.label[segn]); - index = (index === -1) ? 0 : (index + 1) % labels.length; + index = (index === -1) ? 0 : (index + offset) % labels.length; + if (index < 0) { + index = labels.length - 1; + } this.label[segn] = labels[index]; this.dispatchEvent(new CustomEvent('segment-change', { diff --git a/js/element/BBoxElement.js b/js/element/BBoxElement.js index f844e52..eb81fec 100644 --- a/js/element/BBoxElement.js +++ b/js/element/BBoxElement.js @@ -17,21 +17,27 @@ export class BBoxElement extends HTMLElement { label: this.querySelector('.label') }; - const [ height, width ] = size, + const [ imageHeight, imageWidth ] = size, left = bbox[0], top = bbox[1], right = bbox[2], - bottom = bbox[3]; + bottom = bbox[3], + height = bottom - top, + width = right - left; - this.style.left = `${(left / width) * 100}%`; - this.style.top = `${(top / height) * 100}%`; - this.style.width = `${((right - left) / width) * 100}%`; - this.style.height = `${((bottom - top) / height) * 100}%`; + this.style.left = `${(left / imageWidth) * 100}%`; + this.style.top = `${(top / imageHeight) * 100}%`; + this.style.width = `${(width / imageWidth) * 100}%`; + this.style.height = `${(height / imageHeight) * 100}%`; + + // Ensure that smaller boxes are placed on top of larger boxes. + this.style.zIndex = Math.round(2147483647 - (height * width)); // Send clicks to the overlay element. - this.addEventListener('click', event => { - this.dispatchEvent(new CustomEvent('bbox-click', { + this.addEventListener('mousedown', event => { + this.dispatchEvent(new CustomEvent('bbox-mousedown', { detail: { + button: event.button, element: this, segn } @@ -40,6 +46,18 @@ export class BBoxElement extends HTMLElement { event.preventDefault(); event.stopPropagation(); }); + + // Prevent clicks from propagating. + this.addEventListener('click', event => { + event.preventDefault(); + event.stopPropagation(); + }); + + // Prevent the context menu from being display. + this.addEventListener('contextmenu', event => { + event.preventDefault(); + event.stopPropagation(); + }); } setLabel(value) { diff --git a/js/element/BBoxOverlayElement.js b/js/element/BBoxOverlayElement.js index 8e0217f..2b6bd3c 100644 --- a/js/element/BBoxOverlayElement.js +++ b/js/element/BBoxOverlayElement.js @@ -35,7 +35,7 @@ export class BBoxOverlayElement extends HTMLElement { label = this.segments.label[segn]; const bboxElement = new BBoxElement(segn, sizes, bbox); - bboxElement.addEventListener('bbox-click', this.bboxClickHandler); + bboxElement.addEventListener('bbox-mousedown', this.bboxClickHandler); bboxElement.setLabel(label); this.el.bboxes.push(bboxElement); @@ -51,7 +51,14 @@ export class BBoxOverlayElement extends HTMLElement { onBBoxClick(event) { const detail = event.detail; - this.segments.nextLabel(detail.segn); + switch (detail.button) { + case 0: + this.segments.nextLabel(detail.segn, 1); + break; + case 2: + this.segments.nextLabel(detail.segn, -1); + break; + } } } diff --git a/js/styles.css b/js/styles.css index ad35642..7e2b9b6 100644 --- a/js/styles.css +++ b/js/styles.css @@ -204,7 +204,7 @@ liebs-picker-bbox { display: flex; justify-content: center; - align-items: flex-start; + align-items: flex-start; color: #0F0; background-color: rgba(0,128,0,0.2); @@ -225,8 +225,8 @@ liebs-picker-image[data-unwanted="yes"] liebs-picker-bbox { } liebs-picker-bbox > .label { - position: relative; - top: -24px; + position: absolute; + bottom: 4px; white-space: nowrap; background-color: rgba(0,128,0,0.8); } diff --git a/liebs_picker.py b/liebs_picker.py index 92c8c84..1cfc767 100644 --- a/liebs_picker.py +++ b/liebs_picker.py @@ -62,6 +62,14 @@ class LiebsPickerSEGS(PreviewImage): """ Collect segment information for the fronend to visualize. """ + def get_bbox(bbox): + return ([ + getattr(bbox[0], "tolist", lambda: bbox[0])(), + getattr(bbox[1], "tolist", lambda: bbox[1])(), + getattr(bbox[2], "tolist", lambda: bbox[2])(), + getattr(bbox[3], "tolist", lambda: bbox[3])(), + ]) + segs_info = [] if len(segs[1]) > 0: for i, seg in enumerate(segs[1]): @@ -71,7 +79,7 @@ class LiebsPickerSEGS(PreviewImage): segs_info.append({ "size": segs[0], - "bbox": seg.bbox.tolist(), + "bbox": get_bbox(seg.bbox), "label": seg_labels[i % len(seg_labels)] if init_labels[0] and seg_labels is not None and len(seg_labels) > 0 else seg.label, "labels": labels })