Skip to content

Commit

Permalink
feat(dicom): run readOverlappingSegmentation for SEG
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulHax committed Oct 3, 2024
1 parent b5e53d9 commit e555bee
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 22 deletions.
17 changes: 14 additions & 3 deletions src/io/dicom.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -176,13 +180,20 @@ 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(),
mergeSegments: true,
});
console.log(result.metaInfo);
return result.segImage;
}
const result = await readImageDicomFileSeries({
webWorkerPool: getDicomSeriesWorkerPool(),
inputImages,
singleSortedSeries: false,
});

return result.outputImage;
}
10 changes: 7 additions & 3 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ import { createApp } from 'vue';
import VueToast from 'vue-toastification';
import { createPinia } from 'pinia';
import vtkMapper from '@kitware/vtk.js/Rendering/Core/Mapper';
import { setPipelinesBaseUrl, setPipelineWorkerUrl } from '@itk-wasm/image-io';

import { setPipelinesBaseUrl, setPipelineWorkerUrl } from 'itk-wasm';
import { setPipelinesBaseUrl as imageIoSetPipelinesBaseUrl } from '@itk-wasm/image-io';
import itkConfig from '@/src/io/itk/itkConfig';

import App from './components/App.vue';
import vuetify from './plugins/vuetify';
import { FILE_READERS } from './io';
Expand All @@ -36,9 +38,11 @@ vtkMapper.setResolveCoincidentTopologyLineOffsetParameters(-3, -3);

registerAllReaders(FILE_READERS);

// for @itk-wasm/image-io
// Must be set at runtime as new version of @itk-wasm/dicom and @itk-wasm/image-io
// do not pickup build time `../itkConfig` alias remap.
setPipelinesBaseUrl(itkConfig.pipelinesUrl);
setPipelineWorkerUrl(itkConfig.pipelineWorkerUrl);
setPipelinesBaseUrl(itkConfig.imageIOUrl);
imageIoSetPipelinesBaseUrl(itkConfig.imageIOUrl);

const pinia = createPinia();
pinia.use(CorePiniaProviderPlugin({}));
Expand Down
12 changes: 8 additions & 4 deletions src/store/datasets-dicom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down
12 changes: 0 additions & 12 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ function resolvePath(...args: string[]) {

const rootDir = resolvePath(__dirname);
const distDir = resolvePath(rootDir, 'dist');
const itkConfig = resolvePath(rootDir, 'src', 'io', 'itk', 'itkConfig.js');

const { ANALYZE_BUNDLE, SENTRY_AUTH_TOKEN, SENTRY_ORG, SENTRY_PROJECT } =
process.env;
Expand Down Expand Up @@ -113,17 +112,6 @@ export default defineConfig({
find: '@src',
replacement: resolvePath(rootDir, 'src'),
},
// Patch itk-wasm library code with image-io .wasm file paths
// itkConfig alias only applies to itk-wasm library code after "npm run build"
// During "npm run serve", itk-wasm fetches image-io .wasm files from CDN
{
find: '../itkConfig.js',
replacement: itkConfig,
},
{
find: '../../itkConfig.js',
replacement: itkConfig,
},
],
},
plugins: [
Expand Down

0 comments on commit e555bee

Please sign in to comment.