Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
c0b4e20
Add interactive segmentation, text query, and stereo (desktop)
mattdawkins Apr 29, 2026
b6c7561
Multi-polygon support with holes
mattdawkins Apr 29, 2026
d17b9ba
Fix runtime error
mattdawkins Jan 8, 2026
43d5dda
Re-compute lengths when stereo lines changed
mattdawkins May 25, 2026
1e0b103
Consolidate stereo and segmentation interactives into same process
mattdawkins May 26, 2026
21fd3ac
Support better segmentation initialization
mattdawkins May 27, 2026
e1348e5
Remove text-query annotation button (moved to dev/text-query-annot-bu…
mattdawkins Jun 21, 2026
20303f0
Remove native video playback wiring (NativeVideoAnnotator)
mattdawkins Jun 22, 2026
e160436
Restore missing <template> tag in desktop ViewerLoader
mattdawkins Jun 22, 2026
1752ee0
remove bundle.css, it makes no sense to be added
BryonLewis Jun 23, 2026
3f1be78
remove redundant styles
BryonLewis Jun 23, 2026
e971b3d
fix ipc undefined reference error, pass through calibration file
BryonLewis Jun 23, 2026
00e4243
fix polygonSegmentation key and edit layer emit
BryonLewis Jun 23, 2026
eb7788f
proper undo on reset stereo segementation
BryonLewis Jun 23, 2026
19f904f
update initialize to handle segInitialized properly
BryonLewis Jun 23, 2026
867c36d
minor updates
BryonLewis Jun 23, 2026
9f47439
gate interactive stereo to desktop mode only
BryonLewis Jun 23, 2026
8b43516
handle loading errors
BryonLewis Jun 23, 2026
a60cdcd
linting
BryonLewis Jun 23, 2026
2f8c9f0
Merge remote-tracking branch 'origin/main' into dev/add-interactive-s…
BryonLewis Jun 23, 2026
fc3db67
Merge branch 'main' into dev/add-interactive-seg-and-stereo
BryonLewis Jun 24, 2026
e486105
guard segmentation to only desktop mode
BryonLewis Jun 24, 2026
a34869e
Spawn a new detection per click in continuous segmentation mode
mattdawkins Jun 25, 2026
80a08b0
Fix stereo track ID race and re-arm recipe on Point re-edit
mattdawkins Jun 25, 2026
7dbe9c2
Remove empty detections left when nothing is drawn
mattdawkins Jun 25, 2026
570355b
Skip recipe confirm when nothing is pending
mattdawkins Jun 25, 2026
443b3fe
Finalize in-progress shape when starting a new detection
mattdawkins Jun 25, 2026
e0a95b7
Don't spawn a new detection on background segmentation clicks
mattdawkins Jun 25, 2026
9263f09
Restore prior polygon on segmentation reset
mattdawkins Jun 25, 2026
2200c0e
Send frame time from the segmentation recipe for video support
mattdawkins Jun 25, 2026
dc14336
add interactive stereo to bottomSideBar
BryonLewis Jun 25, 2026
b1a8b1a
Fix interactive stereo line-transfer hang and renderer crashes
mattdawkins Jun 25, 2026
14c476f
Add build:electron:dir npm script for unpacked desktop build
mattdawkins Jun 25, 2026
1863d7b
Make stereo-warped lines standard editable line annotations
mattdawkins Jun 25, 2026
da899f9
Lock human-edited stereo lines from auto re-warping
mattdawkins Jun 25, 2026
57198fa
Cap line annotation box aspect ratio at 6:1
mattdawkins Jun 25, 2026
75469cb
One-click cross-camera detection select/edit in multicam
mattdawkins Jun 25, 2026
8b8549e
Seamless new-detection creation on any camera in multicam
mattdawkins Jun 25, 2026
438fb10
Stereo: key auto-created head/tail lines under HeadTailLineKey
mattdawkins Jun 26, 2026
223136a
Stereo: split interactive toggle into length-update and auto-compute
mattdawkins Jun 26, 2026
5fd320e
add support for running in dev:electron mode with stereo and segmenta…
BryonLewis Jun 27, 2026
1a7a10f
loading indicator if segmentation takes too long
BryonLewis Jun 27, 2026
cab95c1
segmentation instructions
BryonLewis Jun 27, 2026
12851de
editing icons for types, loading indicator for segmentation
BryonLewis Jun 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions client/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ node_modules
/dist
/dist_desktop
/dist_electron
/coverage
/.electron
/lib
/bin
Expand Down
92 changes: 92 additions & 0 deletions client/dive-common/apispec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,98 @@ function useApi() {
return use<Readonly<Api>>(ApiSymbol);
}

/**
* Interactive Segmentation Types
*/
export interface SegmentationPredictRequest {
/** Path to the image file */
imagePath: string;
/** Point coordinates as [x, y] pairs */
points: [number, number][];
/** Point labels: 1 for foreground, 0 for background */
pointLabels: number[];
/** Optional low-res mask from previous prediction for refinement */
maskInput?: number[][];
/** Whether to return multiple mask options */
multimaskOutput?: boolean;
/** Time in seconds when imagePath is a video file */
frameTime?: number;
}

export interface SegmentationPredictResponse {
/** Whether the prediction succeeded */
success: boolean;
/** Error message if failed */
error?: string;
/** Polygon coordinates as [x, y] pairs */
polygon?: [number, number][];
/** Bounding box [x_min, y_min, x_max, y_max] */
bounds?: [number, number, number, number];
/** Quality score from segmentation model */
score?: number;
/** Low-res mask for subsequent refinement */
lowResMask?: number[][];
/** Mask dimensions [height, width] */
maskShape?: [number, number];
/** RLE-encoded full-resolution mask for display: [[value, count], ...] */
rleMask?: [number, number][];
}

/**
* Stereo point-segmentation. The segmentation service warps the seed to the
* other camera (configured stereo backend), segments there, and -- when enabled
* -- derives head/tail lines + the measurement.
*/
export interface SegmentationStereoSegmentRequest {
/** The already-segmented source-camera polygon (sampling + measurement). */
polygon?: [number, number][];
/** Source-camera click points and labels. */
points: [number, number][];
pointLabels: number[];
/** Source (clicked) and other camera image/video paths. */
sourceImagePath: string;
otherImagePath: string;
/** Calibration file path, read by the embedded stereo warper. */
calibrationFile?: string;
/** Time in seconds when the paths are video files. */
frameTime?: number;
}

export interface SegmentationStereoSegmentResponse {
id: string;
success: boolean;
error?: string;
/** Other-camera polygon from SAM. */
polygon?: [number, number][];
bounds?: [number, number, number, number];
score?: number;
/** Seed point(s) used on the other camera (median of warped samples). */
seedPoints?: [number, number][];
seedLabels?: number[];
/** Optional head/tail lines: source = clicked camera, other = warped. */
generateLine?: boolean;
lineSource?: [[number, number], [number, number]];
lineOther?: [[number, number], [number, number]];
/** Stereo measurement for the derived line (calibration units, e.g. mm). */
measurement?: {
length: number;
midpoint_x: number;
midpoint_y: number;
midpoint_z: number;
midpoint_range: number;
stereo_rms: number;
};
}

export interface SegmentationStatusResponse {
/** Whether segmentation is available */
available: boolean;
/** Whether the model is currently loaded */
loaded?: boolean;
/** Whether the service is ready for predictions */
ready?: boolean;
}

export {
provideApi,
useApi,
Expand Down
6 changes: 5 additions & 1 deletion client/dive-common/components/BottomPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export default defineComponent({
addAttribute: { type: Function, required: true },
editAttribute: { type: Function, required: true },
saveThreshold: { type: Function, required: true },
isStereoDataset: { type: Boolean, default: false },
},
setup() {
return { context };
Expand Down Expand Up @@ -106,7 +107,10 @@ export default defineComponent({
@track-seek="aggregateSeek($event)"
>
<template slot="settings">
<TrackSettingsPanel :all-types="trackFilters.allTypes.value" />
<TrackSettingsPanel
:all-types="trackFilters.allTypes.value"
:is-stereo-dataset="isStereoDataset"
/>
</template>
<template slot="column-settings">
<TrackListColumnSettings
Expand Down
125 changes: 104 additions & 21 deletions client/dive-common/components/DeleteControls.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,20 @@ export default Vue.extend({
if (this.editingMode === 'rectangle') {
return true; // deleting rectangle is unsupported
}
if (this.editingMode === 'Point') {
return true; // Point mode uses reset instead of delete
}
return false;
},
isPolygonMode(): boolean {
return this.editingMode === 'Polygon';
},
editModeIcon(): string {
if (this.editingMode === 'Polygon') return 'mdi-vector-polygon';
if (this.editingMode === 'LineString') return 'mdi-vector-line';
if (this.editingMode === 'rectangle') return 'mdi-vector-square';
return 'mdi-shape';
},
},

methods: {
Expand All @@ -39,33 +51,104 @@ export default Vue.extend({
this.$emit('delete-annotation');
}
},
addHole() {
this.$emit('add-hole');
},
addPolygon() {
this.$emit('add-polygon');
},
},
});
</script>

<template>
<span class="mx-1">
<v-btn
<span class="mx-1 d-flex align-center">
<!-- Add Polygon button - shown in polygon edit mode -->
<v-tooltip
v-if="isPolygonMode"
bottom
>
<template #activator="{ on, attrs }">
<v-btn
v-bind="attrs"
color="primary"
depressed
small
class="mr-1"
v-on="on"
@click="addPolygon"
>
<v-icon small>
mdi-vector-polygon
</v-icon>
<v-icon
x-small
class="ml-n1"
>
mdi-plus-circle-outline
</v-icon>
</v-btn>
</template>
<span>Add another polygon</span>
</v-tooltip>

<!-- Add Hole button - shown in polygon edit mode -->
<v-tooltip
v-if="isPolygonMode"
bottom
>
<template #activator="{ on, attrs }">
<v-btn
v-bind="attrs"
color="primary"
depressed
small
class="mr-1"
v-on="on"
@click="addHole"
>
<v-icon small>
mdi-vector-polygon
</v-icon>
<v-icon
x-small
class="ml-n1"
>
mdi-minus-circle-outline
</v-icon>
</v-btn>
</template>
<span>Add hole to polygon</span>
</v-tooltip>

<!-- Delete button -->
<v-tooltip
v-if="!disabled"
color="error"
depressed
small
@click="deleteSelected"
bottom
>
<pre class="mr-1 text-body-2">del</pre>
<span v-if="selectedFeatureHandle >= 0">
point {{ selectedFeatureHandle }}
</span>
<span v-else-if="editingMode">
{{ editingMode }}
</span>
<span v-else>unselected</span>
<v-icon
small
class="ml-2"
>
mdi-delete
</v-icon>
</v-btn>
<template #activator="{ on, attrs }">
<v-btn
v-bind="attrs"
color="error"
depressed
small
v-on="on"
@click="deleteSelected"
>
<span class="mr-1 text-body-2 font-weight-bold">DEL</span>
<span v-if="selectedFeatureHandle >= 0">
pt{{ selectedFeatureHandle }}
</span>
<v-icon
v-else
small
>
{{ editModeIcon }}
</v-icon>
</v-btn>
</template>
<span v-if="selectedFeatureHandle >= 0">Delete point {{ selectedFeatureHandle }}</span>
<span v-else-if="editingMode">Delete {{ editingMode }}</span>
</v-tooltip>
</span>
</template>
Loading
Loading