From 34acfe9f9ea9fa6a9f5ecf5a8c81d902826b29ff Mon Sep 17 00:00:00 2001 From: Paul Elliott Date: Wed, 25 Sep 2024 15:46:09 -0400 Subject: [PATCH] wip feat(dicom): run readOverlappingSegmentation for SEG --- src/io/dicom.ts | 16 +++++++++++++--- src/store/datasets-dicom.ts | 12 ++++++++---- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/io/dicom.ts b/src/io/dicom.ts index fed1a7b5..125858a4 100644 --- a/src/io/dicom.ts +++ b/src/io/dicom.ts @@ -1,6 +1,10 @@ import { runPipeline, TextStream, InterfaceTypes, Image } from 'itk-wasm'; -import { readDicomTags, readImageDicomFileSeries } from '@itk-wasm/dicom'; +import { + readDicomTags, + readImageDicomFileSeries, + readOverlappingSegmentation, +} from '@itk-wasm/dicom'; import itkConfig from '@/src/io/itk/itkConfig'; import { getDicomSeriesWorkerPool, getWorker } from '@/src/io/itk/worker'; @@ -176,13 +180,19 @@ export async function readVolumeSlice( * @param {File[]} seriesFiles the set of files to build volume from * @returns ItkImage */ -export async function buildImage(seriesFiles: File[]) { +export async function buildImage(seriesFiles: File[], modality: string) { const inputImages = seriesFiles.map((file) => sanitizeFile(file)); + if (modality === 'SEG') { + const result = await readOverlappingSegmentation(inputImages[0], { + webWorker: getWorker(), + }); + console.log(result.metaInfo); + return result.segImage; + } const result = await readImageDicomFileSeries({ webWorkerPool: getDicomSeriesWorkerPool(), inputImages, singleSortedSeries: false, }); - return result.outputImage; } diff --git a/src/store/datasets-dicom.ts b/src/store/datasets-dicom.ts index 41da3478..341708d4 100644 --- a/src/store/datasets-dicom.ts +++ b/src/store/datasets-dicom.ts @@ -143,12 +143,12 @@ export const getWindowLevels = (info: VolumeInfo) => { return widths.map((width, i) => ({ width, level: levels[i] })); }; -const constructImage = async (volumeKey: string) => { +const constructImage = async (volumeKey: string, volumeInfo: VolumeInfo) => { const fileStore = useFileStore(); const files = fileStore.getFiles(volumeKey); if (!files) throw new Error('No files for volume key'); const image = vtkITKHelper.convertItkToVtkImage( - await DICOM.buildImage(files) + await DICOM.buildImage(files, volumeInfo.Modality) ); return image; }; @@ -196,7 +196,11 @@ export const useDICOMStore = defineStore('dicom', { Object.entries(volumeToFiles).map(async ([volumeKey, files]) => { // Read tags of first file if (!(volumeKey in this.volumeInfo)) { - const tags = await readDicomTags(files[0]); + const rawTags = await readDicomTags(files[0]); + // trim whitespace from all values + const tags = Object.fromEntries( + Object.entries(rawTags).map(([key, value]) => [key, value.trim()]) + ); // TODO parse the raw string values const patient = { PatientID: tags.PatientID || ANONYMOUS_PATIENT_ID, @@ -398,7 +402,7 @@ export const useDICOMStore = defineStore('dicom', { : []; // actually build volume or wait for existing build? const newImagePromise = buildNeeded - ? constructImage(volumeKey) + ? constructImage(volumeKey, this.volumeInfo[volumeKey]) : this.volumeImageData[volumeKey]; // let other calls to buildVolume reuse this constructImage work this.volumeImageData[volumeKey] = newImagePromise;