Skip to content

Commit

Permalink
fix(datasets-dicom): pick one component when overlapping SEG
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulHax committed Oct 3, 2024
1 parent 589306f commit 445fa47
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 12 deletions.
30 changes: 24 additions & 6 deletions src/store/datasets-dicom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import { defineStore } from 'pinia';
import { Image } from 'itk-wasm';
import { DataSourceWithFile } from '@/src/io/import/dataSource';
import * as DICOM from '@/src/io/dicom';
import { pullComponent0 } from '@/src/utils/images';
import { identity, pick, removeFromArray } from '../utils';
import { useImageStore } from './datasets-images';
import { useFileStore } from './datasets-files';
import { StateFile, DatasetType } from '../io/state-file/schema';
import { serializeData } from '../io/state-file/utils';
import { useMessageStore } from './messages';

export const ANONYMOUS_PATIENT = 'Anonymous';
export const ANONYMOUS_PATIENT_ID = 'ANONYMOUS';
Expand Down Expand Up @@ -50,19 +52,29 @@ export interface VolumeInfo {
}

const buildImage = async (seriesFiles: File[], modality: string) => {
const messages: string[] = [];
if (modality === 'SEG') {
const segFile = seriesFiles[0];
const results = await DICOM.buildLabelMap(segFile);
if (results.outputImage.imageType.components !== 1) {
messages.push(
`${segFile.name} SEG file has overlapping segments. Using first set.`
);
results.outputImage = pullComponent0(results.segImage);
}
if (seriesFiles.length > 1)
messages.push(
'SEG image has multiple components. Using only the first component.'
);
return {
modality: 'SEG',
builtImageResults: await DICOM.buildLabelMap(seriesFiles[0]),
messages:
seriesFiles.length > 1
? ['Multiple files in a SEG series. Using only the first file.']
: [],
builtImageResults: results,
messages,
};
}
return {
builtImageResults: await DICOM.buildImage(seriesFiles),
messages: [],
messages,
};
};

Expand Down Expand Up @@ -442,6 +454,12 @@ export const useDICOMStore = defineStore('dicom', {
imageStore.addVTKImageData(name, volumeBuildResults.image, volumeKey);
}

const messageStore = useMessageStore();
volumeBuildResults.messages.forEach((message) => {
console.warn(message);
messageStore.addWarning(message);
});

return volumeBuildResults;
},
},
Expand Down
12 changes: 6 additions & 6 deletions src/store/segmentGroups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,12 +277,12 @@ export const useSegmentGroupStore = defineStore('segmentGroup', () => {
imageStore.deleteData(imageID);
}

const resampled = await ensureSameSpace(parentImage, childImage, true);
const copyNeeded = resampled === childImage && !deleteImage;
const ownedMemoryImage = copyNeeded
? structuredClone(resampled)
: resampled;
const labelmapImage = toLabelMap(ownedMemoryImage);
const matchingParentSpace = await ensureSameSpace(
parentImage,
childImage,
true
);
const labelmapImage = toLabelMap(matchingParentSpace);

const segments = await decodeSegments(imageID, labelmapImage);
const { order, byKey } = normalizeForStore(segments, 'value');
Expand Down
21 changes: 21 additions & 0 deletions src/utils/images.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Image } from 'itk-wasm';

export const pullComponent0 = (image: Image) => {
const srcComponentCount = image.imageType.components;
const srcPixelArray = image.data!;
const oneComponentArrayLength = srcPixelArray.length / srcComponentCount;
const pixelArray = new (srcPixelArray.constructor as {
new (length: number): typeof srcPixelArray;
})(oneComponentArrayLength);
for (let pixel = 0; pixel < oneComponentArrayLength; pixel++) {
pixelArray[pixel] = srcPixelArray[pixel * srcComponentCount];
}
return {
...image,
data: pixelArray,
imageType: {
...image.imageType,
components: 1,
},
};
};

0 comments on commit 445fa47

Please sign in to comment.