@jax-data-science/sci-image-visualizer 0.2.12 → 0.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/index.mjs +2 -1
- package/esm2022/lib/contracts/instance-segmenter.contract.mjs +1 -1
- package/esm2022/lib/toolbar/segmentation/yolo-detect-tool.service.mjs +180 -0
- package/esm2022/lib/toolbar/toolbar.component.mjs +31 -3
- package/esm2022/lib/visualizer.component.mjs +78 -20
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-ci1q0xnJ.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-iPNL2JyC.mjs} +2 -2
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-ci1q0xnJ.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-iPNL2JyC.mjs.map} +1 -1
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +485 -230
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
- package/index.d.ts +1 -0
- package/lib/contracts/instance-segmenter.contract.d.ts +11 -0
- package/lib/toolbar/segmentation/yolo-detect-tool.service.d.ts +49 -0
- package/lib/toolbar/toolbar.component.d.ts +15 -1
- package/lib/visualizer.component.d.ts +27 -2
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export * from './lib/contracts/cell-segmenter.contract';
|
|
|
24
24
|
export { CellposeSegmenterService } from './lib/toolbar/segmentation/cellpose-segmenter.service';
|
|
25
25
|
export * from './lib/contracts/instance-segmenter.contract';
|
|
26
26
|
export { YoloSegmenterService } from './lib/toolbar/segmentation/yolo-segmenter.service';
|
|
27
|
+
export { YoloDetectToolService } from './lib/toolbar/segmentation/yolo-detect-tool.service';
|
|
27
28
|
export { ProcessingImage } from './lib/processing/processing-image';
|
|
28
29
|
export { cropImage, CropImageOptions } from './lib/processing/image-crop';
|
|
29
30
|
export { ImageConverterService } from './lib/processing/image-converter.service';
|
|
@@ -52,6 +52,17 @@ export interface InstanceSegmentation {
|
|
|
52
52
|
export interface InstanceSegmentOptions {
|
|
53
53
|
/** Which registered model to run. Defaults to the registry's default. */
|
|
54
54
|
modelId?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Scale to run at, as a divisor of full resolution — the same meaning the
|
|
57
|
+
* server gives it.
|
|
58
|
+
*
|
|
59
|
+
* This is what puts objects at the size the checkpoint was trained on, and it
|
|
60
|
+
* matters more than any threshold: run a detector at the wrong object scale
|
|
61
|
+
* and it finds nothing. A caller that can re-crop the source (a tile-backed
|
|
62
|
+
* viewer) should honour it rather than accepting whatever the display happens
|
|
63
|
+
* to show.
|
|
64
|
+
*/
|
|
65
|
+
downsamplingFactor?: number;
|
|
55
66
|
/** Minimum detection confidence, per tile. */
|
|
56
67
|
confidence?: number;
|
|
57
68
|
/** NMS IoU within a single tile. */
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { BehaviorSubject } from 'rxjs';
|
|
2
|
+
import { type TileAccessPort } from '../../contracts/ports/tile-access.port';
|
|
3
|
+
import type { IVisualizer } from '../../contracts/visualizer.contract';
|
|
4
|
+
import type { IInstanceSegmenter, InstanceSegmentOptions } from '../../contracts/instance-segmenter.contract';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
/**
|
|
7
|
+
* YOLO object detection over the current view.
|
|
8
|
+
*
|
|
9
|
+
* The complement to {@link CellSegmentToolService}: cellpose auto-segments cells
|
|
10
|
+
* inside a box you draw, whereas a detector is meant to find objects across a
|
|
11
|
+
* field. So this takes no prompt — it runs on whatever is on screen and turns
|
|
12
|
+
* every detection into a region.
|
|
13
|
+
*
|
|
14
|
+
* Detections come back in the displayed image's pixels; they are mapped onto
|
|
15
|
+
* the full-resolution image through the viewer's own source rect, so the regions
|
|
16
|
+
* land where the objects actually are rather than at view-local coordinates.
|
|
17
|
+
*
|
|
18
|
+
* Exposes the same `status$` / `busy$` / `progress$` surface as the cellpose
|
|
19
|
+
* tool so the host's shared segmentation toast drives it unchanged.
|
|
20
|
+
*/
|
|
21
|
+
export declare class YoloDetectToolService {
|
|
22
|
+
/** Server-side crop, so detection can run at the model's scale rather than
|
|
23
|
+
* the viewer's. Optional: without it the tool falls back to the displayed
|
|
24
|
+
* pixels, which is correct but scale-dependent. */
|
|
25
|
+
private tileAccess;
|
|
26
|
+
readonly status$: BehaviorSubject<string>;
|
|
27
|
+
readonly busy$: BehaviorSubject<boolean>;
|
|
28
|
+
readonly progress$: BehaviorSubject<number>;
|
|
29
|
+
constructor(
|
|
30
|
+
/** Server-side crop, so detection can run at the model's scale rather than
|
|
31
|
+
* the viewer's. Optional: without it the tool falls back to the displayed
|
|
32
|
+
* pixels, which is correct but scale-dependent. */
|
|
33
|
+
tileAccess?: TileAccessPort | null);
|
|
34
|
+
/**
|
|
35
|
+
* Detect in the current view and append the results as regions.
|
|
36
|
+
*
|
|
37
|
+
* @returns the number of regions added.
|
|
38
|
+
*/
|
|
39
|
+
detectInView(viz: IVisualizer, segmenter: IInstanceSegmenter, opts?: InstanceSegmentOptions): Promise<number>;
|
|
40
|
+
/**
|
|
41
|
+
* Re-crop `rect` at `1/target` of full resolution. Returns null on any
|
|
42
|
+
* failure, so the caller falls back to the displayed pixels — a coarser crop
|
|
43
|
+
* beats a failed run.
|
|
44
|
+
*/
|
|
45
|
+
private fetchCropAtScale;
|
|
46
|
+
private makeRegion;
|
|
47
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<YoloDetectToolService, [{ optional: true; }]>;
|
|
48
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<YoloDetectToolService>;
|
|
49
|
+
}
|
|
@@ -66,6 +66,12 @@ export declare class ToolbarComponent implements OnChanges {
|
|
|
66
66
|
label: string;
|
|
67
67
|
}[];
|
|
68
68
|
samModelId: string;
|
|
69
|
+
/** YOLO checkpoints offered by the host's registry, and the active one. */
|
|
70
|
+
yoloModels: {
|
|
71
|
+
id: string;
|
|
72
|
+
label: string;
|
|
73
|
+
}[];
|
|
74
|
+
yoloModelId: string;
|
|
69
75
|
selectPlotType: EventEmitter<PlotType>;
|
|
70
76
|
/** Intensity (LINE) mode: add another colored line ROI + inset trace. */
|
|
71
77
|
addProfileLine: EventEmitter<void>;
|
|
@@ -105,6 +111,12 @@ export declare class ToolbarComponent implements OnChanges {
|
|
|
105
111
|
segmentRegions: EventEmitter<void>;
|
|
106
112
|
/** Run cellpose-SAM (auto) inside each drawn rectangle's crop (jit-ui#90). */
|
|
107
113
|
segmentCellpose: EventEmitter<void>;
|
|
114
|
+
/** Run YOLO detection over the current view. */
|
|
115
|
+
detectYolo: EventEmitter<void>;
|
|
116
|
+
/** Pick the YOLO checkpoint. */
|
|
117
|
+
yoloModelChange: EventEmitter<string>;
|
|
118
|
+
/** Open the YOLO parameter dialog. */
|
|
119
|
+
openYoloParams: EventEmitter<void>;
|
|
108
120
|
/** SAM model picker (jit-ui#90 P1). */
|
|
109
121
|
samModelChange: EventEmitter<string>;
|
|
110
122
|
wandSensitivityChange: EventEmitter<number | undefined>;
|
|
@@ -133,6 +145,8 @@ export declare class ToolbarComponent implements OnChanges {
|
|
|
133
145
|
* every change-detection tick, which makes the bound `p-menu` overlay rebuild
|
|
134
146
|
* its DOM mid-interaction and swallow the click on a menu item. */
|
|
135
147
|
samMenuItems: MenuItem[];
|
|
148
|
+
/** Same stable-array reasoning as {@link samMenuItems}. */
|
|
149
|
+
yoloMenuItems: MenuItem[];
|
|
136
150
|
/** Rebuild the SAM model menu when the model list or active selection
|
|
137
151
|
* changes (keeps the array reference stable across other CD ticks). */
|
|
138
152
|
ngOnChanges(changes: SimpleChanges): void;
|
|
@@ -163,5 +177,5 @@ export declare class ToolbarComponent implements OnChanges {
|
|
|
163
177
|
get isIntensityCapable(): boolean;
|
|
164
178
|
showHelp(): void;
|
|
165
179
|
static ɵfac: i0.ɵɵFactoryDeclaration<ToolbarComponent, never>;
|
|
166
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<ToolbarComponent, "plotting-toolbar", never, { "imageInfo": { "alias": "imageInfo"; "required": false; }; "plotTypeOptions": { "alias": "plotTypeOptions"; "required": false; }; "selectedPlotType": { "alias": "selectedPlotType"; "required": false; }; "isoRange": { "alias": "isoRange"; "required": false; }; "maxIndex": { "alias": "maxIndex"; "required": false; }; "zIndex": { "alias": "zIndex"; "required": false; }; "isHeatmap": { "alias": "isHeatmap"; "required": false; }; "activeDragMode": { "alias": "activeDragMode"; "required": false; }; "activeSurface3dMode": { "alias": "activeSurface3dMode"; "required": false; }; "axesVisible": { "alias": "axesVisible"; "required": false; }; "wireframeActive": { "alias": "wireframeActive"; "required": false; }; "resolutionScale": { "alias": "resolutionScale"; "required": false; }; "wandSensitivity": { "alias": "wandSensitivity"; "required": false; }; "brushSize": { "alias": "brushSize"; "required": false; }; "vertexEraserRadius": { "alias": "vertexEraserRadius"; "required": false; }; "canUndo": { "alias": "canUndo"; "required": false; }; "canRedo": { "alias": "canRedo"; "required": false; }; "stackOptions": { "alias": "stackOptions"; "required": false; }; "tools": { "alias": "tools"; "required": false; }; "imageSmoothingEnabled": { "alias": "imageSmoothingEnabled"; "required": false; }; "samModels": { "alias": "samModels"; "required": false; }; "samModelId": { "alias": "samModelId"; "required": false; }; }, { "selectPlotType": "selectPlotType"; "addProfileLine": "addProfileLine"; "toggleImageSmoothing": "toggleImageSmoothing"; "isoRangeChange": "isoRangeChange"; "openChannelHistogram": "openChannelHistogram"; "openRegionEditor": "openRegionEditor"; "selectStackOption": "selectStackOption"; "zScrub": "zScrub"; "zSlide": "zSlide"; "zIndexInput": "zIndexInput"; "reloadAndPlot": "reloadAndPlot"; "downloadImage": "downloadImage"; "autoscaleImage": "autoscaleImage"; "toggleDragMode": "toggleDragMode"; "zoomIn": "zoomIn"; "zoomOut": "zoomOut"; "toggleSurface3dMode": "toggleSurface3dMode"; "resetSurfaceCamera": "resetSurfaceCamera"; "toggleAxes": "toggleAxes"; "toggleWireframe": "toggleWireframe"; "selectResolution": "selectResolution"; "deleteRegion": "deleteRegion"; "undoRegion": "undoRegion"; "redoRegion": "redoRegion"; "segmentRegions": "segmentRegions"; "segmentCellpose": "segmentCellpose"; "samModelChange": "samModelChange"; "wandSensitivityChange": "wandSensitivityChange"; "brushSizeChange": "brushSizeChange"; "vertexEraserRadiusChange": "vertexEraserRadiusChange"; }, never, ["*"], false, never>;
|
|
180
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ToolbarComponent, "plotting-toolbar", never, { "imageInfo": { "alias": "imageInfo"; "required": false; }; "plotTypeOptions": { "alias": "plotTypeOptions"; "required": false; }; "selectedPlotType": { "alias": "selectedPlotType"; "required": false; }; "isoRange": { "alias": "isoRange"; "required": false; }; "maxIndex": { "alias": "maxIndex"; "required": false; }; "zIndex": { "alias": "zIndex"; "required": false; }; "isHeatmap": { "alias": "isHeatmap"; "required": false; }; "activeDragMode": { "alias": "activeDragMode"; "required": false; }; "activeSurface3dMode": { "alias": "activeSurface3dMode"; "required": false; }; "axesVisible": { "alias": "axesVisible"; "required": false; }; "wireframeActive": { "alias": "wireframeActive"; "required": false; }; "resolutionScale": { "alias": "resolutionScale"; "required": false; }; "wandSensitivity": { "alias": "wandSensitivity"; "required": false; }; "brushSize": { "alias": "brushSize"; "required": false; }; "vertexEraserRadius": { "alias": "vertexEraserRadius"; "required": false; }; "canUndo": { "alias": "canUndo"; "required": false; }; "canRedo": { "alias": "canRedo"; "required": false; }; "stackOptions": { "alias": "stackOptions"; "required": false; }; "tools": { "alias": "tools"; "required": false; }; "imageSmoothingEnabled": { "alias": "imageSmoothingEnabled"; "required": false; }; "samModels": { "alias": "samModels"; "required": false; }; "samModelId": { "alias": "samModelId"; "required": false; }; "yoloModels": { "alias": "yoloModels"; "required": false; }; "yoloModelId": { "alias": "yoloModelId"; "required": false; }; }, { "selectPlotType": "selectPlotType"; "addProfileLine": "addProfileLine"; "toggleImageSmoothing": "toggleImageSmoothing"; "isoRangeChange": "isoRangeChange"; "openChannelHistogram": "openChannelHistogram"; "openRegionEditor": "openRegionEditor"; "selectStackOption": "selectStackOption"; "zScrub": "zScrub"; "zSlide": "zSlide"; "zIndexInput": "zIndexInput"; "reloadAndPlot": "reloadAndPlot"; "downloadImage": "downloadImage"; "autoscaleImage": "autoscaleImage"; "toggleDragMode": "toggleDragMode"; "zoomIn": "zoomIn"; "zoomOut": "zoomOut"; "toggleSurface3dMode": "toggleSurface3dMode"; "resetSurfaceCamera": "resetSurfaceCamera"; "toggleAxes": "toggleAxes"; "toggleWireframe": "toggleWireframe"; "selectResolution": "selectResolution"; "deleteRegion": "deleteRegion"; "undoRegion": "undoRegion"; "redoRegion": "redoRegion"; "segmentRegions": "segmentRegions"; "segmentCellpose": "segmentCellpose"; "detectYolo": "detectYolo"; "yoloModelChange": "yoloModelChange"; "openYoloParams": "openYoloParams"; "samModelChange": "samModelChange"; "wandSensitivityChange": "wandSensitivityChange"; "brushSizeChange": "brushSizeChange"; "vertexEraserRadiusChange": "vertexEraserRadiusChange"; }, never, ["*"], false, never>;
|
|
167
181
|
}
|
|
@@ -12,6 +12,8 @@ import { IVisualizer } from './contracts/visualizer.contract';
|
|
|
12
12
|
import { SamToolService } from './toolbar/segmentation/sam-tool.service';
|
|
13
13
|
import { SamPointToolService } from './toolbar/segmentation/sam-point-tool.service';
|
|
14
14
|
import { CellSegmentToolService } from './toolbar/segmentation/cell-segment-tool.service';
|
|
15
|
+
import { YoloDetectToolService } from './toolbar/segmentation/yolo-detect-tool.service';
|
|
16
|
+
import type { IInstanceSegmenter, InstanceSegmentOptions } from './contracts/instance-segmenter.contract';
|
|
15
17
|
import { ToolbarToolVisibility } from './contracts/toolbar-config';
|
|
16
18
|
import { VizConfig } from './contracts/viz-config';
|
|
17
19
|
import * as i0 from "@angular/core";
|
|
@@ -24,6 +26,8 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
|
|
|
24
26
|
private session;
|
|
25
27
|
private samTool;
|
|
26
28
|
private cellSegmentTool;
|
|
29
|
+
private yoloDetectTool;
|
|
30
|
+
private instanceSegmenter;
|
|
27
31
|
private samPointTool;
|
|
28
32
|
private regionOps;
|
|
29
33
|
private vizConfig?;
|
|
@@ -123,6 +127,16 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
|
|
|
123
127
|
label: string;
|
|
124
128
|
}[];
|
|
125
129
|
samModelId: string;
|
|
130
|
+
/** YOLO checkpoints with a configured URL, and the active one. */
|
|
131
|
+
yoloModels: {
|
|
132
|
+
id: string;
|
|
133
|
+
label: string;
|
|
134
|
+
}[];
|
|
135
|
+
yoloModelId: string;
|
|
136
|
+
/** Parameter dialog state. Seeded from the active model's own defaults, which
|
|
137
|
+
* encode the scale and crowding each checkpoint was trained for. */
|
|
138
|
+
showYoloParams: boolean;
|
|
139
|
+
yoloParams: InstanceSegmentOptions;
|
|
126
140
|
/** SAM download/segment toast state (bound by the `sam` p-toast template). */
|
|
127
141
|
samStatus: string;
|
|
128
142
|
samProgress: number;
|
|
@@ -233,7 +247,7 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
|
|
|
233
247
|
private wheelListener?;
|
|
234
248
|
/** Debounced z-slice scrubbing (see SliceScrubber — refactoring plan Step 7). */
|
|
235
249
|
private readonly scrubber;
|
|
236
|
-
constructor(state: ImageStatePort, plotService: IVisualizer, messageService: MessageService, ngZone: NgZone, cdr: ChangeDetectorRef, session: VisualizerStore, samTool: SamToolService, cellSegmentTool: CellSegmentToolService, samPointTool: SamPointToolService, regionOps: RegionOpsService, vizConfig?: VizConfig | undefined);
|
|
250
|
+
constructor(state: ImageStatePort, plotService: IVisualizer, messageService: MessageService, ngZone: NgZone, cdr: ChangeDetectorRef, session: VisualizerStore, samTool: SamToolService, cellSegmentTool: CellSegmentToolService, yoloDetectTool: YoloDetectToolService, instanceSegmenter: IInstanceSegmenter, samPointTool: SamPointToolService, regionOps: RegionOpsService, vizConfig?: VizConfig | undefined);
|
|
237
251
|
/**
|
|
238
252
|
* Plot types offered in the selector for the current image:
|
|
239
253
|
* - Outside **test mode**, only the curated default set (descriptors with a
|
|
@@ -381,6 +395,17 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
|
|
|
381
395
|
* (jit-ui#90). Each box is cropped (browser slide-crop) then run through the
|
|
382
396
|
* cellpose-js model; the same sticky `sam` toast + progress bar is reused. */
|
|
383
397
|
segmentCellpose(): Promise<void>;
|
|
398
|
+
/** Per-model defaults from the registry — what the checkpoint was trained for. */
|
|
399
|
+
private defaultYoloParams;
|
|
400
|
+
/** Switching checkpoint re-seeds the parameters, since the defaults belong to
|
|
401
|
+
* the model rather than to the tool. */
|
|
402
|
+
onYoloModelChange(id: string): void;
|
|
403
|
+
openYoloParams(): void;
|
|
404
|
+
resetYoloParams(): void;
|
|
405
|
+
/** Detect objects across the current view. No prompt: a detector finds objects
|
|
406
|
+
* in a field rather than being pointed at one. Reuses the shared segmentation
|
|
407
|
+
* toast so progress and status read the same as the SAM/cellpose tools. */
|
|
408
|
+
detectYolo(): Promise<void>;
|
|
384
409
|
/** Shared driver for the box-prompt segment tools: wires the tool's status +
|
|
385
410
|
* download progress into the sticky `sam` toast, runs `op`, and reports the
|
|
386
411
|
* region count. Keeps the toast open until the run settles (bar hits 100%). */
|
|
@@ -424,6 +449,6 @@ export declare class VisualizerComponent implements OnInit, OnChanges, AfterView
|
|
|
424
449
|
onSelectPlotType(type: PlotType): void;
|
|
425
450
|
/** Deactivate whatever tool is armed and clear every tool mode. */
|
|
426
451
|
private deactivateActiveTool;
|
|
427
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<VisualizerComponent, [null, null, null, null, null, null, null, null, null, null, { optional: true; }]>;
|
|
452
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<VisualizerComponent, [null, null, null, null, null, null, null, null, null, null, null, null, { optional: true; }]>;
|
|
428
453
|
static ɵcmp: i0.ɵɵComponentDeclaration<VisualizerComponent, "visualizer", never, { "toolbarTools": { "alias": "toolbarTools"; "required": false; }; "testMode": { "alias": "testMode"; "required": false; }; }, { "isStackEvent": "isStackEvent"; "isGrayscaleEvent": "isGrayscaleEvent"; }, never, ["*"], false, never>;
|
|
429
454
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jax-data-science/sci-image-visualizer",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.13",
|
|
4
4
|
"description": "Browser-based scientific image visualization for Angular — gigapixel whole-slide (OpenSeadragon), 2D/3D (Plotly) and WebGPU (napari-js) rendering, with region/annotation editing and in-browser SAM segmentation.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|