From 6817b1bbebd1bd4ca597b0482e73a2525e9507d1 Mon Sep 17 00:00:00 2001 From: Jules Bourdais Date: Thu, 5 Jan 2023 03:21:21 -0500 Subject: [PATCH 01/14] Stereo calibration configuration dialog --- client/dive-common/apispec.ts | 4 +- .../dive-common/components/ImportButton.vue | 16 ++++++- .../components/ImportMultiCamDialog.vue | 45 +++++++++++++++++-- .../components/RunPipelineMenu.vue | 2 + client/dive-common/constants.ts | 6 +++ .../desktop/backend/native/multiCamImport.ts | 12 ++++- .../platform/desktop/backend/native/viame.ts | 25 +++++++++++ client/platform/desktop/constants.ts | 3 ++ client/platform/desktop/frontend/api.ts | 9 +++- .../frontend/components/ImportDialog.vue | 18 ++++++++ .../desktop/frontend/components/Recent.vue | 8 +++- client/platform/web-girder/utils.ts | 2 +- 12 files changed, 140 insertions(+), 10 deletions(-) diff --git a/client/dive-common/apispec.ts b/client/dive-common/apispec.ts index f32f7180a..13a753466 100644 --- a/client/dive-common/apispec.ts +++ b/client/dive-common/apispec.ts @@ -82,6 +82,7 @@ export interface MultiCamImportFolderArgs { trackFile: string; }>; // path/track file per camera calibrationFile?: string; // NPZ calibation matrix file + stereoConfigurationFile?: string; // kwiver *.conf file type: 'image-sequence' | 'video'; } @@ -93,6 +94,7 @@ export interface MultiCamImportKeywordArgs { trackFile: string; }>; // glob pattern for base folder calibrationFile?: string; // NPZ calibation matrix file + stereoConfigurationFile?: string; // kwiver *.conf file type: 'image-sequence'; // Always image-sequence type for glob matching } @@ -161,7 +163,7 @@ interface Api { saveAttributeTrackFilters(datasetId: string, args: SaveAttributeTrackFilterArgs): Promise; // Non-Endpoint shared functions - openFromDisk(datasetType: DatasetType | 'calibration' | 'annotation' | 'text' | 'zip', directory?: boolean): + openFromDisk(datasetType: DatasetType | 'calibration' | 'annotation' | 'text' | 'zip' | 'stereoConfiguration', directory?: boolean): Promise<{canceled?: boolean; filePaths: string[]; fileList?: File[]; root?: string}>; getTiles?(itemId: string, projection?: string): Promise; // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/client/dive-common/components/ImportButton.vue b/client/dive-common/components/ImportButton.vue index 68befabe5..e1bac6e10 100644 --- a/client/dive-common/components/ImportButton.vue +++ b/client/dive-common/components/ImportButton.vue @@ -49,7 +49,7 @@ export default defineComponent({ offset-y offset-x nudge-left="180" - max-width="180" + max-width="250" > diff --git a/client/src/components/track_3d_viewer/misc.ts b/client/src/components/track_3d_viewer/misc.ts index d7dcb4ef8..339c416d6 100644 --- a/client/src/components/track_3d_viewer/misc.ts +++ b/client/src/components/track_3d_viewer/misc.ts @@ -1,2 +1,33 @@ -// eslint-disable-next-line import/prefer-default-export +import { Attribute } from 'vue-media-annotator/use/useAttributes'; + +const EXPECTED_ATTRIBUTE_NAMES = [ + 'stereo3d_x', + 'stereo3d_y', + 'stereo3d_z', +]; + export const noOp = () => undefined; + +export function isStereo3dReady(attrs: Attribute[]) { + const attributeNamesToFind = [...EXPECTED_ATTRIBUTE_NAMES]; + + // eslint-disable-next-line no-restricted-syntax + for (const attr of attrs) { + // eslint-disable-next-line no-plusplus + for (let i = 0; i < attributeNamesToFind.length; i++) { + if (attr.name === attributeNamesToFind[i]) { + if (attr.belongs === 'detection' && attr.datatype === 'number') { + attributeNamesToFind.splice(i, 1); + } else { + return false; + } + } + } + + if (attributeNamesToFind.length === 0) { + return true; + } + } + + return false; +} From 51a3b810e3fa81df15d0e87c70fff0b7fd914007 Mon Sep 17 00:00:00 2001 From: Jules BOURDAIS Date: Wed, 17 Apr 2024 18:15:41 +0200 Subject: [PATCH 11/14] fix: compatibility & syntax --- client/dive-common/store/context.ts | 1 + client/platform/desktop/frontend/components/ImportDialog.vue | 2 +- client/src/components/track_3d_viewer/misc.ts | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/client/dive-common/store/context.ts b/client/dive-common/store/context.ts index 241ba5b90..818e8e00a 100644 --- a/client/dive-common/store/context.ts +++ b/client/dive-common/store/context.ts @@ -52,6 +52,7 @@ const componentMap: Record = { [AttributeTrackFilters.name]: { description: 'Attribute Track Filters', component: AttributeTrackFilters, + }, [TrackViewerSettings.name]: { description: 'Track Viewer Settings', component: TrackViewerSettings, diff --git a/client/platform/desktop/frontend/components/ImportDialog.vue b/client/platform/desktop/frontend/components/ImportDialog.vue index bf09cdb27..1dd6d8231 100644 --- a/client/platform/desktop/frontend/components/ImportDialog.vue +++ b/client/platform/desktop/frontend/components/ImportDialog.vue @@ -11,7 +11,7 @@ import { locateDuplicates } from 'platform/desktop/frontend/store/dataset'; import { useApi } from 'dive-common/apispec'; import Vue from 'vue'; import { clientSettings } from 'dive-common/store/settings'; -import { Attribute } from 'vue-media-annotator/use/useAttributes'; +import { Attribute } from 'vue-media-annotator/use/AttributeTypes'; export default defineComponent({ diff --git a/client/src/components/track_3d_viewer/misc.ts b/client/src/components/track_3d_viewer/misc.ts index 339c416d6..262e75f20 100644 --- a/client/src/components/track_3d_viewer/misc.ts +++ b/client/src/components/track_3d_viewer/misc.ts @@ -1,4 +1,4 @@ -import { Attribute } from 'vue-media-annotator/use/useAttributes'; +import { Attribute } from 'vue-media-annotator/use/AttributeTypes'; const EXPECTED_ATTRIBUTE_NAMES = [ 'stereo3d_x', From 1ccecc884e7470416e0a1972f9f827647947eab1 Mon Sep 17 00:00:00 2001 From: Jules BOURDAIS Date: Tue, 23 Apr 2024 16:05:06 +0200 Subject: [PATCH 12/14] enh(stereo): get rid of stereoscopic calibration dialog keep one single import dialog for stereo --- client/dive-common/apispec.ts | 8 ++-- .../dive-common/components/ImportButton.vue | 12 ------ .../components/ImportMultiCamDialog.vue | 37 +------------------ client/dive-common/components/Viewer.vue | 4 +- .../desktop/backend/native/multiCamImport.ts | 9 +---- .../platform/desktop/backend/native/viame.ts | 4 +- client/platform/desktop/constants.ts | 4 +- .../frontend/components/ImportDialog.vue | 2 +- docs/UI-Attributes.md | 2 +- 9 files changed, 14 insertions(+), 68 deletions(-) diff --git a/client/dive-common/apispec.ts b/client/dive-common/apispec.ts index 3f0389fd7..51665996a 100644 --- a/client/dive-common/apispec.ts +++ b/client/dive-common/apispec.ts @@ -81,8 +81,7 @@ export interface MultiCamImportFolderArgs { sourcePath: string; trackFile: string; }>; // path/track file per camera - calibrationFile?: string; // NPZ calibation matrix file - stereoConfigurationFile?: string; // kwiver *.conf file + calibrationFile?: string; // NPZ calibation matrix file or kwivier *.conf file type: 'image-sequence' | 'video'; } @@ -93,8 +92,7 @@ export interface MultiCamImportKeywordArgs { glob: string; trackFile: string; }>; // glob pattern for base folder - calibrationFile?: string; // NPZ calibation matrix file - stereoConfigurationFile?: string; // kwiver *.conf file + calibrationFile?: string; // NPZ calibation matrix file or kwiver *.conf file type: 'image-sequence'; // Always image-sequence type for glob matching } @@ -139,7 +137,7 @@ interface DatasetMeta extends DatasetMetaMutable { originalFps?: Readonly; subType: Readonly; // In future this could have stuff like IR/EO multiCamMedia: Readonly; - stereoConfigurationFile?: Readonly; + calibrationFile?: Readonly; } interface Api { diff --git a/client/dive-common/components/ImportButton.vue b/client/dive-common/components/ImportButton.vue index e1bac6e10..7d9eb40b1 100644 --- a/client/dive-common/components/ImportButton.vue +++ b/client/dive-common/components/ImportButton.vue @@ -113,18 +113,6 @@ export default defineComponent({ - - - mdi-binoculars - - - Stereoscopic Calibration - - > = ref({}); const globList: Ref> = ref({}); const calibrationFile = ref(''); - const stereoConfigurationFile = ref(''); const defaultDisplay = ref('left'); const importAnnotationFilesCheck = ref(false); const { error: importError, request: importRequest } = useRequest(); @@ -199,8 +198,6 @@ export default defineComponent({ const path = ret.filePaths[0]; if (folder === 'calibration') { calibrationFile.value = path; - } else if (folder === 'stereoConfiguration') { - stereoConfigurationFile.value = path; } else if (importType.value === 'multi') { if (ret.root) { folderList.value[folder].sourcePath = ret.root; @@ -253,10 +250,6 @@ export default defineComponent({ calibrationFile: calibrationFile.value, type: props.dataType, }; - if (props.calibration) { - delete args.calibrationFile; - args.stereoConfigurationFile = stereoConfigurationFile.value; - } emit('begin-multicam-import', args); } else if (importType.value === 'keyword') { @@ -284,7 +277,7 @@ export default defineComponent({ defaultDisplay, displayKeys, importAnnotationFilesCheck, - stereoConfigurationFile, + // stereoConfigurationFile, //Methods open, prepForImport, @@ -479,32 +472,6 @@ export default defineComponent({ - - - - - Open Stereoscopic Configuration - - mdi-matrix - - - @@ -531,7 +498,7 @@ export default defineComponent({ Begin Import diff --git a/client/dive-common/components/Viewer.vue b/client/dive-common/components/Viewer.vue index 10631b783..a2c151919 100644 --- a/client/dive-common/components/Viewer.vue +++ b/client/dive-common/components/Viewer.vue @@ -571,7 +571,7 @@ export default defineComponent({ context.resetActive(); const meta = await loadMetadata(datasetId.value); - isStereoConfigMode.value = meta.stereoConfigurationFile != null; + isStereoConfigMode.value = meta.calibrationFile != null; const defaultCameraMeta = meta.multiCamMedia?.cameras[meta.multiCamMedia.defaultDisplay]; baseMulticamDatasetId.value = datasetId.value; @@ -741,7 +741,7 @@ export default defineComponent({ }); } - if (meta.stereoConfigurationFile) { + if (meta.calibrationFile) { context.register({ component: TrackViewerSettings, description: 'Track Viewer Settings', diff --git a/client/platform/desktop/backend/native/multiCamImport.ts b/client/platform/desktop/backend/native/multiCamImport.ts index 58698be7a..306206ef3 100644 --- a/client/platform/desktop/backend/native/multiCamImport.ts +++ b/client/platform/desktop/backend/native/multiCamImport.ts @@ -108,7 +108,6 @@ async function beginMultiCamImport(args: MultiCamImportArgs): Promise Date: Tue, 23 Apr 2024 16:05:43 +0200 Subject: [PATCH 13/14] enh(track3dviewer): reset camera when relevant --- client/src/components/track_3d_viewer/TrackViewer.vue | 6 ++++-- client/src/components/track_3d_viewer/trackUtils.ts | 2 +- client/src/components/track_3d_viewer/useTrackDrawer.ts | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/client/src/components/track_3d_viewer/TrackViewer.vue b/client/src/components/track_3d_viewer/TrackViewer.vue index 5131476a6..09bb85f07 100644 --- a/client/src/components/track_3d_viewer/TrackViewer.vue +++ b/client/src/components/track_3d_viewer/TrackViewer.vue @@ -174,7 +174,7 @@ export default defineComponent({ const cubeAxes = vtkCubeAxesActor.newInstance(); cubeAxes.setCamera(camera); - viewUtils.rerender = debounce(() => { + viewUtils.rerender = debounce((resetCamera = false) => { if (!renderWindow || renderWindow.isDeleted() || !renderer.value) { // pass } else { @@ -186,7 +186,9 @@ export default defineComponent({ renderer.value.addActor(cubeAxes); } drawCurrentFrameDetectionLabels(); - + if (resetCamera) { + renderer.value.resetCamera(); + } renderWindow.render(); } }, 10); diff --git a/client/src/components/track_3d_viewer/trackUtils.ts b/client/src/components/track_3d_viewer/trackUtils.ts index 98dc3403e..1de0542ce 100644 --- a/client/src/components/track_3d_viewer/trackUtils.ts +++ b/client/src/components/track_3d_viewer/trackUtils.ts @@ -3,7 +3,7 @@ import StyleManager from 'vue-media-annotator/StyleManager'; import * as vtkMath from '@kitware/vtk.js/Common/Core/Math'; export interface ViewUtils { - rerender: () => void; + rerender: (resetCamera?: boolean) => void; } export interface Feature { diff --git a/client/src/components/track_3d_viewer/useTrackDrawer.ts b/client/src/components/track_3d_viewer/useTrackDrawer.ts index 2d763745d..6f76908b5 100644 --- a/client/src/components/track_3d_viewer/useTrackDrawer.ts +++ b/client/src/components/track_3d_viewer/useTrackDrawer.ts @@ -391,7 +391,7 @@ export default function useTrackDrawer({ showAllTracks(); } - viewUtils.rerender(); + viewUtils.rerender(true); }; const onFilteredAnnotationsChange = function onFilteredAnnotationsChange( From 2174cf8de607eb21c2ee15f431bb7c9e9b7b85c3 Mon Sep 17 00:00:00 2001 From: Louis Pagnier Date: Thu, 14 Aug 2025 16:43:52 +0200 Subject: [PATCH 14/14] fix: calibrationFile property path changed --- client/dive-common/apispec.ts | 4 +++- client/dive-common/components/Viewer.vue | 4 ++-- client/platform/desktop/backend/native/viame.ts | 4 ++-- client/platform/web-girder/store/Dataset.ts | 1 + 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/client/dive-common/apispec.ts b/client/dive-common/apispec.ts index 335417dd5..7f2d896e1 100644 --- a/client/dive-common/apispec.ts +++ b/client/dive-common/apispec.ts @@ -7,6 +7,7 @@ import { TrackData } from 'vue-media-annotator/track'; import { Attribute } from 'vue-media-annotator/use/AttributeTypes'; import { CustomStyle } from 'vue-media-annotator/StyleManager'; import { AttributeTrackFilter } from 'vue-media-annotator/AttributeTrackFilterControls'; +import { MultiCamDesktop } from 'platform/desktop/constants'; type DatasetType = 'image-sequence' | 'video' | 'multi' | 'large-image'; type MultiTrackRecord = Record; @@ -140,7 +141,8 @@ interface DatasetMeta extends DatasetMetaMutable { originalFps?: Readonly; subType: Readonly; // In future this could have stuff like IR/EO multiCamMedia: Readonly; - calibrationFile?: Readonly; + multiCam: Readonly; + //calibrationFile?: Readonly; } interface Api { diff --git a/client/dive-common/components/Viewer.vue b/client/dive-common/components/Viewer.vue index 7dee87425..0472ec6d0 100644 --- a/client/dive-common/components/Viewer.vue +++ b/client/dive-common/components/Viewer.vue @@ -572,7 +572,7 @@ export default defineComponent({ context.resetActive(); const meta = await loadMetadata(datasetId.value); - isStereoConfigMode.value = meta.calibrationFile != null; + isStereoConfigMode.value = meta.multiCam?.calibration != null; const defaultCameraMeta = meta.multiCamMedia?.cameras[meta.multiCamMedia.defaultDisplay]; baseMulticamDatasetId.value = datasetId.value; @@ -744,7 +744,7 @@ export default defineComponent({ }); } - if (meta.calibrationFile) { + if (meta.multiCam?.calibration) { context.register({ component: TrackViewerSettings, description: 'Track Viewer Settings', diff --git a/client/platform/desktop/backend/native/viame.ts b/client/platform/desktop/backend/native/viame.ts index c8802486b..3c7741d2e 100644 --- a/client/platform/desktop/backend/native/viame.ts +++ b/client/platform/desktop/backend/native/viame.ts @@ -163,8 +163,8 @@ async function runPipeline( throw new Error('Attempting to run a multicam pipeline on non multicam data'); } - if (meta.calibrationFile) { - command.push(`-c "${meta.calibrationFile}"`); + if (meta.multiCam?.calibration) { + command.push(`-c "${meta.multiCam.calibration}"`); if (meta.multiCam) { // eslint-disable-next-line no-restricted-syntax diff --git a/client/platform/web-girder/store/Dataset.ts b/client/platform/web-girder/store/Dataset.ts index 21637d08e..6f028b3cd 100644 --- a/client/platform/web-girder/store/Dataset.ts +++ b/client/platform/web-girder/store/Dataset.ts @@ -24,6 +24,7 @@ const datasetModule: Module = { const dsMeta = { ...metaStatic.data, ...media.data, + multiCam: null, videoUrl: media.data.video?.url, }; // TODO remove when multi is supported in web