Skip to content

Commit

Permalink
fix(examples): stack and volume segmentation (#1684)
Browse files Browse the repository at this point in the history
* seg works import

* seg works import
  • Loading branch information
sedghi authored Dec 6, 2024
1 parent 17e09d5 commit 5149b31
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 53 deletions.
33 changes: 26 additions & 7 deletions packages/adapters/examples/segmentationStack/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ import { api } from "dicomweb-client";

import * as cornerstone from "@cornerstonejs/core";
import * as cornerstoneTools from "@cornerstonejs/tools";
import * as cornerstoneAdapters from "@cornerstonejs/adapters";

import { dicomMap } from "./demo";

import {
addButtonToToolbar,
addDropdownToToolbar,
addManipulationBindings,
addToggleButtonToToolbar,
addUploadToToolbar,
Expand All @@ -26,7 +24,7 @@ console.warn(
);

const { Enums: csEnums, RenderingEngine, utilities: csUtilities } = cornerstone;
const { ViewportType } = csEnums;
const { segmentation: csToolsSegmentation } = cornerstoneTools;
import {
readDicom,
loadDicom,
Expand All @@ -36,7 +34,8 @@ import {
restart,
getSegmentationIds,
handleFileSelect,
handleDragOver
handleDragOver,
createSegmentation
} from "../segmentationVolume/utils";

const referenceImageIds: string[] = [];
Expand Down Expand Up @@ -135,6 +134,13 @@ function loadDicom() {
renderingEngine.render();
}

function createSegmentationRepresentation() {
csToolsSegmentation.addLabelmapRepresentationToViewport(
state.viewportIds[0],
[{ segmentationId: state.segmentationId }]
);
}

// ============================= //
addButtonToToolbar({
id: "LOAD_DICOM",
Expand Down Expand Up @@ -169,16 +175,27 @@ addButtonToToolbar({
});

await loadSegmentation(arrayBuffer, state);
createSegmentationRepresentation();
},
container: group1
});

addUploadToToolbar({
id: "IMPORT_DICOM",
title: "Import DICOM",
onChange: (files: FileList) => {
readDicom(files, state);
loadDicom();
onChange: async (files: FileList) => {
await readDicom(files, state);
await loadDicom();
},
container: group2
});

addButtonToToolbar({
id: "CREATE_SEGMENTATION",
title: "Create Empty SEG",
onClick: async () => {
await createSegmentation(state);
createSegmentationRepresentation();
},
container: group2
});
Expand All @@ -190,6 +207,8 @@ addUploadToToolbar({
for (const file of files) {
await readSegmentation(file, state);
}

createSegmentationRepresentation();
},
container: group2
});
Expand Down
31 changes: 29 additions & 2 deletions packages/adapters/examples/segmentationVolume/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ console.warn(
);

const { utilities: csUtilities } = cornerstone;
const { segmentation: csToolsSegmentation } = cornerstoneTools;
import {
readDicom,
readSegmentation,
loadSegmentation,
exportSegmentation,
handleFileSelect,
handleDragOver,
restart
restart,
createSegmentation
} from "../segmentationVolume/utils";

setTitleAndDescription(
Expand Down Expand Up @@ -158,6 +160,15 @@ async function loadDicom() {
renderingEngine.render();
}

function createSegmentationRepresentation() {
const segMap = {
[state.viewportIds[0]]: [{ segmentationId: state.segmentationId }],
[state.viewportIds[1]]: [{ segmentationId: state.segmentationId }],
[state.viewportIds[2]]: [{ segmentationId: state.segmentationId }]
};

csToolsSegmentation.addLabelmapRepresentationToViewportMap(segMap);
}
// ============================= //
addButtonToToolbar({
id: "LOAD_DICOM",
Expand Down Expand Up @@ -191,14 +202,28 @@ addButtonToToolbar({
});

await loadSegmentation(arrayBuffer, state);
createSegmentationRepresentation();
},
container: group1
});

addUploadToToolbar({
id: "IMPORT_DICOM",
title: "Import DICOM",
onChange: (files: FileList) => readDicom(files, state),
onChange: async (files: FileList) => {
await readDicom(files, state);
await loadDicom();
},
container: group2
});

addButtonToToolbar({
id: "CREATE_SEGMENTATION",
title: "Create Empty SEG",
onClick: async () => {
await createSegmentation(state);
createSegmentationRepresentation();
},
container: group2
});

Expand All @@ -213,6 +238,8 @@ addUploadToToolbar({
for (const file of files) {
await readSegmentation(file, state);
}

createSegmentationRepresentation();
},
container: group2
});
Expand Down
78 changes: 35 additions & 43 deletions packages/adapters/examples/segmentationVolume/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,46 @@ import * as cornerstoneDicomImageLoader from "@cornerstonejs/dicom-image-loader"
import * as cornerstoneAdapters from "@cornerstonejs/adapters";
import dcmjs from "dcmjs";

const {
cache,
imageLoader,
metaData,
utilities: csUtilities,
volumeLoader
} = cornerstone;
const { cache, imageLoader, metaData } = cornerstone;
const { segmentation: csToolsSegmentation } = cornerstoneTools;
const { wadouri } = cornerstoneDicomImageLoader;
const { downloadDICOMData } = cornerstoneAdapters.helpers;
const { Cornerstone3D } = cornerstoneAdapters.adaptersSEG;

export async function readDicom(files: FileList, state) {
if (files.length <= 1) {
console.error(
"Viewport volume does not support just one image, it must be two or more images"
);
return;
}

for (const file of files) {
const imageId = wadouri.fileManager.add(file);
await imageLoader.loadAndCacheImage(imageId);
state.referenceImageIds.push(imageId);
}
}

export async function createSegmentation(state) {
const { referenceImageIds, segmentationId } = state;

const derivedSegmentationImages =
await imageLoader.createAndCacheDerivedLabelmapImages(
referenceImageIds
);

const derivedSegmentationImageIds = derivedSegmentationImages.map(
image => image.imageId
);

csToolsSegmentation.addSegmentations([
{
segmentationId,
representation: {
type: cornerstoneTools.Enums.SegmentationRepresentations
.Labelmap,
data: {
imageIds: derivedSegmentationImageIds
}
}
}
]);
}

export async function readSegmentation(file: File, state) {
const imageId = wadouri.fileManager.add(file);
const image = await imageLoader.loadAndCacheImage(imageId);
Expand All @@ -52,8 +65,7 @@ export async function readSegmentation(file: File, state) {
}

export async function loadSegmentation(arrayBuffer: ArrayBuffer, state) {
const { referenceImageIds, skipOverlapping, viewportIds, segmentationId } =
state;
const { referenceImageIds, skipOverlapping, segmentationId } = state;

const generateToolState =
await Cornerstone3D.Segmentation.generateToolState(
Expand All @@ -72,35 +84,15 @@ export async function loadSegmentation(arrayBuffer: ArrayBuffer, state) {
return;
}

const derivedSegmentationImages =
await imageLoader.createAndCacheDerivedLabelmapImages(
referenceImageIds
);

const derivedSegmentationImageIds = derivedSegmentationImages.map(
image => image.imageId
);
await createSegmentation(state);

csToolsSegmentation.addSegmentations([
{
segmentationId,
representation: {
type: cornerstoneTools.Enums.SegmentationRepresentations
.Labelmap,
data: {
imageIds: derivedSegmentationImageIds
}
}
}
]);

const segMap = {
[viewportIds[0]]: [{ segmentationId }],
[viewportIds[1]]: [{ segmentationId }],
[viewportIds[2]]: [{ segmentationId }]
};
const segmentation =
csToolsSegmentation.state.getSegmentation(segmentationId);

await csToolsSegmentation.addLabelmapRepresentationToViewportMap(segMap);
const { imageIds } = segmentation.representationData.Labelmap;
const derivedSegmentationImages = imageIds.map(imageId =>
cache.getImage(imageId)
);

const volumeScalarData = new Uint8Array(
generateToolState.labelmapBufferArray[0]
Expand Down
2 changes: 1 addition & 1 deletion utils/ExampleRunner/template-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const rspack = require('@rspack/core');
module.exports = {
mode: 'development',
devtool: 'source-map',
devtool: 'eval-source-map',
plugins: [
new rspack.HtmlRspackPlugin({
template: '${root.replace(/\\/g, '/')}/utils/ExampleRunner/template.html',
Expand Down

0 comments on commit 5149b31

Please sign in to comment.